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(); }
/// <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; } } } }