Step 1 - Use new Activity to Replace OT Span (#660)
This commit is contained in:
parent
92963a384d
commit
44b3a438d7
|
|
@ -37,7 +37,7 @@ namespace Samples
|
|||
/// <param name="args">Arguments from command line.</param>
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
Parser.Default.ParseArguments<JaegerOptions, ZipkinOptions, PrometheusOptions, HttpClientOptions, ZPagesOptions, ConsoleOptions, OtlpOptions>(args)
|
||||
Parser.Default.ParseArguments<JaegerOptions, ZipkinOptions, PrometheusOptions, HttpClientOptions, ZPagesOptions, ConsoleOptions, ConsoleActivityOptions, OtlpOptions>(args)
|
||||
.MapResult(
|
||||
(JaegerOptions options) => TestJaeger.Run(options.Host, options.Port),
|
||||
(ZipkinOptions options) => TestZipkin.Run(options.Uri),
|
||||
|
|
@ -46,6 +46,7 @@ namespace Samples
|
|||
(RedisOptions options) => TestRedis.Run(options.Uri),
|
||||
(ZPagesOptions options) => TestZPages.Run(),
|
||||
(ConsoleOptions options) => TestConsole.Run(options),
|
||||
(ConsoleActivityOptions options) => TestConsoleActivity.Run(options),
|
||||
(OtlpOptions options) => TestOtlp.Run(options.Endpoint),
|
||||
errs => 1);
|
||||
|
||||
|
|
@ -105,10 +106,17 @@ namespace Samples
|
|||
[Verb("console", HelpText = "Specify the options required to test console exporter")]
|
||||
internal class ConsoleOptions
|
||||
{
|
||||
[Option('p', "pretty", HelpText = "Specify if the output should be pretty printed (default: false)", Default = false)]
|
||||
[Option('p', "pretty", HelpText = "Specify if the output should be pretty printed (default: true)", Default = true)]
|
||||
public bool Pretty { get; set; }
|
||||
}
|
||||
|
||||
[Verb("consoleactivity", HelpText = "Specify the options required to test console activity exporter")]
|
||||
internal class ConsoleActivityOptions
|
||||
{
|
||||
[Option('p', "displayasjson", HelpText = "Specify if the output should be displayed as json or not (default: false)", Default = false)]
|
||||
public bool DisplayAsJson { get; set; }
|
||||
}
|
||||
|
||||
[Verb("otlp", HelpText = "Specify the options required to test OpenTelemetry Protocol (OTLP)")]
|
||||
internal class OtlpOptions
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,8 +1,22 @@
|
|||
// <auto-generated/>
|
||||
// <copyright file="TestConsole.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
|
||||
using OpenTelemetry.Trace.Configuration;
|
||||
using OpenTelemetry.Exporter.Console;
|
||||
using OpenTelemetry.Trace;
|
||||
using OpenTelemetry.Trace.Configuration;
|
||||
|
||||
namespace Samples
|
||||
{
|
||||
|
|
@ -13,14 +27,15 @@ namespace Samples
|
|||
// map test project settings to ConsoleExporterSetting
|
||||
var exporterOptions = new ConsoleExporterOptions
|
||||
{
|
||||
Pretty = options.Pretty
|
||||
Pretty = options.Pretty,
|
||||
};
|
||||
|
||||
// create exporter
|
||||
var exporter = new ConsoleExporter(exporterOptions);
|
||||
|
||||
// Create tracer
|
||||
using var tracerFactory = TracerFactory.Create(builder => {
|
||||
using var tracerFactory = TracerFactory.Create(builder =>
|
||||
{
|
||||
builder.AddProcessorPipeline(p => p.SetExporter(exporter));
|
||||
});
|
||||
var tracer = tracerFactory.GetTracer("console-test");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,89 @@
|
|||
// <copyright file="TestConsoleActivity.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using OpenTelemetry.Exporter.Console;
|
||||
using OpenTelemetry.Trace.Configuration;
|
||||
|
||||
namespace Samples
|
||||
{
|
||||
internal class TestConsoleActivity
|
||||
{
|
||||
internal static object Run(ConsoleActivityOptions options)
|
||||
{
|
||||
// Enable OpenTelemetry for the source "MyCompany.MyProduct.MyWebServer"
|
||||
// and use Console exporter
|
||||
OpenTelemetrySdk.EnableOpenTelemetry(
|
||||
(builder) => builder.AddActivitySource("MyCompany.MyProduct.MyWebServer")
|
||||
.UseConsoleActivityExporter(opt => opt.DisplayAsJson = options.DisplayAsJson));
|
||||
|
||||
// The above line is required only in Applications
|
||||
// which decide to use OT.
|
||||
|
||||
// Libraries would simply write the following lines of code to
|
||||
// emit activities, which are the .NET representation of OT Spans.
|
||||
var source = new ActivitySource("MyCompany.MyProduct.MyWebServer");
|
||||
|
||||
// The below commented out line shows more likely code in a real world webserver.
|
||||
// using (var parent = source.StartActivity("HttpIn", ActivityKind.Server, HttpContext.Request.Headers["traceparent"] ))
|
||||
using (var parent = source.StartActivity("HttpIn", ActivityKind.Server))
|
||||
{
|
||||
// TagNames can follow the OT guidelines
|
||||
// from https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/trace/semantic_conventions
|
||||
parent?.AddTag("http.method", "GET");
|
||||
parent?.AddTag("http.host", "MyHostName");
|
||||
if (parent != null)
|
||||
{
|
||||
parent.DisplayName = "HttpIn DisplayName";
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Actual code to achieve the purpose of the library.
|
||||
// For websebserver example, this would be calling
|
||||
// user middlware pipeline.
|
||||
|
||||
// There can be child activities.
|
||||
// In this example HttpOut is a child of HttpIn.
|
||||
using (var child = source.StartActivity("HttpOut", ActivityKind.Client))
|
||||
{
|
||||
child?.AddTag("http.url", "www.mydependencyapi.com");
|
||||
try
|
||||
{
|
||||
// do actual work.
|
||||
|
||||
child?.AddEvent(new ActivityEvent("sample activity event."));
|
||||
child?.AddTag("http.status_code", "200");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
child?.AddTag("http.status_code", "500");
|
||||
}
|
||||
}
|
||||
|
||||
parent?.AddTag("http.status_code", "200");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
parent?.AddTag("http.status_code", "500");
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
// <copyright file="ConsoleActivityExporter.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using OpenTelemetry.Trace.Export;
|
||||
|
||||
namespace OpenTelemetry.Exporter.Console
|
||||
{
|
||||
public class ConsoleActivityExporter : ActivityExporter
|
||||
{
|
||||
private readonly JsonSerializerOptions serializerOptions;
|
||||
private bool displayAsJson;
|
||||
|
||||
public ConsoleActivityExporter(ConsoleActivityExporterOptions options)
|
||||
{
|
||||
this.serializerOptions = new JsonSerializerOptions()
|
||||
{
|
||||
WriteIndented = true,
|
||||
};
|
||||
|
||||
this.displayAsJson = options.DisplayAsJson;
|
||||
|
||||
this.serializerOptions.Converters.Add(new JsonStringEnumConverter());
|
||||
this.serializerOptions.Converters.Add(new ActivitySpanIdConverter());
|
||||
this.serializerOptions.Converters.Add(new ActivityTraceIdConverter());
|
||||
}
|
||||
|
||||
public override Task<ExportResult> ExportAsync(IEnumerable<Activity> activityBatch, CancellationToken cancellationToken)
|
||||
{
|
||||
foreach (var activity in activityBatch)
|
||||
{
|
||||
if (this.displayAsJson)
|
||||
{
|
||||
System.Console.WriteLine(JsonSerializer.Serialize(activity, this.serializerOptions));
|
||||
}
|
||||
else
|
||||
{
|
||||
System.Console.WriteLine("Activity ID - " + activity.Id);
|
||||
if (!string.IsNullOrEmpty(activity.ParentId))
|
||||
{
|
||||
System.Console.WriteLine("Activity ParentId - " + activity.ParentId);
|
||||
}
|
||||
|
||||
System.Console.WriteLine("Activity OperationName - " + activity.OperationName);
|
||||
System.Console.WriteLine("Activity DisplayName - " + activity.DisplayName);
|
||||
System.Console.WriteLine("Activity StartTime - " + activity.StartTimeUtc);
|
||||
System.Console.WriteLine("Activity Duration - " + activity.Duration);
|
||||
if (activity.Tags.Count() > 0)
|
||||
{
|
||||
System.Console.WriteLine("Activity Tags");
|
||||
foreach (var tag in activity.Tags)
|
||||
{
|
||||
System.Console.WriteLine($"\t {tag.Key} : {tag.Value}");
|
||||
}
|
||||
}
|
||||
|
||||
if (activity.Events.Any())
|
||||
{
|
||||
System.Console.WriteLine("Activity Events");
|
||||
foreach (var activityEvent in activity.Events)
|
||||
{
|
||||
System.Console.WriteLine($"Event Name: {activityEvent.Name} TimeStamp: {activityEvent.Timestamp}");
|
||||
}
|
||||
}
|
||||
|
||||
System.Console.WriteLine("\n");
|
||||
}
|
||||
}
|
||||
|
||||
return Task.FromResult(ExportResult.Success);
|
||||
}
|
||||
|
||||
public override Task ShutdownAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
// <copyright file="ConsoleActivityExporterOptions.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
|
||||
namespace OpenTelemetry.Exporter.Console
|
||||
{
|
||||
public class ConsoleActivityExporterOptions
|
||||
{
|
||||
public bool DisplayAsJson { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
// <copyright file="OpenTelemetryBuilderExtensions.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
|
||||
using System;
|
||||
using OpenTelemetry.Trace.Configuration;
|
||||
|
||||
namespace OpenTelemetry.Exporter.Console
|
||||
{
|
||||
public static class OpenTelemetryBuilderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers a ConsoleActivity exporter.
|
||||
/// </summary>
|
||||
/// <param name="builder">Open Telemetry builder to use.</param>
|
||||
/// <param name="configure">Exporter configuration options.</param>
|
||||
/// <returns>The instance of <see cref="OpenTelemetryBuilder"/> to chain the calls.</returns>
|
||||
public static OpenTelemetryBuilder UseConsoleActivityExporter(this OpenTelemetryBuilder builder, Action<ConsoleActivityExporterOptions> configure)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
if (configure == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(configure));
|
||||
}
|
||||
|
||||
var exporterOptions = new ConsoleActivityExporterOptions();
|
||||
configure(exporterOptions);
|
||||
var consoleExporter = new ConsoleActivityExporter(exporterOptions);
|
||||
return builder.SetProcessorPipeline(pipeline => pipeline.SetExporter(consoleExporter));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
// <copyright file="ActivityProcessorPipelineBuilder.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenTelemetry.Trace.Export;
|
||||
|
||||
namespace OpenTelemetry.Trace.Configuration
|
||||
{
|
||||
/// <summary>
|
||||
/// Configures exporting pipeline with chains of processors and exporter.
|
||||
/// </summary>
|
||||
public class ActivityProcessorPipelineBuilder
|
||||
{
|
||||
private Func<ActivityExporter, ActivityProcessor> lastProcessorFactory;
|
||||
private List<Func<ActivityProcessor, ActivityProcessor>> processorChain;
|
||||
|
||||
internal ActivityProcessorPipelineBuilder()
|
||||
{
|
||||
}
|
||||
|
||||
internal ActivityExporter Exporter { get; private set; }
|
||||
|
||||
internal List<ActivityProcessor> Processors { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Adds chained processor to the pipeline. Processors are executed in the order they were added.
|
||||
/// </summary>
|
||||
/// <param name="processorFactory">Function that creates processor from the next one.</param>
|
||||
/// <returns>Returns <see cref="ActivityProcessorPipelineBuilder"/>.</returns>
|
||||
public ActivityProcessorPipelineBuilder AddProcessor(Func<ActivityProcessor, ActivityProcessor> processorFactory)
|
||||
{
|
||||
if (processorFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(processorFactory));
|
||||
}
|
||||
|
||||
if (this.processorChain == null)
|
||||
{
|
||||
this.processorChain = new List<Func<ActivityProcessor, ActivityProcessor>>();
|
||||
}
|
||||
|
||||
this.processorChain.Add(processorFactory);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures last processor that invokes exporter. When not set, <see cref="SimpleActivityProcessor"/> is used.
|
||||
/// </summary>
|
||||
/// <param name="processorFactory">Factory that creates exporting processor from the exporter.</param>
|
||||
/// <returns>Returns <see cref="ActivityProcessorPipelineBuilder"/>.</returns>
|
||||
public ActivityProcessorPipelineBuilder SetExportingProcessor(Func<ActivityExporter, ActivityProcessor> processorFactory)
|
||||
{
|
||||
this.lastProcessorFactory = processorFactory ?? throw new ArgumentNullException(nameof(processorFactory));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures exporter.
|
||||
/// </summary>
|
||||
/// <param name="exporter">Exporter instance.</param>
|
||||
/// <returns>Returns <see cref="ActivityProcessorPipelineBuilder"/>.</returns>
|
||||
public ActivityProcessorPipelineBuilder SetExporter(ActivityExporter exporter)
|
||||
{
|
||||
this.Exporter = exporter ?? throw new ArgumentNullException(nameof(exporter));
|
||||
return this;
|
||||
}
|
||||
|
||||
internal ActivityProcessor Build()
|
||||
{
|
||||
this.Processors = new List<ActivityProcessor>();
|
||||
|
||||
ActivityProcessor exportingProcessor = null;
|
||||
|
||||
// build or create default exporting processor
|
||||
if (this.lastProcessorFactory != null)
|
||||
{
|
||||
exportingProcessor = this.lastProcessorFactory.Invoke(this.Exporter);
|
||||
this.Processors.Add(exportingProcessor);
|
||||
}
|
||||
else if (this.Exporter != null)
|
||||
{
|
||||
exportingProcessor = new SimpleActivityProcessor(this.Exporter);
|
||||
this.Processors.Add(exportingProcessor);
|
||||
}
|
||||
|
||||
if (this.processorChain == null)
|
||||
{
|
||||
// if there is no chain, return exporting processor.
|
||||
if (exportingProcessor == null)
|
||||
{
|
||||
exportingProcessor = new NoopActivityProcessor();
|
||||
this.Processors.Add(exportingProcessor);
|
||||
}
|
||||
|
||||
return exportingProcessor;
|
||||
}
|
||||
|
||||
var next = exportingProcessor;
|
||||
|
||||
// build chain from the end to the beginning
|
||||
for (int i = this.processorChain.Count - 1; i >= 0; i--)
|
||||
{
|
||||
next = this.processorChain[i].Invoke(next);
|
||||
this.Processors.Add(next);
|
||||
}
|
||||
|
||||
// return the last processor in the chain - it will be called first
|
||||
return this.Processors[this.Processors.Count - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
// <copyright file="OpenTelemetryBuilder.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using OpenTelemetry.Resources;
|
||||
|
||||
namespace OpenTelemetry.Trace.Configuration
|
||||
{
|
||||
/// <summary>
|
||||
/// Build OpenTelemetry pipeline.
|
||||
/// Currently supports a single processing pipeline, and any number of activity source names
|
||||
/// to subscribe to.
|
||||
/// </summary>
|
||||
public class OpenTelemetryBuilder
|
||||
{
|
||||
internal OpenTelemetryBuilder()
|
||||
{
|
||||
}
|
||||
|
||||
internal ActivityProcessorPipelineBuilder ProcessingPipeline { get; private set; }
|
||||
|
||||
internal HashSet<string> ActivitySourceNames { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sets processing and exporting pipeline.
|
||||
/// </summary>
|
||||
/// <param name="configure">Function that configures pipeline.</param>
|
||||
/// <returns>Returns <see cref="OpenTelemetryBuilder"/> for chaining.</returns>
|
||||
public OpenTelemetryBuilder SetProcessorPipeline(Action<ActivityProcessorPipelineBuilder> configure)
|
||||
{
|
||||
if (configure == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(configure));
|
||||
}
|
||||
|
||||
var pipelineBuilder = new ActivityProcessorPipelineBuilder();
|
||||
configure(pipelineBuilder);
|
||||
this.ProcessingPipeline = pipelineBuilder;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds given activitysource name to the list of subscribed sources.
|
||||
/// </summary>
|
||||
/// <param name="activitySourceName">Activity source name.</param>
|
||||
/// <returns>Returns <see cref="OpenTelemetryBuilder"/> for chaining.</returns>
|
||||
public OpenTelemetryBuilder AddActivitySource(string activitySourceName)
|
||||
{
|
||||
if (this.ActivitySourceNames == null)
|
||||
{
|
||||
this.ActivitySourceNames = new HashSet<string>();
|
||||
}
|
||||
|
||||
this.ActivitySourceNames.Add(activitySourceName.ToUpperInvariant());
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
// <copyright file="OpenTelemetrySdk.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using OpenTelemetry.Trace.Export;
|
||||
|
||||
namespace OpenTelemetry.Trace.Configuration
|
||||
{
|
||||
public class OpenTelemetrySdk
|
||||
{
|
||||
static OpenTelemetrySdk()
|
||||
{
|
||||
Activity.DefaultIdFormat = ActivityIdFormat.W3C;
|
||||
Activity.ForceDefaultIdFormat = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables OpenTelemetry.
|
||||
/// </summary>
|
||||
/// <param name="configureOpenTelemetryBuilder">Function that configures OpenTelemetryBuilder.</param>
|
||||
/// <remarks>
|
||||
/// Basic implementation only. Most logic from TracerBuilder will be ported here.
|
||||
/// </remarks>
|
||||
public static void EnableOpenTelemetry(Action<OpenTelemetryBuilder> configureOpenTelemetryBuilder)
|
||||
{
|
||||
var openTelemetryBuilder = new OpenTelemetryBuilder();
|
||||
configureOpenTelemetryBuilder(openTelemetryBuilder);
|
||||
|
||||
ActivityProcessor activityProcessor;
|
||||
if (openTelemetryBuilder.ProcessingPipeline == null)
|
||||
{
|
||||
// if there are no pipelines are configured, use noop processor
|
||||
activityProcessor = new NoopActivityProcessor();
|
||||
}
|
||||
else
|
||||
{
|
||||
activityProcessor = openTelemetryBuilder.ProcessingPipeline.Build();
|
||||
}
|
||||
|
||||
// This is what subscribes to Activities.
|
||||
// Think of this as the replacement for DiagnosticListener.AllListeners.Subscribe(onNext => diagnosticListener.Subscribe(..));
|
||||
ActivityListener listener = new ActivityListener
|
||||
{
|
||||
// Callback when Activity is started.
|
||||
ActivityStarted = activityProcessor.OnStart,
|
||||
|
||||
// Callback when Activity is started.
|
||||
ActivityStopped = activityProcessor.OnEnd,
|
||||
|
||||
// Function which takes ActivitySource and returns true/false to indicate if it should be subscribed to
|
||||
// or not
|
||||
ShouldListenTo = (activitySource) => openTelemetryBuilder.ActivitySourceNames.Contains(activitySource.Name.ToUpperInvariant()),
|
||||
|
||||
// The following parameters are not used now.
|
||||
GetRequestedDataUsingParentId = (ref ActivityCreationOptions<string> options) => ActivityDataRequest.AllData,
|
||||
GetRequestedDataUsingContext = (ref ActivityCreationOptions<ActivityContext> options) => ActivityDataRequest.AllData,
|
||||
};
|
||||
|
||||
ActivitySource.AddActivityListener(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
// <copyright file="ActivityExporter.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OpenTelemetry.Trace.Export
|
||||
{
|
||||
/// <summary>
|
||||
/// ActivityExporter base class.
|
||||
/// </summary>
|
||||
public abstract class ActivityExporter
|
||||
{
|
||||
public enum ExportResult
|
||||
{
|
||||
/// <summary>
|
||||
/// Batch is successfully exported.
|
||||
/// </summary>
|
||||
Success = 0,
|
||||
|
||||
/// <summary>
|
||||
/// Batch export failed. Caller must not retry.
|
||||
/// </summary>
|
||||
FailedNotRetryable = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Batch export failed transiently. Caller should record error and may retry.
|
||||
/// </summary>
|
||||
FailedRetryable = 2,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exports batch of activities asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="batch">Batch of activities to export.</param>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>Result of export.</returns>
|
||||
public abstract Task<ExportResult> ExportAsync(IEnumerable<Activity> batch, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Shuts down exporter asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>Returns <see cref="Task"/>.</returns>
|
||||
public abstract Task ShutdownAsync(CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
// <copyright file="ActivityProcessor.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OpenTelemetry.Trace.Export
|
||||
{
|
||||
/// <summary>
|
||||
/// Activity processor base class.
|
||||
/// </summary>
|
||||
public abstract class ActivityProcessor
|
||||
{
|
||||
/// <summary>
|
||||
/// Activity start hook.
|
||||
/// </summary>
|
||||
/// <param name="activity">Instance of activity to process.</param>
|
||||
public abstract void OnStart(Activity activity);
|
||||
|
||||
/// <summary>
|
||||
/// Activity end hook.
|
||||
/// </summary>
|
||||
/// <param name="activity">Instance of activity to process.</param>
|
||||
public abstract void OnEnd(Activity activity);
|
||||
|
||||
/// <summary>
|
||||
/// Shuts down Activity processor asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">Cancellation token.</param>
|
||||
/// <returns>Returns <see cref="Task"/>.</returns>
|
||||
public abstract Task ShutdownAsync(CancellationToken cancellationToken);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
// <copyright file="NoopActivityProcessor.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OpenTelemetry.Trace.Export
|
||||
{
|
||||
internal sealed class NoopActivityProcessor : ActivityProcessor
|
||||
{
|
||||
public override void OnStart(Activity activity)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnEnd(Activity activity)
|
||||
{
|
||||
}
|
||||
|
||||
public override Task ShutdownAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
// <copyright file="SimpleActivityProcessor.cs" company="OpenTelemetry Authors">
|
||||
// Copyright The OpenTelemetry Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
// </copyright>
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using OpenTelemetry.Internal;
|
||||
|
||||
namespace OpenTelemetry.Trace.Export
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements simple activity processor that exports activities in OnEnd call without batching.
|
||||
/// </summary>
|
||||
public class SimpleActivityProcessor : ActivityProcessor, IDisposable
|
||||
{
|
||||
private readonly ActivityExporter exporter;
|
||||
private bool disposed = false;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SimpleActivityProcessor"/> class.
|
||||
/// </summary>
|
||||
/// <param name="exporter">Activity exporter instance.</param>
|
||||
public SimpleActivityProcessor(ActivityExporter exporter)
|
||||
{
|
||||
this.exporter = exporter ?? throw new ArgumentNullException(nameof(exporter));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnStart(Activity activity)
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnEnd(Activity activity)
|
||||
{
|
||||
try
|
||||
{
|
||||
// do not await, just start export
|
||||
// it can still throw in synchronous part
|
||||
|
||||
_ = this.exporter.ExportAsync(new[] { activity }, CancellationToken.None);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OpenTelemetrySdkEventSource.Log.SpanProcessorException("OnEnd", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task ShutdownAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
if (!this.disposed)
|
||||
{
|
||||
this.disposed = true;
|
||||
return this.exporter.ShutdownAsync(cancellationToken);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
this.Dispose(true);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool isDisposing)
|
||||
{
|
||||
if (isDisposing)
|
||||
{
|
||||
if (this.exporter is IDisposable disposableExporter)
|
||||
{
|
||||
try
|
||||
{
|
||||
disposableExporter.Dispose();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
OpenTelemetrySdkEventSource.Log.SpanProcessorException("Dispose", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue