private void SetupTraceEvents(Trace trace, List <DaxStudioTraceEventClass> events) { Log.Verbose(Constants.LogMessageTemplate, nameof(QueryTraceEngine), nameof(SetupTraceEvents), "entering"); trace.Events.Clear(); // Add CommandBegine & DiscoverBegin so we can catch the heartbeat events trace.Events.Add(TraceEventFactory.Create(TraceEventClass.DiscoverBegin)); trace.Events.Add(TraceEventFactory.Create(TraceEventClass.CommandBegin)); // Add QueryEnd so we know when to stop the trace trace.Events.Add(TraceEventFactory.Create(TraceEventClass.QueryEnd)); // catch the events in the ITraceWatcher foreach (DaxStudioTraceEventClass eventClass in events) { TraceEventClass amoEventClass = (TraceEventClass)eventClass; if (trace.Events.Find(amoEventClass) != null) { continue; } var trcEvent = TraceEventFactory.Create(amoEventClass); trace.Events.Add(trcEvent); } trace.Update(UpdateOptions.Default, UpdateMode.CreateOrReplace); Log.Verbose(Constants.LogMessageTemplate, nameof(QueryTraceEngine), nameof(SetupTraceEvents), "exiting"); }
private void Start() { try { Log.Verbose("{class} {method} {message}", nameof(QueryTraceEngine), nameof(Start), "entering"); if (_trace != null) { if (_trace.IsStarted || Status == QueryTraceStatus.Starting || Status == QueryTraceStatus.Started) { return; // exit here if trace is already started } } if (Status != QueryTraceStatus.Started) { Status = QueryTraceStatus.Starting; } Log.Verbose("{class} {method} {event}", "QueryTraceEngine", "Start", "Connecting to: " + _connectionString); if (_connectionManager != null) { _connectionManager.Ping(); _sessionId = _connectionManager.SessionId; _databaseName = _connectionManager.DatabaseName; _connectionString = AdjustConnectionString(_connectionManager.ConnectionString); } _trace = GetTrace(); SetupTraceEvents(_trace, Events); _trace.OnEvent += OnTraceEventInternal; _trace.Start(); // create timer to "ping" the server with DISCOVER_SESSION requests // until the trace events start to fire. if (_startingTimer == null) { _startingTimer = new Timer(); } _startingTimer.Interval = 500; _startingTimer.Elapsed += OnTimerElapsed; _startingTimer.Enabled = true; _startingTimer.Start(); _utcPingStart = DateTime.UtcNow; // Wait for Trace to become active Log.Verbose("{class} {method} {message}", nameof(QueryTraceEngine), nameof(Start), "exiting"); } catch (Exception ex) { RaiseError(ex); //Log.Error("{class} {method} {message}","QueryTraceEngine" , "Start", ex.Message); } }
public void DisposeTrace() { if (_trace == null) { return; // exit here if trace has already been disposed } _trace.OnEvent -= OnTraceEventInternal; try { _trace.Drop(); } catch (Exception ex) { // just log any error, don't rethrow as we are trying to stop the trace anyway Log.Error(ex, "{Class} {Method} Exception while dropping query trace {message}", "QueryTraceEngine", "DisposeTrace", ex.Message); } // TODO - do we need to call both DROP and DISPOSE ?? Sometimes causes hanging // need to check if AMO is also trying to drop the trace //_trace.Dispose(); _trace = null; }
private Trace GetTrace() { if (_trace == null) { _server = new Server(); _server.Connect(_connectionString); _trace = _server.Traces.Add($"DaxStudio_Session_{_sessionId}"); // Enable automatic filter only if DirectQuery is not enabled - otherwise, it will filter events in the trace event (slower, use DirectQuery with care!) if ((!_globalOptions.TraceDirectQuery || Version.Parse(_server.Version).Major >= 14) && _filterForCurrentSession) { Log.Verbose("Activate filter {sessionId} - {applicationName}", _sessionId, _applicationName); _trace.Filter = GetSessionIdFilter(_sessionId, _applicationName); } // set default stop time in case trace gets disconnected _trace.StopTime = DateTime.UtcNow.AddHours(24); _trace.Audit = true; } return(_trace); }