Ejemplo n.º 1
0
        private static Match GetMatchFromType(ITypeDetails t)
        {
            var assy      = t.Assembly.Name;
            var className = t.FullName;

            return(new Match(assy, className));
        }
Ejemplo n.º 2
0
        private static string GetFriendlyTypeName(ITypeDetails t)
        {
            if (!t.IsGenericType)
            {
                return(t.FullName);
            }
            else
            {
                // Generics when asked for their full-name do crazy things like:
                // System.Nullable`1[[System.Decimal, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
                // Which isn't much use to us as NewRelic uses a combination of backtick notation and angle brackets.
                // However, we can fiddle this...
                const string FORMAT     = "{0}.{1}<{2}>";
                string[]     innerTypes = t.GenericArguments.Select(x => string.Format("{0}", GetFriendlyTypeName(x))).ToArray();

                return(string.Format(FORMAT, t.Namespace, t.Name, string.Join(",", innerTypes)));
            }
        }
Ejemplo n.º 3
0
        private static string GetGenericParameterTypeName(ITypeDetails parameterType, IEnumerable <ITypeDetails> orderedTypeContext)
        {
            if (parameterType.IsGenericType)
            {
                return(parameterType.FullName + "<" + string.Join(",", parameterType.GenericArguments.Select(x => GetGenericParameterTypeName(x, orderedTypeContext))) + ">");
            }
            else
            {
                // Is this something that's in our context?
                int idx = 0;
                foreach (var genericArgument in orderedTypeContext)
                {
                    if (genericArgument.Equals(parameterType))
                    {
                        return(string.Format("MVAR {0}", idx));
                    }

                    idx++;
                }
            }

            // Fall back to standard process
            return(GetFriendlyTypeName(parameterType));
        }
        protected virtual IEnumerable<InstrumentationTarget> GetInstrumentationSet(ITypeDetails t, InstrumentAttribute context)
        {
            var toReturn = new List<InstrumentationTarget>();

            if (!t.IsGenericTypeDefinition)
            {
                // Does the type have an Instrument attribute?
                var typeLevelAttribute = t.InstrumentationContext;
                typeLevelAttribute = InstrumentAttribute.GetEffectiveInstrumentationContext(typeLevelAttribute, context);

                if (t.IsCompilerGenerated && (typeLevelAttribute == null || !typeLevelAttribute.IncludeCompilerGeneratedCode))
                {
                    // Bail out early - we've found a compiler-generated method and haven't been told to include 'em
                    _logger.DebugFormat("Skipping type {0} - compiler-generated and configuration set to skip", t.FullName);

                    return toReturn;
                }

                _logger.DebugFormat("Processing type {0}", t.FullName);

                var baseBindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly;
                var propBindingFlags = baseBindingFlags;
                var methodBindingFlags = baseBindingFlags;
                var ctorBindingFlags = baseBindingFlags;

                if (typeLevelAttribute == null)
                {
                    propBindingFlags |= BindingFlags.NonPublic | BindingFlags.Public;
                    methodBindingFlags |= BindingFlags.NonPublic | BindingFlags.Public;
                    ctorBindingFlags |= BindingFlags.NonPublic | BindingFlags.Public;
                }
                else
                {
                    if ((typeLevelAttribute.Scopes & InstrumentationScopes.PublicProperties) == InstrumentationScopes.PublicProperties)
                    {
                        propBindingFlags |= BindingFlags.Public;
                    }
                    if ((typeLevelAttribute.Scopes & InstrumentationScopes.NonPublicProperties) == InstrumentationScopes.NonPublicProperties)
                    {
                        propBindingFlags |= BindingFlags.NonPublic;
                    }

                    if ((typeLevelAttribute.Scopes & InstrumentationScopes.PublicMethods) == InstrumentationScopes.PublicMethods)
                    {
                        methodBindingFlags |= BindingFlags.Public;
                    }
                    if ((typeLevelAttribute.Scopes & InstrumentationScopes.NonPublicMethods) == InstrumentationScopes.NonPublicMethods)
                    {
                        methodBindingFlags |= BindingFlags.NonPublic;
                    }

                    if ((typeLevelAttribute.Scopes & InstrumentationScopes.PublicConstructors) == InstrumentationScopes.PublicConstructors)
                    {
                        ctorBindingFlags |= BindingFlags.Public;
                    }
                    if ((typeLevelAttribute.Scopes & InstrumentationScopes.NonPublicConstructors) == InstrumentationScopes.NonPublicConstructors)
                    {
                        ctorBindingFlags |= BindingFlags.NonPublic;
                    }
                }

                _logger.DebugFormat("Prop flags {0}, Ctor flags {1}, Method flags {2}", propBindingFlags, ctorBindingFlags, methodBindingFlags);

                // Instrument everything in this type, irrespective of its member-level
                // details
                foreach (var methodDetails in t.GetMethods(methodBindingFlags))
                {
                    _logger.DebugFormat("Examining method {0}", methodDetails.ToString());

                    var attr = InstrumentAttribute.GetEffectiveInstrumentationContext(methodDetails.InstrumentationContext, typeLevelAttribute);
                    if (attr != null && (!methodDetails.IsCompilerGenerated || attr.IncludeCompilerGeneratedCode))
                    {
                        toReturn.Add(GetInstrumentationTarget(methodDetails, attr));
                    }
                }

                foreach (var propertyDetails in t.GetProperties(propBindingFlags))
                {
                    _logger.DebugFormat("Examining property {0}.{1}", t.FullName, propertyDetails.Name);

                    var getMethod = propertyDetails.GetMethod;
                    var setMethod = propertyDetails.SetMethod;

                    if (getMethod != null && getMethod.ContainsGenericParameters)
                    {
                        getMethod = null;
                    }

                    if (setMethod != null && setMethod.ContainsGenericParameters)
                    {
                        setMethod = null;
                    }

                    if (getMethod != null)
                    {
                        var getMethodAttr = InstrumentAttribute.GetEffectiveInstrumentationContext(propertyDetails.InstrumentationContext, getMethod.InstrumentationContext, typeLevelAttribute);
                        if (getMethodAttr != null)
                        {
                            toReturn.Add(GetInstrumentationTarget(getMethod, getMethodAttr));
                        }
                    }

                    if (setMethod != null)
                    {
                        var setMethodAttr = InstrumentAttribute.GetEffectiveInstrumentationContext(propertyDetails.InstrumentationContext, setMethod.InstrumentationContext, typeLevelAttribute);
                        if (setMethodAttr != null)
                        {
                            toReturn.Add(GetInstrumentationTarget(setMethod, setMethodAttr));
                        }
                    }
                }

                foreach (var constructorDetails in t.GetConstructors(ctorBindingFlags).Where(x => !x.ContainsGenericParameters))
                {
                    _logger.DebugFormat("Examining method {0}", constructorDetails.ToString());

                    var attr = InstrumentAttribute.GetEffectiveInstrumentationContext(constructorDetails.InstrumentationContext, typeLevelAttribute);
                    if (attr != null)
                    {
                        toReturn.Add(GetInstrumentationTarget(constructorDetails, attr));
                    }
                }

                // Process nested types recursively, rather than enumerating them from the get-go so that we can apply
                // instrumentation scoping recursively too - the nested class will take on the instrumentation configuration
                // of the containing type, if any, or whatever's been passed down by initial settings
                foreach (var nested in t.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static))
                {
                    toReturn.AddRange(GetInstrumentationSet(nested, typeLevelAttribute));
                }
            }
            else
            {
                _logger.DebugFormat("Skipping type {0} - generic types not supported", t.FullName);
            }

            return toReturn;
        }
Ejemplo n.º 5
0
 public DummyMethodDetails(ITypeDetails declaringType, string name)
 {
     this.DeclaringType = declaringType;
     this.Name = name;
 }
Ejemplo n.º 6
0
        private static string GetGenericParameterTypeName(ITypeDetails parameterType, IEnumerable<ITypeDetails> orderedTypeContext)
        {
            if (parameterType.IsGenericType)
            {
                return parameterType.FullName + "<" + string.Join(",", parameterType.GenericArguments.Select(x => GetGenericParameterTypeName(x, orderedTypeContext))) + ">";
            }
            else
            {
                // Is this something that's in our context?
                int idx = 0;
                foreach (var genericArgument in orderedTypeContext)
                {
                    if (genericArgument.Equals(parameterType))
                    {
                        return string.Format("MVAR {0}", idx);
                    }

                    idx++;
                }
            }

            // Fall back to standard process
            return GetFriendlyTypeName(parameterType);
        }
Ejemplo n.º 7
0
        private static Match GetMatchFromType(ITypeDetails t)
        {
            var assy = t.Assembly.Name;
            var className = t.FullName;

            return new Match(assy, className);
        }
Ejemplo n.º 8
0
        private static string GetFriendlyTypeName(ITypeDetails t)
        {
            if (!t.IsGenericType)
            {
                return t.FullName;
            }
            else
            {
                // Generics when asked for their full-name do crazy things like:
                // System.Nullable`1[[System.Decimal, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
                // Which isn't much use to us as NewRelic uses a combination of backtick notation and angle brackets.
                // However, we can fiddle this...
                const string FORMAT = "{0}.{1}<{2}>";
                string[] innerTypes = t.GenericArguments.Select(x => string.Format("{0}", GetFriendlyTypeName(x))).ToArray();

                return string.Format(FORMAT, t.Namespace, t.Name, string.Join(",", innerTypes));
            }
        }
Ejemplo n.º 9
0
 public DummyMethodDetails(ITypeDetails declaringType, string name)
 {
     this.DeclaringType = declaringType;
     this.Name          = name;
 }
            protected override IEnumerable<InstrumentationTarget> GetInstrumentationSet(ITypeDetails t, InstrumentAttribute context)
            {
                if (this.FirstContext == null)
                {
                    this.FirstContext = context;
                }

                this.ScannedTypes[t] = context;

                return base.GetInstrumentationSet(t, context);
            }
        protected virtual IEnumerable <InstrumentationTarget> GetInstrumentationSet(ITypeDetails t, InstrumentAttribute context)
        {
            var toReturn = new List <InstrumentationTarget>();

            if (!t.IsGenericTypeDefinition)
            {
                // Does the type have an Instrument attribute?
                var typeLevelAttribute = t.InstrumentationContext;
                typeLevelAttribute = InstrumentAttribute.GetEffectiveInstrumentationContext(typeLevelAttribute, context);

                if (t.IsCompilerGenerated && (typeLevelAttribute == null || !typeLevelAttribute.IncludeCompilerGeneratedCode))
                {
                    // Bail out early - we've found a compiler-generated method and haven't been told to include 'em
                    _logger.DebugFormat("Skipping type {0} - compiler-generated and configuration set to skip", t.FullName);

                    return(toReturn);
                }

                _logger.DebugFormat("Processing type {0}", t.FullName);

                var baseBindingFlags   = BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly;
                var propBindingFlags   = baseBindingFlags;
                var methodBindingFlags = baseBindingFlags;
                var ctorBindingFlags   = baseBindingFlags;

                if (typeLevelAttribute == null)
                {
                    propBindingFlags   |= BindingFlags.NonPublic | BindingFlags.Public;
                    methodBindingFlags |= BindingFlags.NonPublic | BindingFlags.Public;
                    ctorBindingFlags   |= BindingFlags.NonPublic | BindingFlags.Public;
                }
                else
                {
                    if ((typeLevelAttribute.Scopes & InstrumentationScopes.PublicProperties) == InstrumentationScopes.PublicProperties)
                    {
                        propBindingFlags |= BindingFlags.Public;
                    }
                    if ((typeLevelAttribute.Scopes & InstrumentationScopes.NonPublicProperties) == InstrumentationScopes.NonPublicProperties)
                    {
                        propBindingFlags |= BindingFlags.NonPublic;
                    }

                    if ((typeLevelAttribute.Scopes & InstrumentationScopes.PublicMethods) == InstrumentationScopes.PublicMethods)
                    {
                        methodBindingFlags |= BindingFlags.Public;
                    }
                    if ((typeLevelAttribute.Scopes & InstrumentationScopes.NonPublicMethods) == InstrumentationScopes.NonPublicMethods)
                    {
                        methodBindingFlags |= BindingFlags.NonPublic;
                    }

                    if ((typeLevelAttribute.Scopes & InstrumentationScopes.PublicConstructors) == InstrumentationScopes.PublicConstructors)
                    {
                        ctorBindingFlags |= BindingFlags.Public;
                    }
                    if ((typeLevelAttribute.Scopes & InstrumentationScopes.NonPublicConstructors) == InstrumentationScopes.NonPublicConstructors)
                    {
                        ctorBindingFlags |= BindingFlags.NonPublic;
                    }
                }

                _logger.DebugFormat("Prop flags {0}, Ctor flags {1}, Method flags {2}", propBindingFlags, ctorBindingFlags, methodBindingFlags);

                // Instrument everything in this type, irrespective of its member-level
                // details
                foreach (var methodDetails in t.GetMethods(methodBindingFlags))
                {
                    _logger.DebugFormat("Examining method {0}", methodDetails.ToString());

                    var attr = InstrumentAttribute.GetEffectiveInstrumentationContext(methodDetails.InstrumentationContext, typeLevelAttribute);
                    if (attr != null && (!methodDetails.IsCompilerGenerated || attr.IncludeCompilerGeneratedCode))
                    {
                        toReturn.Add(GetInstrumentationTarget(methodDetails, attr));
                    }
                }

                foreach (var propertyDetails in t.GetProperties(propBindingFlags))
                {
                    _logger.DebugFormat("Examining property {0}.{1}", t.FullName, propertyDetails.Name);

                    var getMethod = propertyDetails.GetMethod;
                    var setMethod = propertyDetails.SetMethod;

                    if (getMethod != null && getMethod.ContainsGenericParameters)
                    {
                        getMethod = null;
                    }

                    if (setMethod != null && setMethod.ContainsGenericParameters)
                    {
                        setMethod = null;
                    }

                    if (getMethod != null)
                    {
                        var getMethodAttr = InstrumentAttribute.GetEffectiveInstrumentationContext(propertyDetails.InstrumentationContext, getMethod.InstrumentationContext, typeLevelAttribute);
                        if (getMethodAttr != null)
                        {
                            toReturn.Add(GetInstrumentationTarget(getMethod, getMethodAttr));
                        }
                    }

                    if (setMethod != null)
                    {
                        var setMethodAttr = InstrumentAttribute.GetEffectiveInstrumentationContext(propertyDetails.InstrumentationContext, setMethod.InstrumentationContext, typeLevelAttribute);
                        if (setMethodAttr != null)
                        {
                            toReturn.Add(GetInstrumentationTarget(setMethod, setMethodAttr));
                        }
                    }
                }

                foreach (var constructorDetails in t.GetConstructors(ctorBindingFlags).Where(x => !x.ContainsGenericParameters))
                {
                    _logger.DebugFormat("Examining method {0}", constructorDetails.ToString());

                    var attr = InstrumentAttribute.GetEffectiveInstrumentationContext(constructorDetails.InstrumentationContext, typeLevelAttribute);
                    if (attr != null)
                    {
                        toReturn.Add(GetInstrumentationTarget(constructorDetails, attr));
                    }
                }

                // Process nested types recursively, rather than enumerating them from the get-go so that we can apply
                // instrumentation scoping recursively too - the nested class will take on the instrumentation configuration
                // of the containing type, if any, or whatever's been passed down by initial settings
                foreach (var nested in t.GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static))
                {
                    toReturn.AddRange(GetInstrumentationSet(nested, typeLevelAttribute));
                }
            }
            else
            {
                _logger.DebugFormat("Skipping type {0} - generic types not supported", t.FullName);
            }

            return(toReturn);
        }
            protected override IEnumerable<InstrumentationTarget> GetInstrumentationSet(ITypeDetails t, InstrumentAttribute context)
            {
                if (this.FirstContext == null)
                {
                    this.FirstContext = context;
                }

                this.ScannedTypes[t] = context;

                return base.GetInstrumentationSet(t, context);
            }