public void Activate()
        {
            if (this.isDisposed)
            {
                throw new ObjectDisposedException(nameof(EtwInput));
            }

            if (this.session != null)
            {
                throw new InvalidOperationException($"{nameof(EtwInput)} has already been activated");
            }

            if (this.Providers.Count() == 0)
            {
                healthReporter.ReportWarning($"{nameof(EtwInput)}: no providers configured", nameof(EtwInput));
                return;
            }

            this.session = SessionFactory();

            foreach (var providerConfiguration in this.Providers)
            {
                string validationError;
                if (!providerConfiguration.Validate(out validationError))
                {
                    this.healthReporter.ReportWarning($"{nameof(EtwInput)}: one of the providers is configured improperly. {validationError}", EventFlowContextIdentifiers.Configuration);
                    continue;
                }
                if (providerConfiguration.ProviderGuid != Guid.Empty)
                {
                    this.session.EnableProvider(providerConfiguration.ProviderGuid, providerConfiguration.Level, (ulong)providerConfiguration.Keywords);
                }
                else
                {
                    this.session.EnableProvider(providerConfiguration.ProviderName, providerConfiguration.Level, (ulong)providerConfiguration.Keywords);
                }
            }

            // Also enable .NET Task Parallel Library hierarchical activity tracking
            this.session.EnableProvider(TplActivities.TplEventSourceGuid, TraceEventLevel.Always, TplActivities.TaskFlowActivityIdsKeyword);

            Task.Factory.StartNew(() =>
            {
                try
                {
                    this.session.Process((eventData) => this.subject.OnNext(eventData));
                }
                catch (Exception e)
                {
                    this.healthReporter.ReportProblem($"{nameof(EtwInput)}: ETW session has terminated unexpectedly and events are no longer collected. {e.ToString()}");
                }
            }, TaskCreationOptions.LongRunning);
        }
        public void Dispose()
        {
            if (this.isDisposed)
            {
                return;
            }
            this.isDisposed = true;

            if (this.session != null)
            {
                // Might have been null if no providers were configured.
                this.session.Dispose();
                this.session = null;
            }

            this.subject.Dispose();
        }
Beispiel #3
0
        /// <summary>
        /// Initializes the telemetry module and starts tracing ETW events specified via <see cref="Sources"/> property.
        /// </summary>
        /// <param name="configuration">Module configuration.</param>
        public void Initialize(TelemetryConfiguration configuration)
        {
            string errorMessage;

            if (configuration == null)
            {
                errorMessage = string.Format(CultureInfo.InvariantCulture, "Argument {0} is required. The initialization is terminated.", nameof(configuration));
                EventSourceListenerEventSource.Log.ModuleInitializationFailed(
                    nameof(EtwTelemetryModule),
                    errorMessage);
                return;
            }

            if (this.isDisposed)
            {
                errorMessage = "Can't initialize a module that is disposed. The initialization is terminated.";
                EventSourceListenerEventSource.Log.ModuleInitializationFailed(
                    nameof(EtwTelemetryModule),
                    errorMessage);
                return;
            }

            lock (this.lockObject)
            {
                this.client = new TelemetryClient(configuration);

                // sdkVersionIdentifier will be used in telemtry entry as a identifier for the sender.
                // The value will look like: etw:x.x.x-x
                const string SdkVersionIdentifier = "etw:";
                this.client.Context.GetInternalContext().SdkVersion = SdkVersionUtils.GetSdkVersion(SdkVersionIdentifier);

                if (this.isInitialized)
                {
                    this.DisableProviders();
                    this.enabledProviderIds.Clear();
                    this.enabledProviderNames.Clear();
                }

                if (this.Sources.Count == 0)
                {
                    EventSourceListenerEventSource.Log.NoSourcesConfigured(moduleName: nameof(EtwTelemetryModule));
                    this.isInitialized = false;
                    return;
                }

                if (this.traceEventSession == null)
                {
                    this.traceEventSession = this.traceEventSessionFactory();
                }

                this.EnableProviders();

                if (!this.isInitialized)
                {
                    try
                    {
                        // Start the trace session
                        if (this.traceEventSession != null && this.traceEventSession.Source != null && this.traceEventSession.Source.Dynamic != null)
                        {
                            this.traceEventSession.Source.Dynamic.All += this.OnEvent;
                            Task.Factory.StartNew(
                                () =>
                            {
                                this.traceEventSession.Source.Process();
                                this.traceEventSession.Source.Dynamic.All -= this.OnEvent;
                                this.isInitialized = false;
                            },
                                TaskCreationOptions.LongRunning);
                        }
                    }
                    finally
                    {
                        this.isInitialized = true;
                    }
                }
            }
        }