/// <summary> /// Close and delete the trace (needs to be closed before deleting) /// NOP if trace wasn't registered /// </summary> /// <param name="cancel"></param> /// <returns></returns> public async Task UnregisterTraceAsync(CancellationToken cancel) { if (_traceId == null) { Log.Debug("Trace wasn't registered. Nothing to stop."); return; } try { Log.Debug("Stopping trace with sp_trace_setstatus, status = 0"); await DbTasks.ControlTraceAsync(_connection, _traceId.Value, 0 /* stop */, cancel); } catch (Exception ex) { Log.Warn($"Cannot stop trace. TraceId: {_traceId}", ex); throw; } try { Log.Debug("Deleting trace with sp_trace_setstatus, status = 2"); await DbTasks.ControlTraceAsync(_connection, _traceId.Value, 2 /* close and delete */, cancel); } catch { Log.Warn($"Cannot delete trace. TraceId: {_traceId}"); throw; } }
/// <summary> /// Registers trace with the database, opens command and DB data readers. /// Setups events/columns to be captured /// </summary> public async Task RegisterTraceAsync(Dictionary <EventClassType, List <EventColumnType> > registeredEvents, CancellationToken cancel) { Log.Debug("Creating new trace"); _traceId = await DbTasks.CreateTraceAsync(_connection, cancel); Log.Debug($"Trace ID: {_traceId}"); // prepare new buffer for receiving data _buffer = new ProfilerEvent(EventClassType.Unknown); // register each event-class foreach (var evClass in registeredEvents.Keys) { cancel.ThrowIfCancellationRequested(); // convert all columns for this event-class into a flat array for registration var columns = registeredEvents[evClass].Select(x => (int)x).ToArray(); try { Log.Debug($"Registering event ID: {evClass} with {columns.Count()} columns"); await DbTasks.SetEventAsync(_connection, cancel, _traceId.Value, (int)evClass, columns); } catch { Log.Warn($"Event registration failed. ID: {evClass}"); throw; } } try { await DbTasks.ControlTraceAsync(_connection, _traceId.Value, 1 /* start */, cancel); } catch { Log.Warn("Cannot start registered trace"); throw; } }