Ejemplo n.º 1
0
 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();
            }
        }