예제 #1
0
        private static EventPipeConfiguration BuildConfigFromEnvironment()
        {
            // Build the full path to the trace file.
            string traceFileName  = BuildTraceFileName();
            string outputFilePath = Path.Combine(Config_EventPipeOutputPath, traceFileName);

            // Create a new configuration object.
            EventPipeConfiguration config = new EventPipeConfiguration(
                outputFilePath,
                Config_EventPipeCircularMB);

            // Get the configuration.
            string strConfig = Config_EventPipeConfig;

            if (!string.IsNullOrEmpty(strConfig))
            {
                // If the configuration is specified, parse it and save it to the config object.
                SetProviderConfiguration(strConfig, config);
            }
            else
            {
                // Specify the default configuration.
                config.EnableProviderRange(DefaultProviderConfiguration);
            }

            return(config);
        }
예제 #2
0
        private static void SetProviderConfiguration(string strConfig, EventPipeConfiguration config)
        {
            if (string.IsNullOrEmpty(strConfig))
            {
                throw new ArgumentNullException(nameof(strConfig));
            }

            // Provider format: "(GUID|KnownProviderName)[:Flags[:Level][:KeyValueArgs]]"
            // where KeyValueArgs are of the form: "[key1=value1][;key2=value2]"
            // `strConfig` must be of the form "Provider[,Provider]"
            string[] providers = strConfig.Split(
                ProviderConfigDelimiter,
                StringSplitOptions.RemoveEmptyEntries); // Remove "empty" providers.
            foreach (string provider in providers)
            {
                // Split expecting a maximum of four tokens.
                string[] components = provider.Split(
                    ConfigComponentDelimiter,
                    4,                        // if there is ':' in the parameters then anything after it will not be ignored.
                    StringSplitOptions.None); // Keep empty tokens

                string providerName = components.Length > 0 ? components[0] : null;
                if (string.IsNullOrEmpty(providerName))
                {
                    continue;  // No provider name specified.
                }
                ulong keywords = ulong.MaxValue;
                if (components.Length > 1)
                {
                    // We use a try/catch block here because ulong.TryParse won't accept 0x at the beginning
                    // of a hex string.  Thus, we either need to conditionally strip it or handle the exception.
                    // Given that this is not a perf-critical path, catching the exception is the simpler code.
                    try
                    {
                        keywords = Convert.ToUInt64(components[1], 16);
                    }
                    catch
                    {
                    }
                }

                uint level = 5; // Verbose
                if (components.Length > 2)
                {
                    uint.TryParse(components[2], out level);
                }

                string filterData = components.Length > 3 ? components[3] : null;

                config.EnableProviderWithFilter(providerName, keywords, level, filterData);
            }
        }
예제 #3
0
        private static EventPipeConfiguration GetConfiguration()
        {
            // Create a new configuration object.
            EventPipeConfiguration config = new EventPipeConfiguration(
                GetDisambiguatedTraceFilePath(Config_EventPipeOutputFile),
                Config_EventPipeCircularMB);

            // Get the configuration.
            string strConfig = Config_EventPipeConfig;

            if (!string.IsNullOrEmpty(strConfig))
            {
                // String must be of the form "providerName:keywords:level,providerName:keywords:level..."
                string[] providers = strConfig.Split(ProviderConfigDelimiter);
                foreach (string provider in providers)
                {
                    string[] components = provider.Split(ConfigComponentDelimiter);
                    if (components.Length == 3)
                    {
                        string providerName = components[0];

                        // We use a try/catch block here because ulong.TryParse won't accept 0x at the beginning
                        // of a hex string.  Thus, we either need to conditionally strip it or handle the exception.
                        // Given that this is not a perf-critical path, catching the exception is the simpler code.
                        ulong keywords = 0;
                        try
                        {
                            keywords = Convert.ToUInt64(components[1], 16);
                        }
                        catch { }

                        uint level;
                        if (!uint.TryParse(components[2], out level))
                        {
                            level = 0;
                        }

                        config.EnableProvider(providerName, keywords, level);
                    }
                }
            }
            else
            {
                // Specify the default configuration.
                config.EnableProviderRange(DefaultProviderConfiguration);
            }

            return(config);
        }
예제 #4
0
        internal static void Enable(EventPipeConfiguration configuration)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            EventPipeProviderConfiguration[] providers = configuration.Providers;

            EventPipeInternal.Enable(
                configuration.OutputFile,
                configuration.CircularBufferSizeInMB,
                configuration.ProfilerSamplingRateInNanoseconds,
                providers,
                providers.Length);
        }
예제 #5
0
        internal static void Enable(EventPipeConfiguration configuration)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            if (configuration.Providers == null)
            {
                throw new ArgumentNullException(nameof(configuration.Providers));
            }

            EventPipeProviderConfiguration[] providers = configuration.Providers;

            s_sessionID = EventPipeInternal.Enable(
                configuration.OutputFile,
                configuration.Format,
                configuration.CircularBufferSizeInMB,
                providers);
        }
예제 #6
0
        internal static void Enable(EventPipeConfiguration configuration)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            if (configuration.Providers == null)
            {
                throw new ArgumentNullException(nameof(configuration.Providers));
            }

            EventPipeProviderConfiguration[] providers = configuration.Providers;

            s_sessionID = EventPipeInternal.Enable(
                configuration.OutputFile,
                configuration.CircularBufferSizeInMB,
                (ulong)configuration.ProfilerSamplingRateInNanoseconds,
                providers,
                (uint)providers.Length,
                configuration.MultiFileTraceLengthInSeconds);
        }
예제 #7
0
        private void PollForTracingCommand(object state)
        {
            // Make sure that any transient errors don't cause the listener thread to exit.
            try
            {
                // Check for existence of the config file.
                // If the existence of the file has changed since the last time we checked or the update time has changed
                // this means that we need to act on that change.
                bool fileExists = File.Exists(m_configFilePath);
                if (m_configFileExists != fileExists)
                {
                    // Save the result.
                    m_configFileExists = fileExists;

                    // Take the appropriate action.
                    if (fileExists)
                    {
                        // Enable tracing.
                        // Check for null here because it's possible that the configuration contains a process filter
                        // that doesn't match the current process.  IF this occurs, we should't enable tracing.
                        EventPipeConfiguration config = BuildConfigFromFile(m_configFilePath);
                        if (config != null)
                        {
                            EventPipe.Enable(config);
                        }
                    }
                    else
                    {
                        // Disable tracing.
                        EventPipe.Disable();
                    }
                }

                // Schedule the timer to run again.
                m_timer.Change(fileExists ? EnabledPollingIntervalMilliseconds : DisabledPollingIntervalMilliseconds, Timeout.Infinite);
            }
            catch { }
        }
예제 #8
0
        private static void SetProviderConfiguration(string strConfig, EventPipeConfiguration config)
        {
            if (string.IsNullOrEmpty(strConfig))
            {
                throw new ArgumentNullException(nameof(strConfig));
            }

            // String must be of the form "providerName:keywords:level,providerName:keywords:level..."
            string[] providers = strConfig.Split(ProviderConfigDelimiter);
            foreach (string provider in providers)
            {
                string[] components = provider.Split(ConfigComponentDelimiter);
                if (components.Length == 3)
                {
                    string providerName = components[0];

                    // We use a try/catch block here because ulong.TryParse won't accept 0x at the beginning
                    // of a hex string.  Thus, we either need to conditionally strip it or handle the exception.
                    // Given that this is not a perf-critical path, catching the exception is the simpler code.
                    ulong keywords = 0;
                    try
                    {
                        keywords = Convert.ToUInt64(components[1], 16);
                    }
                    catch { }

                    uint level;
                    if (!uint.TryParse(components[2], out level))
                    {
                        level = 0;
                    }

                    config.EnableProvider(providerName, keywords, level);
                }
            }
        }
예제 #9
0
        private static EventPipeConfiguration BuildConfigFromFile(string configFilePath)
        {
            // Read the config file in once call.
            byte[] configContents = File.ReadAllBytes(configFilePath);

            // Convert the contents to a string.
            string strConfigContents = Encoding.UTF8.GetString(configContents);

            // Read all of the config options.
            string outputPath        = null;
            string strProviderConfig = null;
            string strCircularMB     = null;
            string strProcessID      = null;
            string strMultiFileSec   = null;

            // Split the configuration entries by line.
            string[] configEntries = strConfigContents.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string configEntry in configEntries)
            {
                //`Split the key and value by '='.
                string[] entryComponents = configEntry.Split(
                    ConfigEntryDelimiter,
                    2,  // Stop split on first occurrence of the separator.
                    StringSplitOptions.RemoveEmptyEntries);
                if (entryComponents.Length == 2)
                {
                    string key = entryComponents[0];
                    if (key.Equals(ConfigKey_Providers))
                    {
                        strProviderConfig = entryComponents[1];
                    }
                    else if (key.Equals(ConfigKey_OutputPath))
                    {
                        outputPath = entryComponents[1];
                    }
                    else if (key.Equals(ConfigKey_CircularMB))
                    {
                        strCircularMB = entryComponents[1];
                    }
                    else if (key.Equals(ConfigKey_ProcessID))
                    {
                        strProcessID = entryComponents[1];
                    }
                    else if (key.Equals(ConfigKey_MultiFileSec))
                    {
                        strMultiFileSec = entryComponents[1];
                    }
                }
            }

            // Check the process ID filter if it is set.
            if (!string.IsNullOrEmpty(strProcessID))
            {
                // If set, bail out early if the specified process does not match the current process.
                int processID = Convert.ToInt32(strProcessID);
                if (processID != Interop.Kernel32.GetCurrentProcessId())
                {
                    return(null);
                }
            }

            // Ensure that the output path is set.
            if (string.IsNullOrEmpty(outputPath))
            {
                throw new ArgumentNullException(nameof(outputPath));
            }

            // Check to see if MultiFileSec is specified.
            ulong multiFileSec = 0;

            if (!string.IsNullOrEmpty(strMultiFileSec))
            {
                multiFileSec = Convert.ToUInt64(strMultiFileSec);
            }

            // Build the full path to the trace file.
            string traceFileName = BuildTraceFileName();
            string outputFile    = Path.Combine(outputPath, traceFileName);

            // Get the circular buffer size.
            uint circularMB = DefaultCircularBufferMB;

            if (!string.IsNullOrEmpty(strCircularMB))
            {
                circularMB = Convert.ToUInt32(strCircularMB);
            }

            // Initialize a new configuration object.
            EventPipeConfiguration config = new EventPipeConfiguration(outputFile, circularMB);

            config.SetMultiFileTraceLength(multiFileSec);

            // Set the provider configuration if specified.
            if (!string.IsNullOrEmpty(strProviderConfig))
            {
                SetProviderConfiguration(strProviderConfig, config);
            }
            else
            {
                // If the provider configuration isn't specified, use the default.
                config.EnableProviderRange(DefaultProviderConfiguration);
            }

            return(config);
        }