/// <summary> /// Initializes a new instance of the <see cref="ExceptionTrackingTelemetryModule" /> class. /// </summary> public ExceptionTrackingTelemetryModule() { this.listener = new WebEventsSubscriber( new Dictionary<int, Action<EventWrittenEventArgs>> { { 3, this.OnError }, }); }
/// <summary> /// Initializes a new instance of the <see cref="RequestTrackingTelemetryModule" /> class. /// </summary> public RequestTrackingTelemetryModule() { this.listener = new WebEventsSubscriber( new Dictionary<int, Action<EventWrittenEventArgs>> { { 1, this.OnBeginRequest }, { 2, this.OnEndRequest } }); }
private void InitEventHandler() { // First time execution, initialize the logger verboseListener = new StorageFileEventListener("Log"); informationListener = new StorageFileEventListener("Warning"); verboseListener.EnableEvents(MetroEventSource.Instance, EventLevel.Verbose); informationListener.EnableEvents(MetroEventSource.Instance, EventLevel.Informational); }
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); listener = SignalRLog.CreateListener(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); listener.EnableEvents(SampleWebAppEventSource.Log, EventLevel.Verbose); SampleWebAppEventSource.Log.ApplicationStart(); }
internal EventDispatcher(EventDispatcher next, bool[] eventEnabled, EventListener listener) { m_Next = next; m_EventEnabled = eventEnabled; m_Listener = listener; }
/// <summary> /// Helper used in code:Dispose that removes any references to 'listenerToRemove' in any of the /// eventSources in the appdomain. /// /// The EventListenersLock must be held before calling this routine. /// </summary> private static void RemoveReferencesToListenerInEventSources(EventListener listenerToRemove) { // Foreach existing EventSource in the appdomain foreach (WeakReference eventSourceRef in s_EventSources) { EventSource eventSource = eventSourceRef.Target as EventSource; if (eventSource != null) { // Is the first output dispatcher the dispatcher we are removing? if (eventSource.m_Dispatchers.m_Listener == listenerToRemove) eventSource.m_Dispatchers = eventSource.m_Dispatchers.m_Next; else { // Remove 'listenerToRemove' from the eventSource.m_Dispatchers linked list. EventDispatcher prev = eventSource.m_Dispatchers; for (; ;) { EventDispatcher cur = prev.m_Next; if (cur == null) { Contract.Assert(false, "EventSource did not have a registered EventListener!"); break; } if (cur.m_Listener == listenerToRemove) { prev.m_Next = cur.m_Next; // Remove entry. break; } prev = cur; } } } } }
// Helper used by code:EventListener.AddEventSource and code:EventListener.EventListener // when a listener gets attached to a eventSource internal void AddListener(EventListener listener) { lock (EventListener.EventListenersLock) { bool[] enabledArray = null; if (m_eventData != null) enabledArray = new bool[m_eventData.Length]; m_Dispatchers = new EventDispatcher(m_Dispatchers, enabledArray, listener); listener.OnEventSourceCreated(this); } }
private void SetupEventTracing() { bool.TryParse(WebConfigurationManager.AppSettings["UseInprocEventTracing"], out this.useInprocEventTracing); if (this.useInprocEventTracing) { //Log to file all DataAccess events this.fileListener = FlatFileLog.CreateListener("aExpense.DataAccess.log", formatter: new XmlEventTextFormatter(EventTextFormatting.Indented), isAsync: true); fileListener.EnableEvents(AExpenseEvents.Log, EventLevel.LogAlways, AExpenseEvents.Keywords.DataAccess); //Log to Rolling file informational UI events only this.rollingfileListener = RollingFlatFileLog.CreateListener("aExpense.UserInterface.log", rollSizeKB: 10, timestampPattern: "yyyy", rollFileExistsBehavior: RollFileExistsBehavior.Increment, rollInterval: RollInterval.Day, formatter: new JsonEventTextFormatter(EventTextFormatting.Indented), isAsync: true); rollingfileListener.EnableEvents(AExpenseEvents.Log, EventLevel.Informational, AExpenseEvents.Keywords.UserInterface); // Log all events to DB this.dbListener = SqlDatabaseLog.CreateListener("aExpense", WebConfigurationManager.ConnectionStrings["Tracing"].ConnectionString, bufferingInterval: TimeSpan.FromSeconds(3), bufferingCount:10); dbListener.EnableEvents(AExpenseEvents.Log, EventLevel.LogAlways, Keywords.All); } }
private static ObservableEventListener CastToObservableEventListener(EventListener eventListener) { Guard.ArgumentNotNull(eventListener, "eventListener"); var observableEventListener = eventListener as ObservableEventListener; if (observableEventListener == null) { throw new ArgumentException(Resources.ArgumentMustBeObservableEventListener, "eventListener"); } return observableEventListener; }
private void EnableNonTransientErrorsHandling() { var observable = new ObservableEventListener(); this.slabNonTransientErrors = observable; if (this.consoleMode) { observable.LogToConsole(); } else { observable.Subscribe(new ServiceEventLogSink(this.EventLog)); } EventLevel level; if (!Enum.TryParse<EventLevel>(ConfigurationManager.AppSettings[NonTransientErrorsEventLevelKey], out level)) { level = EventLevel.LogAlways; } this.slabNonTransientErrors.EnableEvents(SemanticLoggingEventSource.Log, level, Keywords.All); // Capture any unhandled error in worker threads AppDomain.CurrentDomain.UnhandledException += this.OnAppDomainUnhandledException; // Handle unobserved task exceptions TaskScheduler.UnobservedTaskException += this.OnUnobservedTaskException; }
internal void WriteStringToListener(EventListener listener, string msg, SessionMask m) { Contract.Assert(listener == null || (uint)m == (uint)SessionMask.FromId(0)); if (m_eventSourceEnabled) { if (listener == null) { WriteEventString(0, (long) m.ToEventKeywords(), msg); } else { List<object> arg = new List<object>(); arg.Add(msg); EventWrittenEventArgs eventCallbackArgs = new EventWrittenEventArgs(this); eventCallbackArgs.EventId = 0; eventCallbackArgs.Payload = new ReadOnlyCollection<object>(arg); listener.OnEventWritten(eventCallbackArgs); } } }
private void ReportActivitySamplingInfo(EventListener listener, SessionMask sessions) { Contract.Assert(listener == null || (uint)sessions == (uint)SessionMask.FromId(0)); for (int perEventSourceSessionId = 0; perEventSourceSessionId < SessionMask.MAX; ++perEventSourceSessionId) { if (!sessions[perEventSourceSessionId]) continue; ActivityFilter af; if (listener == null) { EtwSession etwSession = m_etwSessionIdMap[perEventSourceSessionId]; Contract.Assert(etwSession != null); af = etwSession.m_activityFilter; } else { af = listener.m_activityFilter; } if (af == null) continue; SessionMask m = new SessionMask(); m[perEventSourceSessionId] = true; foreach (var t in af.GetFilterAsTuple(m_guid)) { WriteStringToListener(listener, string.Format(CultureInfo.InvariantCulture, "Session {0}: {1} = {2}", perEventSourceSessionId, t.Item1, t.Item2), m); } bool participateInSampling = (listener == null) ? m_activityFilteringForETWEnabled[perEventSourceSessionId] : GetDispatcher(listener).m_activityFilteringEnabled; WriteStringToListener(listener, string.Format(CultureInfo.InvariantCulture, "Session {0}: Activity Sampling support: {1}", perEventSourceSessionId, participateInSampling ? "enabled" : "disabled"), m); } }
// This is the internal entry point that code:EventListeners call when wanting to send a command to a // eventSource. The logic is as follows // // * if Command == Update // * perEventSourceSessionId specifies the per-provider ETW session ID that the command applies // to (if listener != null) // perEventSourceSessionId = 0 - reserved for EventListeners // perEventSourceSessionId = 1..SessionMask.MAX - reserved for activity tracing aware ETW sessions // perEventSourceSessionId-1 represents the bit in the reserved field (bits 44..47) in // Keywords that identifies the session // perEventSourceSessionId = SessionMask.MAX+1 - reserved for legacy ETW sessions; these are // discriminated by etwSessionId // * etwSessionId specifies a machine-wide ETW session ID; this allows correlation of // activity tracing across different providers (which might have different sessionIds // for the same ETW session) // * enable, level, matchAnyKeywords are used to set a default for all events for the // eventSource. In particular, if 'enabled' is false, 'level' and // 'matchAnyKeywords' are not used. // * OnEventCommand is invoked, which may cause calls to // code:EventSource.EnableEventForDispatcher which may cause changes in the filtering // depending on the logic in that routine. // * else (command != Update) // * Simply call OnEventCommand. The expectation is that filtering is NOT changed. // * The 'enabled' 'level', matchAnyKeyword' arguments are ignored (must be true, 0, 0). // // dispatcher == null has special meaning. It is the 'ETW' dispatcher. internal void SendCommand(EventListener listener, int perEventSourceSessionId, int etwSessionId, EventCommand command, bool enable, EventLevel level, EventKeywords matchAnyKeyword, IDictionary<string, string> commandArguments) { m_lastCommandException = null; bool shouldReport = (perEventSourceSessionId > 0) && (perEventSourceSessionId <= SessionMask.MAX); try { lock (EventListener.EventListenersLock) { EnsureInitialized(); // Find the per-EventSource dispatcher cooresponding to registered dispatcher EventDispatcher eventSourceDispatcher = GetDispatcher(listener); if (eventSourceDispatcher == null && listener != null) // dispatcher == null means ETW dispatcher throw new ArgumentException(Environment.GetResourceString("EventSource_ListenerNotFound")); if (commandArguments == null) commandArguments = new Dictionary<string, string>(); if (command == EventCommand.Update) { // Set it up using the 'standard' filtering bitfields (use the "global" enable, not session specific one) for (int i = 0; i < m_eventData.Length; i++) EnableEventForDispatcher(eventSourceDispatcher, i, IsEnabledByDefault(i, enable, level, matchAnyKeyword)); if (enable) { if (!m_eventSourceEnabled) { // EventSource turned on for the first time, simply copy the bits. m_level = level; m_matchAnyKeyword = matchAnyKeyword; } else { // Already enabled, make it the most verbose of the existing and new filter if (level > m_level) m_level = level; if (matchAnyKeyword == 0) m_matchAnyKeyword = 0; else if (m_matchAnyKeyword != 0) m_matchAnyKeyword |= matchAnyKeyword; } } // interpret perEventSourceSessionId's sign, and adjust perEventSourceSessionId to // represent 0-based positive values bool bSessionEnable = (perEventSourceSessionId >= 0); if (perEventSourceSessionId == 0 && enable == false) bSessionEnable = false; if (listener == null) { if (!bSessionEnable) perEventSourceSessionId = -perEventSourceSessionId; // for "global" enable/disable (passed in with listener == null and // perEventSourceSessionId == 0) perEventSourceSessionId becomes -1 --perEventSourceSessionId; } command = bSessionEnable ? EventCommand.Enable : EventCommand.Disable; // perEventSourceSessionId = -1 when ETW sent a notification, but the set of active sessions // hasn't changed. // sesisonId = SessionMask.MAX when one of the legacy ETW sessions changed // 0 <= perEventSourceSessionId < SessionMask.MAX for activity-tracing aware sessions Contract.Assert(perEventSourceSessionId >= -1 && perEventSourceSessionId <= SessionMask.MAX); // Send the manifest if we are enabling an ETW session if (bSessionEnable && eventSourceDispatcher == null) { // eventSourceDispatcher == null means this is the ETW manifest // SendCommand can be called from the EventSource constructor as a side effect of // ETW registration. Unfortunately when this callback is active the provider is // not actually enabled (WriteEvents will fail). Thus if we detect this condition // (that we are still being constructed), we simply skip sending the manifest. // When the constructor completes we will try again and send the manifest at that time. // // Note that we unconditionally send the manifest whenever we are enabled, even if // we were already enabled. This is because there may be multiple sessions active // and we can't know that all the sessions have seen the manifest. if (m_completelyInited) SendManifest(m_rawManifest); else m_deferedSendManifest = true; } #if FEATURE_ACTIVITYSAMPLING if (bSessionEnable && perEventSourceSessionId != -1) { bool participateInSampling = false; string activityFilters; int sessionIdBit; ParseCommandArgs(commandArguments, out participateInSampling, out activityFilters, out sessionIdBit); if (listener == null && commandArguments.Count > 0 && perEventSourceSessionId != sessionIdBit) { throw new ArgumentException(Environment.GetResourceString("EventSource_SessionIdError", perEventSourceSessionId+SessionMask.SHIFT_SESSION_TO_KEYWORD, sessionIdBit+SessionMask.SHIFT_SESSION_TO_KEYWORD)); } if (listener == null) { UpdateEtwSession(perEventSourceSessionId, etwSessionId, true, activityFilters, participateInSampling); } else { ActivityFilter.UpdateFilter(ref listener.m_activityFilter, this, 0, activityFilters); eventSourceDispatcher.m_activityFilteringEnabled = participateInSampling; } } else if (!bSessionEnable && listener == null) { // if we disable an ETW session, indicate that in a synthesized command argument if (perEventSourceSessionId >= 0 && perEventSourceSessionId < SessionMask.MAX) { commandArguments["EtwSessionKeyword"] = (perEventSourceSessionId+SessionMask.SHIFT_SESSION_TO_KEYWORD).ToString(CultureInfo.InvariantCulture); } } #endif // FEATURE_ACTIVITYSAMPLING this.OnEventCommand(new EventCommandEventArgs(command, commandArguments, this, eventSourceDispatcher)); #if FEATURE_ACTIVITYSAMPLING if (listener == null && !bSessionEnable && perEventSourceSessionId != -1) { // if we disable an ETW session, complete disabling it UpdateEtwSession(perEventSourceSessionId, etwSessionId, false, null, false); } #endif // FEATURE_ACTIVITYSAMPLING if (enable) { m_eventSourceEnabled = true; } else { // If we are disabling, maybe we can turn on 'quick checks' to filter // quickly. These are all just optimizations (since later checks will still filter) #if FEATURE_ACTIVITYSAMPLING // Turn off (and forget) any information about Activity Tracing. if (listener == null) { // reset all filtering information for activity-tracing-aware sessions for (int i = 0; i < SessionMask.MAX; ++i) { EtwSession etwSession = m_etwSessionIdMap[i]; if (etwSession != null) ActivityFilter.DisableFilter(ref etwSession.m_activityFilter, this); } m_activityFilteringForETWEnabled = new SessionMask(0); m_curLiveSessions = new SessionMask(0); // reset activity-tracing-aware sessions if (m_etwSessionIdMap != null) for (int i = 0; i < SessionMask.MAX; ++i) m_etwSessionIdMap[i] = null; // reset legacy sessions if (m_legacySessions != null) m_legacySessions.Clear(); } else { ActivityFilter.DisableFilter(ref listener.m_activityFilter, this); eventSourceDispatcher.m_activityFilteringEnabled = false; } #endif // FEATURE_ACTIVITYSAMPLING // There is a good chance EnabledForAnyListener are not as accurate as // they could be, go ahead and get a better estimate. for (int i = 0; i < m_eventData.Length; i++) { bool isEnabledForAnyListener = false; for (EventDispatcher dispatcher = m_Dispatchers; dispatcher != null; dispatcher = dispatcher.m_Next) { if (dispatcher.m_EventEnabled[i]) { isEnabledForAnyListener = true; break; } } m_eventData[i].EnabledForAnyListener = isEnabledForAnyListener; } // If no events are enabled, disable the global enabled bit. if (!AnyEventEnabled()) { m_level = 0; m_matchAnyKeyword = 0; m_eventSourceEnabled = false; } } #if FEATURE_ACTIVITYSAMPLING UpdateKwdTriggers(enable); #endif // FEATURE_ACTIVITYSAMPLING } else { if (command == EventCommand.SendManifest) SendManifest(m_rawManifest); // These are not used for non-update commands and thus should always be 'default' values Contract.Assert(enable == true); Contract.Assert(m_level == EventLevel.LogAlways); Contract.Assert(m_matchAnyKeyword == EventKeywords.None); this.OnEventCommand(new EventCommandEventArgs(command, commandArguments, null, null)); } #if FEATURE_ACTIVITYSAMPLING if (m_completelyInited && (listener != null || shouldReport)) { SessionMask m = SessionMask.FromId(perEventSourceSessionId); ReportActivitySamplingInfo(listener, m); } OutputDebugString(string.Format(CultureInfo.InvariantCulture, "{0}.SendCommand(session {1}, cmd {2}, enable {3}, level {4}): live sessions {5:x}, sampling {6:x}", m_name, perEventSourceSessionId, command, enable, level, (ulong) m_curLiveSessions, (ulong) m_activityFilteringForETWEnabled)); #endif // FEATURE_ACTIVITYSAMPLING } } catch (Exception e) { // Remember any exception and rethrow. m_lastCommandException = e; throw; } }
public void AddShutdownEventListener(EventListener e) { throw new NotImplementedException(); }
// Finds the Dispatcher (which holds the filtering state), for a given dispatcher for the current // eventSource). private EventDispatcher GetDispatcher(EventListener listener) { EventDispatcher dispatcher = m_Dispatchers; while (dispatcher != null) { if (dispatcher.m_Listener == listener) return dispatcher; dispatcher = dispatcher.m_Next; } return dispatcher; }
// This is the internal entry point that code:EventListeners call when wanting to send a command to a // eventSource. The logic is as follows // // * if Command == Update // * enabled, level, matchAnyKeywords are used to set a default for all events for the // curEventSource. In particular, if 'enabled' is false, 'level' and // 'matchAnyKeywords' are not used. // * OnEventCommand is invoked, which may cause calls to // code:EventSource.EnableEventForDispatcher which may cause changes in the filtering // depending on the logic in that routine. // * else (command != Update) // * Simply call OnEventCommand. The expectation is that filtering is NOT changed. // * The 'enabled' 'level', matchAnyKeyword' arguments are ignored (must be true, 0, 0). // // dispatcher == null has special meaning. It is the 'ETW' dispatcher. internal void SendCommand(EventListener listener, EventCommand command, bool enable, EventLevel level, EventKeywords matchAnyKeyword, IDictionary<string, string> commandArguments) { m_lastCommandException = null; try { InsureInitialized(); // Find the per-EventSource dispatcher cooresponding to registered dispatcher EventDispatcher eventSourceDispatcher = GetDispatcher(listener); if (eventSourceDispatcher == null && listener != null) // dispatcher == null means ETW dispatcher throw new ArgumentException(SR.EventSource_ListenerNotFound); if (commandArguments == null) commandArguments = new Dictionary<string, string>(); if (command == EventCommand.Update) { // Set it up using the 'standard' filtering bitfields for (int i = 0; i < m_eventData.Length; i++) EnableEventForDispatcher(eventSourceDispatcher, i, IsEnabledByDefault(i, enable, level, matchAnyKeyword)); command = EventCommand.Disable; if (enable) { command = EventCommand.Enable; if (!m_eventSourceEnabled) { // EventSource turned on for the first time, simply copy the bits. m_level = level; m_matchAnyKeyword = matchAnyKeyword; } else { // Already enabled, make it the most verbose of the existing and new filter if (level > m_level) m_level = level; if (matchAnyKeyword == 0) m_matchAnyKeyword = 0; else if (m_matchAnyKeyword != 0) m_matchAnyKeyword |= matchAnyKeyword; } // Send the manifest if we are writing to ETW if (eventSourceDispatcher == null) { // eventSourceDispatcher == null means this is the ETW manifest // If we are not completely initalized we can't send the manifest because WriteEvent // will fail (handle was not returned from OS API). We will try again after the // constuctor completes. if (!m_ETWManifestSent && m_completelyInited) { m_ETWManifestSent = true; SendManifest(m_rawManifest); } } } this.OnEventCommand(new EventCommandEventArgs(command, commandArguments, this, eventSourceDispatcher)); if (enable) { m_eventSourceEnabled = true; } else { // If we are disabling, maybe we can turn so 'quick checks' to filter // quickly. These are all just optimizations (since later checks will still filter) // reset the 'manifestSent' bit for the listener. if (eventSourceDispatcher == null) m_ETWManifestSent = false; // Null dispatcher means ETW dispatcher. // There is a good chance EnabledForAnyListener are not as accurate as // they could be, go ahead and get a better estimate. for (int i = 0; i < m_eventData.Length; i++) { m_eventData[i].EnabledForAnyListener = false; for (EventDispatcher dispatcher = m_Dispatchers; dispatcher != null; dispatcher = dispatcher.m_Next) { if (dispatcher.m_EventEnabled[i]) { m_eventData[i].EnabledForAnyListener = true; break; } } } // If no events are enabled, disable the global enabled bit. if (!AnyEventEnabled()) { m_level = 0; m_matchAnyKeyword = 0; m_eventSourceEnabled = false; } } } else { if (command == EventCommand.SendManifest) SendManifest(m_rawManifest); // These are not used for non-update commands and thus should always be 'default' values Contract.Assert(enable == true); Contract.Assert(m_level == EventLevel.LogAlways); Contract.Assert(m_matchAnyKeyword == EventKeywords.None); this.OnEventCommand(new EventCommandEventArgs(command, commandArguments, null, null)); } } catch (Exception e) { // Remember any exception and rethrow. m_lastCommandException = e; throw; } }
private void DisableNonTransientErrorsHandling() { if (this.slabNonTransientErrors != null) { this.slabNonTransientErrors.DisableEvents(SemanticLoggingEventSource.Log); this.slabNonTransientErrors.Dispose(); this.slabNonTransientErrors = null; } AppDomain.CurrentDomain.UnhandledException -= this.OnAppDomainUnhandledException; TaskScheduler.UnobservedTaskException -= this.OnUnobservedTaskException; }