/// <summary> /// Serializes an object to a string. /// </summary> /// <param name="value">The object to serialize.</param> /// <param name="context">The context of the serialization.</param> /// <returns>The serialized representation of the object.</returns> public override string SerializeObject(object value, TraceSerializationContext context) { if (value == null) return null; return value.ToString(); }
/// <summary> /// Serializes an object to a string. /// </summary> /// <param name="value">The object to serialize.</param> /// <param name="context">The context of the serialization.</param> /// <returns>The serialized representation of the object.</returns> public override string SerializeObject(object value, TraceSerializationContext context) { if (value == null) { return(null); } return(value.ToString()); }
/// <summary> /// Called by EventSourceProxy to serialize an object. This method should call ShouldSerialize /// then SerializeObject if serialization is enabled. /// </summary> /// <param name="value">The value to serialize.</param> /// <param name="context">The serialization context.</param> /// <returns>The serialized value.</returns> public virtual string ProvideSerialization(object value, TraceSerializationContext context) { if (!ShouldSerialize(context)) { return(null); } return(SerializeObject(value, context)); }
public override string SerializeObject(object value, TraceSerializationContext context) { try { // if we have a task, don't attempt to serialize the task if it's not completed Task t = value as Task; if (t != null && !t.IsCompleted) { return JsonConvert.SerializeObject(new { TaskId = t.Id }); } return JsonConvert.SerializeObject(value); } catch (Exception e) { // don't let serialization exceptions blow up processing return String.Format(CultureInfo.InvariantCulture, "{{ Exception: '{0}' }}", e.Message.Replace("'", "\\'")); } }
public override string SerializeObject(object value, TraceSerializationContext context) { try { // if we have a task, don't attempt to serialize the task if it's not completed Task t = value as Task; if (t != null && !t.IsCompleted) { return(JsonConvert.SerializeObject(new { TaskId = t.Id })); } return(JsonConvert.SerializeObject(value)); } catch (Exception e) { // don't let serialization exceptions blow up processing return(String.Format(CultureInfo.InvariantCulture, "{{ Exception: '{0}' }}", e.Message.Replace("'", "\\'"))); } }
/// <summary> /// Returns the EventLevel at which to enable serialization for the given context. /// This method looks at the TraceSerializationAttributes on the parameter, method, or class. /// </summary> /// <param name="context">The serialization context to evaluate.</param> /// <returns>The EventLevel at which to enable serialization for the given context.</returns> public virtual EventLevel? GetEventLevelForContext(TraceSerializationContext context) { if (context == null) throw new ArgumentNullException("context"); TraceSerializationAttribute attribute = null; // look on the parameter first ParameterInfo parameterInfo = null; switch (context.ContextType) { case InvocationContextTypes.MethodCall: parameterInfo = context.MethodInfo.GetParameters()[context.ParameterIndex]; break; case InvocationContextTypes.MethodCompletion: parameterInfo = context.MethodInfo.ReturnParameter; break; } if (parameterInfo != null) { // look at the attribute on the parameter attribute = parameterInfo.GetCustomAttribute<TraceSerializationAttribute>(); if (attribute != null) return attribute.Level; // look at the attribute on the parameter's type attribute = parameterInfo.ParameterType.GetCustomAttribute<TraceSerializationAttribute>(); if (attribute != null) return attribute.Level; } // now look on the method attribute = context.MethodInfo.GetCustomAttribute<TraceSerializationAttribute>(); if (attribute != null) return attribute.Level; // now look at the type attribute = context.MethodInfo.DeclaringType.GetCustomAttribute<TraceSerializationAttribute>(); if (attribute != null) return attribute.Level; return _defaultEventLevel; }
/// <summary> /// Returns if the should the given parameter be serialized. /// </summary> /// <param name="context">The context of the serialization.</param> /// <returns>True if the value should be serialized, false otherwise.</returns> public virtual bool ShouldSerialize(TraceSerializationContext context) { if (context == null) { throw new ArgumentNullException("context"); } if (context.EventLevel == null) { return(false); } var eventLevel = context.EventLevel.Value; if (eventLevel == EventLevel.LogAlways) { return(true); } return(context.EventSource.IsEnabled(eventLevel, (EventKeywords)(-1))); }
/// <summary> /// Serializes an object to a string. /// </summary> /// <param name="value">The object to serialize.</param> /// <param name="context">The context of the serialization.</param> /// <returns>The serialized representation of the object.</returns> public abstract string SerializeObject(object value, TraceSerializationContext context);
/// <summary> /// Returns if the should the given parameter be serialized. /// </summary> /// <param name="context">The context of the serialization.</param> /// <returns>True if the value should be serialized, false otherwise.</returns> public override bool ShouldSerialize(TraceSerializationContext context) { return(false); }
/// <summary> /// Called by EventSourceProxy to serialize an object. This method should call ShouldSerialize /// then SerializeObject if serialization is enabled. /// </summary> /// <param name="value">The value to serialize.</param> /// <param name="context">The serialization context.</param> /// <returns>The serialized value.</returns> public virtual string ProvideSerialization(object value, TraceSerializationContext context) { if (!ShouldSerialize(context)) return null; return SerializeObject(value, context); }
/// <summary> /// Returns the EventLevel at which to enable serialization for the given context. /// This method looks at the TraceSerializationAttributes on the parameter, method, or class. /// </summary> /// <param name="context">The serialization context to evaluate.</param> /// <returns>The EventLevel at which to enable serialization for the given context.</returns> public override EventLevel?GetEventLevelForContext(TraceSerializationContext context) { return(null); }
/// <summary> /// Serializes an object to a string. /// </summary> /// <param name="value">The object to serialize.</param> /// <param name="context">The context of the serialization.</param> /// <returns>The serialized representation of the object.</returns> public override string SerializeObject(object value, TraceSerializationContext context) { return(null); }
/// <summary> /// Returns if the should the given parameter be serialized. /// </summary> /// <param name="context">The context of the serialization.</param> /// <returns>True if the value should be serialized, false otherwise.</returns> public override bool ShouldSerialize(TraceSerializationContext context) { return false; }
/// <summary> /// Serializes an object to a string. /// </summary> /// <param name="value">The object to serialize.</param> /// <param name="context">The context of the serialization.</param> /// <returns>The serialized representation of the object.</returns> public override string SerializeObject(object value, TraceSerializationContext context) { return null; }
/// <summary> /// Emits the code needed to properly push an object on the stack, /// serializing the value if necessary. /// </summary> /// <param name="typeBuilder">The TypeBuilder for the method being built.</param> /// <param name="methodBuilder">The method currently being built.</param> /// <param name="invocationContext">The invocation context for this call.</param> /// <param name="invocationContexts">A list of invocation contexts that will be appended to.</param> /// <param name="invocationContextsField">The static field containing the array of invocation contexts at runtime.</param> /// <param name="parameterMapping">The mapping of source parameters to destination parameters.</param> /// <param name="serializationProvider">The serialization provider for the current interface.</param> /// <param name="serializationProviderField"> /// The field on the current object that contains the serialization provider at runtime. /// This method assume the current object is stored in arg.0. /// </param> internal static void EmitSerializeValue( TypeBuilder typeBuilder, MethodBuilder methodBuilder, InvocationContext invocationContext, List<InvocationContext> invocationContexts, FieldBuilder invocationContextsField, ParameterMapping parameterMapping, TraceSerializationProvider serializationProvider, FieldBuilder serializationProviderField) { var sourceCount = parameterMapping.Sources.Count(); if (sourceCount == 0) return; if (sourceCount == 1) { var parameter = parameterMapping.Sources.First(); EmitSerializeValue( typeBuilder, methodBuilder, invocationContext, invocationContexts, invocationContextsField, parameter.Position, parameter.SourceType, parameterMapping.CleanTargetType, parameter.Converter, serializationProvider, serializationProviderField); return; } var il = methodBuilder.GetILGenerator(); // use the serializer to serialize the objects var context = new TraceSerializationContext(invocationContext.SpecifyType(InvocationContextTypes.BundleParameters), -1); context.EventLevel = serializationProvider.GetEventLevelForContext(context); if (context.EventLevel != null) { // get the object serializer from the this pointer il.Emit(OpCodes.Ldsfld, serializationProviderField); // create a new dictionary strings and values il.Emit(OpCodes.Newobj, typeof(Dictionary<string, string>).GetConstructor(Type.EmptyTypes)); foreach (var parameter in parameterMapping.Sources) { il.Emit(OpCodes.Dup); il.Emit(OpCodes.Ldstr, parameter.Alias); EmitSerializeValue( typeBuilder, methodBuilder, invocationContext, invocationContexts, invocationContextsField, parameter.Position, parameter.SourceType, parameterMapping.CleanTargetType, parameter.Converter, serializationProvider, serializationProviderField); var method = typeof(Dictionary<string, string>).GetMethod("Add"); il.Emit(OpCodes.Call, method); } // get the invocation context from the array on the provider il.Emit(OpCodes.Ldsfld, invocationContextsField); il.Emit(OpCodes.Ldc_I4, invocationContexts.Count); il.Emit(OpCodes.Ldelem, typeof(TraceSerializationContext)); invocationContexts.Add(context); il.Emit(OpCodes.Callvirt, typeof(TraceSerializationProvider).GetMethod("ProvideSerialization", BindingFlags.Instance | BindingFlags.Public)); } else il.Emit(OpCodes.Ldnull); }
/// <summary> /// Returns if the should the given parameter be serialized. /// </summary> /// <param name="context">The context of the serialization.</param> /// <returns>True if the value should be serialized, false otherwise.</returns> public virtual bool ShouldSerialize(TraceSerializationContext context) { if (context == null) throw new ArgumentNullException("context"); if (context.EventLevel == null) return false; var eventLevel = context.EventLevel.Value; if (eventLevel == EventLevel.LogAlways) return true; return context.EventSource.IsEnabled(eventLevel, (EventKeywords)(-1)); }
/// <summary> /// Emits the code needed to properly push an object on the stack, /// serializing the value if necessary. /// </summary> /// <param name="methodBuilder">The method currently being built.</param> /// <param name="invocationContext">The invocation context for this call.</param> /// <param name="invocationContexts">A list of invocation contexts that will be appended to.</param> /// <param name="invocationContextsField">The static field containing the array of invocation contexts at runtime.</param> /// <param name="i">The index of the current parameter being pushed.</param> /// <param name="sourceType">The type that the parameter is being converted from.</param> /// <param name="targetType">The type that the parameter is being converted to.</param> /// <param name="serializationProvider">The serialization provider for the current interface.</param> /// <param name="serializationProviderField"> /// The field on the current object that contains the serialization provider at runtime. /// This method assume the current object is stored in arg.0. /// </param> internal static void EmitSerializeValue( MethodBuilder methodBuilder, InvocationContext invocationContext, List<InvocationContext> invocationContexts, FieldBuilder invocationContextsField, int i, Type sourceType, Type targetType, TraceSerializationProvider serializationProvider, FieldBuilder serializationProviderField) { ILGenerator mIL = methodBuilder.GetILGenerator(); // if the source type is a reference to the target type, we have to dereference it if (sourceType.IsByRef && sourceType.GetElementType() == targetType) { mIL.Emit(OpCodes.Ldarg, (int)i + 1); sourceType = sourceType.GetElementType(); mIL.Emit(OpCodes.Ldobj, sourceType); return; } // if the types match, just put the argument on the stack if (sourceType == targetType) { mIL.Emit(OpCodes.Ldarg, (int)i + 1); return; } // this is not a match, so convert using the serializer. // verify that the target type is a string if (targetType != typeof(string)) throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Cannot convert type {0} to a type compatible with EventSource", targetType.FullName)); // for fundamental types, just convert them with ToString and be done with it var underlyingType = Nullable.GetUnderlyingType(sourceType) ?? sourceType; if (!sourceType.IsGenericParameter && (underlyingType.IsEnum || (underlyingType.IsValueType && underlyingType.Assembly == typeof(string).Assembly))) { // convert the argument to a string with ToString mIL.Emit(OpCodes.Ldarga_S, i + 1); mIL.Emit(OpCodes.Call, sourceType.GetMethod("ToString", Type.EmptyTypes)); return; } // non-fundamental types use the object serializer var context = new TraceSerializationContext(invocationContext, i); context.EventLevel = serializationProvider.GetEventLevelForContext(context); if (context.EventLevel != null) { // get the object serializer from the this pointer mIL.Emit(OpCodes.Ldsfld, serializationProviderField); // load the value mIL.Emit(OpCodes.Ldarg, (int)i + 1); // if the source type is a reference to the target type, we have to dereference it if (sourceType.IsByRef) { sourceType = sourceType.GetElementType(); mIL.Emit(OpCodes.Ldobj, sourceType); } // if it's a value type, we have to box it to log it if (sourceType.IsGenericParameter || sourceType.IsValueType) mIL.Emit(OpCodes.Box, sourceType); // get the invocation context from the array on the provider mIL.Emit(OpCodes.Ldsfld, invocationContextsField); mIL.Emit(OpCodes.Ldc_I4, invocationContexts.Count); mIL.Emit(OpCodes.Ldelem, typeof(TraceSerializationContext)); invocationContexts.Add(context); mIL.Emit(OpCodes.Callvirt, typeof(TraceSerializationProvider).GetMethod("ProvideSerialization", BindingFlags.Instance | BindingFlags.Public)); } else mIL.Emit(OpCodes.Ldnull); }
/// <summary> /// Returns the EventLevel at which to enable serialization for the given context. /// This method looks at the TraceSerializationAttributes on the parameter, method, or class. /// </summary> /// <param name="context">The serialization context to evaluate.</param> /// <returns>The EventLevel at which to enable serialization for the given context.</returns> public virtual EventLevel?GetEventLevelForContext(TraceSerializationContext context) { if (context == null) { throw new ArgumentNullException("context"); } TraceSerializationAttribute attribute = null; // look on the parameter first ParameterInfo parameterInfo = null; switch (context.ContextType) { case InvocationContextTypes.MethodCall: // added context data is added by default if (context.ParameterIndex < 0) { return(_defaultEventLevel); } parameterInfo = context.MethodInfo.GetParameters()[context.ParameterIndex]; break; case InvocationContextTypes.MethodCompletion: parameterInfo = context.MethodInfo.ReturnParameter; break; } if (parameterInfo != null) { // look at the attribute on the parameter attribute = parameterInfo.GetCustomAttribute <TraceSerializationAttribute>(); if (attribute != null) { return(attribute.Level); } // look at the attribute on the parameter's type attribute = parameterInfo.ParameterType.GetCustomAttribute <TraceSerializationAttribute>(); if (attribute != null) { return(attribute.Level); } } // now look on the method attribute = context.MethodInfo.GetCustomAttribute <TraceSerializationAttribute>(); if (attribute != null) { return(attribute.Level); } // now look at the type attribute = context.MethodInfo.DeclaringType.GetCustomAttribute <TraceSerializationAttribute>(); if (attribute != null) { return(attribute.Level); } return(_defaultEventLevel); }
/// <summary> /// Emits the code needed to properly push an object on the stack, /// serializing the value if necessary. /// </summary> /// <param name="typeBuilder">The TypeBuilder for the method being built.</param> /// <param name="methodBuilder">The method currently being built.</param> /// <param name="invocationContext">The invocation context for this call.</param> /// <param name="invocationContexts">A list of invocation contexts that will be appended to.</param> /// <param name="invocationContextsField">The static field containing the array of invocation contexts at runtime.</param> /// <param name="i">The index of the current parameter being pushed.</param> /// <param name="sourceType">The type that the parameter is being converted from.</param> /// <param name="targetType">The type that the parameter is being converted to.</param> /// <param name="converter">An optional converter to apply to the source type.</param> /// <param name="serializationProvider">The serialization provider for the current interface.</param> /// <param name="serializationProviderField"> /// The field on the current object that contains the serialization provider at runtime. /// This method assume the current object is stored in arg.0. /// </param> internal static void EmitSerializeValue( TypeBuilder typeBuilder, MethodBuilder methodBuilder, InvocationContext invocationContext, List<InvocationContext> invocationContexts, FieldBuilder invocationContextsField, int i, Type sourceType, Type targetType, LambdaExpression converter, TraceSerializationProvider serializationProvider, FieldBuilder serializationProviderField) { ILGenerator mIL = methodBuilder.GetILGenerator(); // if the source is a parameter, then load the parameter onto the stack if (i >= 0) mIL.Emit(OpCodes.Ldarg, i + 1); // if a converter is passed in, then define a static method and use it to convert if (converter != null) { MethodBuilder mb = typeBuilder.DefineMethod(Guid.NewGuid().ToString(), MethodAttributes.Static | MethodAttributes.Public, converter.ReturnType, converter.Parameters.Select(p => p.Type).ToArray()); converter.CompileToMethod(mb); mIL.Emit(OpCodes.Call, mb); // the object on the stack is now the return type. we may need to convert it further sourceType = converter.ReturnType; } // if the source type is a reference to the target type, we have to dereference it if (sourceType.IsByRef && sourceType.GetElementType() == targetType) { sourceType = sourceType.GetElementType(); mIL.Emit(OpCodes.Ldobj, sourceType); return; } // if the types match, just put the argument on the stack if (sourceType == targetType) return; // this is not a match, so convert using the serializer. // verify that the target type is a string if (targetType != typeof(string)) throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Cannot convert type {0} to a type compatible with EventSource", targetType.FullName)); // for fundamental types, just convert them with ToString and be done with it var underlyingType = Nullable.GetUnderlyingType(sourceType) ?? sourceType; if (!sourceType.IsGenericParameter && (underlyingType.IsEnum || (underlyingType.IsValueType && underlyingType.Assembly == typeof(string).Assembly))) { // convert the argument to a string with ToString LocalBuilder lb = mIL.DeclareLocal(sourceType); mIL.Emit(OpCodes.Stloc, lb.LocalIndex); mIL.Emit(OpCodes.Ldloca, lb.LocalIndex); mIL.Emit(OpCodes.Call, sourceType.GetMethod("ToString", Type.EmptyTypes)); return; } // non-fundamental types use the object serializer var context = new TraceSerializationContext(invocationContext, i); context.EventLevel = serializationProvider.GetEventLevelForContext(context); if (context.EventLevel != null) { LocalBuilder lb = mIL.DeclareLocal(sourceType); mIL.Emit(OpCodes.Stloc, lb.LocalIndex); // get the object serializer from the this pointer mIL.Emit(OpCodes.Ldsfld, serializationProviderField); mIL.Emit(OpCodes.Ldloc, lb.LocalIndex); // if the source type is a reference to the target type, we have to dereference it if (sourceType.IsByRef) { sourceType = sourceType.GetElementType(); mIL.Emit(OpCodes.Ldobj, sourceType); } // if it's a value type, we have to box it to log it if (sourceType.IsGenericParameter || sourceType.IsValueType) mIL.Emit(OpCodes.Box, sourceType); // get the invocation context from the array on the provider mIL.Emit(OpCodes.Ldsfld, invocationContextsField); mIL.Emit(OpCodes.Ldc_I4, invocationContexts.Count); mIL.Emit(OpCodes.Ldelem, typeof(TraceSerializationContext)); invocationContexts.Add(context); mIL.Emit(OpCodes.Callvirt, typeof(TraceSerializationProvider).GetMethod("ProvideSerialization", BindingFlags.Instance | BindingFlags.Public)); } else { mIL.Emit(OpCodes.Pop); mIL.Emit(OpCodes.Ldnull); } }
/// <summary> /// Returns the EventLevel at which to enable serialization for the given context. /// This method looks at the TraceSerializationAttributes on the parameter, method, or class. /// </summary> /// <param name="context">The serialization context to evaluate.</param> /// <returns>The EventLevel at which to enable serialization for the given context.</returns> public override EventLevel? GetEventLevelForContext(TraceSerializationContext context) { return null; }