Add() публичный статический Метод

Adds the specified log message.
public static Add ( Level level, string format ) : void
level Level The level.
format string The format.
Результат void
Пример #1
0
        /// <summary>
        /// Adds or updates a performance counter categories information.
        /// </summary>
        /// <param name="categoryName">Name of the category.</param>
        /// <param name="typeReference">The type reference.</param>
        /// <param name="assembly">The assembly.</param>
        /// <param name="categoryHelp">The category help.</param>
        public static void Set(
            [NotNull] string categoryName,
            [NotNull] TypeReference typeReference,
            [NotNull] string assembly,
            string categoryHelp)
        {
            if (categoryName == null)
            {
                throw new ArgumentNullException("categoryName");
            }
            if (typeReference == null)
            {
                throw new ArgumentNullException("typeReference");
            }
            if (assembly == null)
            {
                throw new ArgumentNullException("assembly");
            }
            try
            {
                PerformanceType performanceType = PerformanceType.Get(typeReference);
                PerfCategory    category        = _categories.GetOrAdd(
                    categoryName,
                    // ReSharper disable once AssignNullToNotNullAttribute
                    n => new PerfCategory(assembly, performanceType, n));
                Debug.Assert(category != null);

                // Type cannot change.
                if (category.PerformanceType != performanceType)
                {
                    Logger.Add(
                        Level.Error,
                        "The '{0}' performance counter category was declared more than once with different types ('{1}' and '{2}') in assembly '{3}'.",
                        categoryName,
                        category.PerformanceType,
                        performanceType,
                        assembly);
                    return;
                }

                // Only update category help if not already set.
                if (!string.IsNullOrWhiteSpace(categoryHelp) &&
                    string.IsNullOrWhiteSpace(category.CategoryHelp))
                {
                    category.CategoryHelp = categoryHelp;
                }

                // Add assembly if not seen before
                if (!category._assemblies.Contains(assembly))
                {
                    category._assemblies.Add(assembly);
                }
            }
            catch (Exception e)
            {
                Logger.Add(
                    Level.Error,
                    "Failed to set performance category information for category '{0}' in assembly '{1}'. {2}",
                    categoryName,
                    assembly,
                    e.Message);
            }
        }
Пример #2
0
        /// <summary>
        /// Scans the supplied <see paramref="fullPath" /> (to a directory or assembly) for performance counters and adds/deletes/lists
        /// them depending on the <see paramref="mode" />.
        /// </summary>
        /// <param name="mode">The mode.</param>
        /// <param name="fullPath">The assemblies path.</param>
        /// <param name="executeAgain">if set to <see langword="true" /> execute's again on 64-bit OS.</param>
        public static void Execute(
            ScanMode mode,
            [NotNull] string fullPath,
            bool executeAgain)
        {
            if (fullPath == null)
            {
                throw new ArgumentNullException("fullPath");
            }

            // Check we have access to the performance counters.
            PerformanceCounterCategory.Exists("TestAccess");

            string[] files;
            string   directory;

            try
            {
                fullPath = Path.GetFullPath(fullPath.Trim());
                if (File.Exists(fullPath))
                {
                    directory = Path.GetDirectoryName(fullPath);
                    files     = new[] { fullPath };
                }
                else if (Directory.Exists(fullPath))
                {
                    directory = fullPath;
                    files     = Directory.GetFiles(fullPath)
                                .Where(
                        f =>
                    {
                        // ReSharper disable once PossibleNullReferenceException
                        string ext = Path.GetExtension(f).ToLower();
                        return(ext == ".dll" || ext == ".exe");
                    }).ToArray();
                }
                else
                {
                    Logger.Add(Level.Error, "The '{0}' path is neither a file or directory.", fullPath);
                    return;
                }
            }
            catch (Exception e)
            {
                Logger.Add(Level.Error, "The '{0}' path was invalid. {1}", fullPath, e.Message);
                return;
            }

            Debug.Assert(files != null);
            Debug.Assert(directory != null);

            if (!files.Any())
            {
                Logger.Add(
                    Level.Warning,
                    "The '{0}' path did not match any executables or dlls, so no performance counters added.",
                    fullPath);
                return;
            }

            AssemblyResolver.AddSearchDirectory(directory);
            foreach (string file in files)
            {
                Load(file);
            }

            int succeeded = 0;
            int failed    = 0;

            foreach (PerfCategory performanceInformation in PerfCategory.All)
            {
                switch (mode)
                {
                case ScanMode.Add:
                    bool added = performanceInformation.Create();
                    Logger.Add(
                        added ? Level.Normal : Level.Error,
                        "Adding '{0}' {1}",
                        performanceInformation,
                        added ? "succeeded" : "failed");
                    if (added)
                    {
                        succeeded++;
                    }
                    else
                    {
                        failed++;
                    }
                    break;

                case ScanMode.Delete:
                    bool deleted = performanceInformation.Delete();
                    Logger.Add(
                        deleted ? Level.Normal : Level.Error,
                        "Deleting '{0}' {1}",
                        performanceInformation,
                        deleted ? "succeeded" : "failed");
                    if (deleted)
                    {
                        succeeded++;
                    }
                    else
                    {
                        failed++;
                    }
                    break;

                default:
                    // Treat everything else as list.
                    bool exists = performanceInformation.Exists;
                    Logger.Add(
                        exists ? Level.Normal : Level.Error,
                        "'{0}' {1}",
                        performanceInformation,
                        exists ? "exists" : "is missing");
                    if (exists)
                    {
                        succeeded++;
                    }
                    else
                    {
                        failed++;
                    }
                    break;
                }
            }

            if (succeeded + failed > 0)
            {
                string operation;
                switch (mode)
                {
                case ScanMode.Add:
                    operation = "Added";
                    break;

                case ScanMode.Delete:
                    operation = "Deleted";
                    break;

                default:
                    operation = "Found";
                    break;
                }
                Logger.Add(
                    Level.High,
                    "{0} '{1}' performance counters.{2}",
                    operation,
                    succeeded,
                    failed > 0 ? string.Format(" {0} failures.", failed) : string.Empty);

                if (executeAgain &&
                    Environment.Is64BitOperatingSystem)
                {
                    bool bit64 = Environment.Is64BitProcess;
                    Logger.Add(
                        Level.High,
                        "Running PerfSetup in {0} bit process on 64 bit operating system, will run again in {1} bit mode to ensure counters are added to both environments!",
                        bit64 ? 64 : 32,
                        bit64 ? 32 : 64);
                    ExecuteAgain(mode, fullPath, !bit64);
                }
            }
            else
            {
                Logger.Add(Level.High, "No valid performance counters found.");
            }
        }
Пример #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PerformanceType" /> class.
        /// </summary>
        /// <param name="typeReference">The type reference.</param>
        /// <exception cref="System.NotImplementedException"></exception>
        // ReSharper disable once NotNullMemberIsNotInitialized
        private PerformanceType([NotNull] TypeReference typeReference)
        {
            if (typeReference == null)
            {
                throw new ArgumentNullException("typeReference");
            }
            TypeReference = typeReference;
            try
            {
                TypeDefinition typeDefinition = typeReference.Resolve();
                Debug.Assert(typeDefinition != null);

                // Confirm we descend from PerfCategory
                TypeDefinition baseType = typeDefinition;
                do
                {
                    baseType = baseType.BaseType != null
                        ? baseType.BaseType.Resolve()
                        : null;

                    if (baseType == null)
                    {
                        Logger.Add(
                            Level.Error,
                            "The '{0}' type does not descend from 'WebApplications.Utilities.Performance.PerfCategory' and so cannot be used.",
                            typeDefinition.FullName);
                        IsValid = false;
                        return;
                    }

                    // Check for match
                    if ((baseType.FullName == "WebApplications.Utilities.Performance.PerfCategory") &&
                        // ReSharper disable PossibleNullReferenceException
                        (baseType.Module.Assembly.Name.Name == "WebApplications.Utilities.Performance"))
                    {
                        // ReSharper restore PossibleNullReferenceException
                        break;
                    }
                } while (true);

                // Find CounterCreationData[] field
                // ReSharper disable once AssignNullToNotNullAttribute
                FieldDefinition creationField = typeDefinition
                                                .Fields
                                                .SingleOrDefault(
                    fd =>
                    // ReSharper disable PossibleNullReferenceException
                    fd.IsStatic && fd.FieldType.FullName == "System.Diagnostics.CounterCreationData[]" &&
                    // ReSharper restore PossibleNullReferenceException
                    fd.IsInitOnly
                    );

                if (creationField == null)
                {
                    Logger.Add(
                        Level.Error,
                        "The '{0}' type does not contains a single readonly static field of type 'System.Diagnostics.CounterCreationData[]' so counters cannot be created.",
                        typeDefinition.FullName);
                    IsValid = false;
                    return;
                }

                // Find static constructor (initialised static readonly fields must be initialized from a static constructor).
                MethodDefinition staticConstructor =
                    // ReSharper disable once AssignNullToNotNullAttribute, PossibleNullReferenceException
                    typeDefinition.Methods.SingleOrDefault(m => m.IsConstructor && m.IsStatic);
                if ((staticConstructor == null) ||
                    !staticConstructor.HasBody)
                {
                    Logger.Add(
                        Level.Error,
                        "The '{0}' type does not contain a static constructor so the initial values for the '{1}' field cannot be parsed.",
                        typeDefinition.FullName,
                        creationField.FullName);
                    IsValid = false;
                    return;
                }

                // Parse static constructor for creation data.
                // TODO Genericising this and sharing with Scan would be very cool (but also quite complex).
                Queue <string>             lastStrings     = new Queue <string>(2);
                PerformanceCounterType     lastCounterType = default(PerformanceCounterType);
                List <CounterCreationData> data            = new List <CounterCreationData>();
                // ReSharper disable PossibleNullReferenceException
                foreach (Instruction instr in staticConstructor.Body.Instructions)
                // ReSharper restore PossibleNullReferenceException
                {
                    Debug.Assert(instr != null);

                    // Detect string literals being loaded onto evaluation stack
                    if (instr.OpCode.Code == Code.Ldstr)
                    {
                        // We track last two load strings.
                        if (lastStrings.Count > 1)
                        {
                            lastStrings.Dequeue();
                        }

                        lastStrings.Enqueue(instr.Operand as string);
                        continue;
                    }

                    // Detect nulls being loaded onto evaluation stack
                    if (instr.OpCode.Code == Code.Ldnull)
                    {
                        // We track last two load strings.
                        if (lastStrings.Count > 1)
                        {
                            lastStrings.Dequeue();
                        }

                        lastStrings.Enqueue(null);
                        continue;
                    }

                    // Detect integers being loaded onto the evaluation stack.
                    if (instr.OpCode.Code == Code.Ldc_I4)
                    {
                        // If the int is not a valid performance counter type, clear strings (as this isn't the right data).
                        // ReSharper disable once PossibleNullReferenceException
                        if (!_performanceCounterTypes.TryGetValue((int)instr.Operand, out lastCounterType))
                        {
                            lastStrings.Clear();
                        }
                        continue;
                    }

                    if (instr.OpCode.Code != Code.Newobj)
                    {
                        // If we have any ops other than NewObj after our loads then the loads aren't for us.
                        lastStrings.Clear();
                        lastCounterType = default(PerformanceCounterType);
                        continue;
                    }

                    // Check we have a 3 parameter constructor with the right types
                    MethodReference methodReference = instr.Operand as MethodReference;
                    if ((methodReference == null) ||
                        // ReSharper disable PossibleNullReferenceException
                        (methodReference.Parameters.Count != 3) ||
                        (methodReference.Parameters[0].ParameterType.FullName != "System.String") ||
                        (methodReference.Parameters[1].ParameterType.FullName != "System.String") ||
                        (methodReference.Parameters[2].ParameterType.FullName !=
                         // ReSharper restore PossibleNullReferenceException
                         "System.Diagnostics.PerformanceCounterType"))
                    {
                        continue;
                    }

                    // Check this is a constructor for CounterCreationData.
                    TypeReference ctr = methodReference.DeclaringType;
                    if ((ctr == null) ||
                        (ctr.FullName !=
                         "System.Diagnostics.CounterCreationData"))
                    {
                        continue;
                    }

                    if (lastStrings.Count == 2)
                    {
                        // Add creation data.
                        string counterCategory = lastStrings.Dequeue();
                        string counterHelp     = lastStrings.Dequeue();
                        data.Add(new CounterCreationData(counterCategory, counterHelp, lastCounterType));
                        Logger.Add(
                            Level.Low,
                            "The '{0}' type specifies CounterCreationData(\"{1}\", {2}, PerformanceCounterType.{3}).",
                            typeReference.FullName,
                            counterCategory,
                            counterHelp == null ? "null" : "\"" + counterHelp + "\"",
                            lastCounterType);
                    }
                    else
                    {
                        Logger.Add(
                            Level.Warning,
                            "Performance counter creation data construction was found for the '{0}' type, but the parameters were not literals and so could not be decoded.",
                            typeDefinition.FullName);
                        IsValid = false;
                        return;
                    }

                    lastStrings.Clear();
                }

                if (data.Count < 1)
                {
                    Logger.Add(
                        Level.Warning,
                        "The '{0}' type does not appear to contain any initialisation data for the '{1}' field.",
                        typeDefinition.FullName,
                        creationField.FullName);
                    IsValid = false;
                    return;
                }

                // We have valid creation data for the type.
                CounterCreationData = data.ToArray();
                Logger.Add(
                    Level.Normal,
                    "The '{0}' type defines '{1}' performance counters.",
                    typeDefinition.FullName,
                    CounterCreationData.Length);
                IsValid = true;
            }
            catch (Exception e)
            {
                Logger.Add(
                    Level.Error,
                    "Fatal error occurred trying to parse the '{0}' performance counter type. {1}",
                    typeReference.FullName,
                    e.Message);
                IsValid = false;
            }
        }
Пример #4
0
        /// <summary>
        /// Loads the specified assembly and checks for performance counter use.
        /// </summary>
        /// <param name="assemblyPath">The assembly path.</param>
        private static void Load(string assemblyPath)
        {
            AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(assemblyPath, ReaderParameters);

            Debug.Assert(assembly != null);
            Debug.Assert(assembly.Name != null);
            if (assembly.Name.Name == "WebApplications.Utilities.Performance")
            {
                return;
            }

            // Find any modules that reference logging.
            // ReSharper disable once AssignNullToNotNullAttribute
            ModuleDefinition[] referencingModules = assembly.Modules
                                                    .Where(
                // ReSharper disable PossibleNullReferenceException, AssignNullToNotNullAttribute
                m => m.AssemblyReferences
                .FirstOrDefault(
                    ar => ar.Name == "WebApplications.Utilities.Performance") !=
                null)
                                                    // ReSharper restore PossibleNullReferenceException, AssignNullToNotNullAttribute
                                                    .ToArray();

            if (referencingModules.Length < 1)
            {
                return;
            }

            Queue <string> lastStrings = new Queue <string>(2);

            foreach (ModuleDefinition module in referencingModules)
            {
                Debug.Assert(module != null);
                Debug.Assert(module.Types != null);
                foreach (TypeDefinition type in module.Types)
                {
                    Debug.Assert(type != null);
                    Debug.Assert(type.Methods != null);
                    foreach (MethodDefinition method in type.Methods)
                    {
                        Debug.Assert(method != null);

                        if (!method.HasBody)
                        {
                            continue;
                        }

                        lastStrings.Clear();

                        Debug.Assert(method.Body != null);
                        Debug.Assert(method.Body.Instructions != null);
                        foreach (Instruction instr in method.Body.Instructions)
                        {
                            Debug.Assert(instr != null);

                            // Detect string literals loaded onto evaluation stack
                            if (instr.OpCode.Code == Code.Ldstr)
                            {
                                // We track last two load strings.
                                if (lastStrings.Count > 1)
                                {
                                    lastStrings.Dequeue();
                                }

                                lastStrings.Enqueue(instr.Operand as string);
                                continue;
                            }

                            // Detect nulls being loaded onto evaluation stack
                            if (instr.OpCode.Code == Code.Ldnull)
                            {
                                // We track last two load strings.
                                if (lastStrings.Count > 1)
                                {
                                    lastStrings.Dequeue();
                                }

                                lastStrings.Enqueue(null);
                                continue;
                            }

                            if (instr.OpCode.Code != Code.Call)
                            {
                                // If we have any ops other than NewObj after our loads then the loads aren't for us.
                                lastStrings.Clear();
                                continue;
                            }

                            // Make sure we have the right method signature.
                            GenericInstanceMethod methodReference = instr.Operand as GenericInstanceMethod;
                            if ((methodReference == null) ||
                                (methodReference.Name != "GetOrAdd") ||
                                !methodReference.HasGenericArguments ||
                                !methodReference.IsGenericInstance ||
                                // ReSharper disable PossibleNullReferenceException
                                (methodReference.GenericArguments.Count != 1) ||
                                (methodReference.Parameters.Count != 2) ||
                                (methodReference.Parameters[0].ParameterType.FullName != "System.String") ||
                                (methodReference.Parameters[1].ParameterType.FullName != "System.String"))
                            {
                                // ReSharper restore PossibleNullReferenceException
                                continue;
                            }

                            // Make sure it's on the right type.
                            TypeReference typeReference = methodReference.DeclaringType;
                            if ((typeReference == null) ||
                                (typeReference.FullName !=
                                 "WebApplications.Utilities.Performance.PerfCategory"))
                            {
                                continue;
                            }

                            TypeReference perfCategoryType = methodReference.GenericArguments.First();
                            Debug.Assert(perfCategoryType != null);

                            if (lastStrings.Count > 1)
                            {
                                int  pCount  = methodReference.Parameters.Count();
                                bool isTimer = pCount == 4;
                                Debug.Assert(isTimer || (pCount == 2));
                                string categoryName = lastStrings.Dequeue();
                                string categoryHelp = lastStrings.Dequeue();

                                // We have a constructor set performance information.
                                if (!String.IsNullOrWhiteSpace(categoryName))
                                {
                                    Logger.Add(
                                        Level.Low,
                                        "The '{0}' assembly calls PerfCategory.GetOrAdd<{1}>(\"{2}\", {3}).",
                                        assemblyPath,
                                        perfCategoryType.Name,
                                        categoryName,
                                        categoryHelp == null ? "null" : "\"" + categoryHelp + "\"");

                                    PerfCategory.Set(
                                        categoryName,
                                        perfCategoryType,
                                        // ReSharper disable once AssignNullToNotNullAttribute
                                        assembly.Name.Name,
                                        categoryHelp);
                                }
                                else
                                {
                                    Logger.Add(
                                        Level.Error,
                                        "Performance counter creation found in '{0}' but category name was null or empty - make sure you use inline strings as constructor parameters.  Press any key to continue",
                                        assemblyPath);
                                }
                            }
                            else
                            {
                                Logger.Add(
                                    Level.Error,
                                    "Performance counter creation found in '{0}' but could not find category name and or category help - make sure you use inline strings as constructor parameters.  Press any key to continue",
                                    assemblyPath);
                            }
                            lastStrings.Clear();
                        }
                    }
                }
            }
        }