/// <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();
        }
Example #2
0
        /// <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());
        }
Example #3
0
        /// <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("'", "\\'"));
            }
        }
Example #5
0
        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;
        }
Example #7
0
        /// <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);
Example #9
0
 /// <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);
        }
Example #11
0
 /// <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);
 }
Example #12
0
 /// <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;
 }
Example #15
0
        /// <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));
        }
Example #17
0
        /// <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);
        }
Example #18
0
 /// <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);
Example #19
0
        /// <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);
        }
Example #20
0
        /// <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;
 }