public void AddOutputSink(IOutputSink sink) => OutputSinks.Add(sink);
public static void EnableTracingForLegacyCode( LegacyFeaturesUsed flags, OutputSinks output) { if (flags.HasFlag(LegacyFeaturesUsed.CorrelationManager)) { CorrelationManagerHook.PipeCorrelationManagerToOpenTracing(); } var rawConsoleOut = Console.Out; if (flags.HasFlag(LegacyFeaturesUsed.ConsoleOut)) { // Intercept Console.Out messages (this is a source) Console.SetOut(new OpenTracingTextWriter( // We do NOT set to Console.Out, so that we ensure all log messages go through us textWriterImplementation: TextWriter.Null)); } // Start output if (output.HasFlag(OutputSinks.TraceSource)) { // Create an ITracer/TraceSource pair for getting output FROM OpenTracing (this is a sink) var pair = ToOpenTracing.OpenTracingTraceSource.CreateTracerTraceSourcePair(); var traceSourceSink = pair.TraceSourceSink; var tracerSource = pair.OpenTracingTracerSource; // Tell OT to write-to/actually-use that sink GlobalTracer.Register(tracerSource); OpenTracingTraceSource = traceSourceSink; } // Because it reads Trace.Listeners, must be before any writes to that. if (output.HasFlag(OutputSinks.CopyExistingTraceListeners)) { if (!output.HasFlag(OutputSinks.TraceSource)) { throw new InvalidOperationException( "Presently, you must pipe out to TraceSource to be able to get to Trace.Write, since that's all we've implemented."); } // No longer need to validate, since we write AFTER reading //if (flags.HasFlag(LegacyFeaturesUsed.TraceWrite)) //{ // throw new InvalidOperationException( // "Catching Trace.Write and piping output to Trace.Write would be cyclic"); //} OpenTracingTraceSource.Listeners.AddRange( Trace.Listeners); } if (flags.HasFlag(LegacyFeaturesUsed.TraceWrite)) { OpenTracingTraceListener = new OpenTracingTraceListener(); // Send Trace messages to OpenTracing (this is a source) Trace.Listeners.Add(OpenTracingTraceListener); } if (output.HasFlag(OutputSinks.ColoredConsole)) { if (!output.HasFlag(OutputSinks.TraceSource)) { throw new InvalidOperationException( "Presently, you must pipe out to TraceSource to be able to get to Console, since that's all we've implemented."); } var listener = new JsonDataConsoleTraceListener(rawConsoleOut); OpenTracingTraceSource.Listeners.Add(listener); } if (flags.HasFlag(LegacyFeaturesUsed.NoTracingSetup)) { if (!flags.HasFlag(LegacyFeaturesUsed.ConsoleOut) && !flags.HasFlag(LegacyFeaturesUsed.TraceWrite)) { throw new ArgumentException( "No need to set the NoTracingSetup flag if not using any features that will output to the active span."); } // Explicitly NOT disposing of the IScope, we want it to remain forever active var scope = GlobalTracer.Instance .BuildSpan("GlobalSpan") .StartActive(); } }