Remove span exporter from ConsoleExporter (#783)

* Remove SpanExporter from ConsoleExporter. Only Activity exporter needs to remain.

* rename console activity exporter to just console exporter

* change example dotnet run

* minor
This commit is contained in:
Cijo Thomas 2020-07-08 11:23:59 -07:00 committed by GitHub
parent a36236f74e
commit c5e5604115
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 94 additions and 334 deletions

View File

@ -27,17 +27,18 @@ namespace Samples
/// Main method - invoke this using command line.
/// For example:
///
/// dotnet Exporters.dll zipkin -u http://localhost:9411/api/v2/spans
/// dotnet Exporters.dll jaeger -h localhost -p 6831
/// dotnet Exporters.dll prometheus -i 15 -p 9184 -d 2
/// dotnet run -p Exporters.csproj console
/// dotnet run -p Exporters.csproj zipkin -u http://localhost:9411/api/v2/spans
/// dotnet run -p Exporters.csproj jaeger -h localhost -p 6831
/// dotnet run -p Exporters.csproj prometheus -i 15 -p 9184 -d 2
///
/// The above must be run from the project bin folder
/// (eg: C:\repos\opentelemetry-dotnet\src\samples\Exporters\Console\bin\Debug\netcoreapp3.1).
/// The above must be run from the project root folder
/// (eg: C:\repos\opentelemetry-dotnet\src\samples\Exporters\Console\).
/// </summary>
/// <param name="args">Arguments from command line.</param>
public static void Main(string[] args)
{
Parser.Default.ParseArguments<JaegerOptions, ZipkinOptions, PrometheusOptions, HttpClientOptions, ZPagesOptions, ConsoleOptions, ConsoleActivityOptions, OtlpOptions>(args)
Parser.Default.ParseArguments<JaegerOptions, ZipkinOptions, PrometheusOptions, HttpClientOptions, ZPagesOptions, ConsoleOptions, OtlpOptions>(args)
.MapResult(
(JaegerOptions options) => TestJaeger.Run(options.Host, options.Port, options.UseActivitySource),
(ZipkinOptions options) => TestZipkin.Run(options.Uri, options.UseActivitySource),
@ -45,8 +46,7 @@ namespace Samples
(HttpClientOptions options) => TestHttpClient.Run(),
(RedisOptions options) => TestRedis.Run(options.Uri),
(ZPagesOptions options) => TestZPages.Run(),
(ConsoleOptions options) => TestConsole.Run(options),
(ConsoleActivityOptions options) => TestConsoleActivity.Run(options),
(ConsoleOptions options) => TestConsoleExporter.Run(options),
(OtlpOptions options) => TestOtlp.Run(options.Endpoint, options.UseActivitySource),
errs => 1);
@ -111,13 +111,6 @@ 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: 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; }

View File

@ -1,57 +0,0 @@
// <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.Exporter.Console;
using OpenTelemetry.Trace;
using OpenTelemetry.Trace.Configuration;
namespace Samples
{
internal class TestConsole
{
internal static object Run(ConsoleOptions options)
{
// map test project settings to ConsoleExporterSetting
var exporterOptions = new ConsoleExporterOptions
{
Pretty = options.Pretty,
};
// create exporter
var exporter = new ConsoleExporter(exporterOptions);
// Create tracer
using var tracerFactory = TracerFactory.Create(builder =>
{
builder.AddProcessorPipeline(p => p.SetExporter(exporter));
});
var tracer = tracerFactory.GetTracer("console-test");
using (tracer.StartActiveSpan("parent", out var parent))
{
tracer.CurrentSpan.SetAttribute("key", 123);
tracer.CurrentSpan.AddEvent("test-event");
using (tracer.StartActiveSpan("child", out var child))
{
child.SetAttribute("key", "value");
}
}
return null;
}
}
}

View File

@ -1,4 +1,4 @@
// <copyright file="TestConsoleActivity.cs" company="OpenTelemetry Authors">
// <copyright file="TestConsoleExporter.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -25,18 +25,18 @@ using OpenTelemetry.Trace.Export;
namespace Samples
{
internal class TestConsoleActivity
internal class TestConsoleExporter
{
internal static object Run(ConsoleActivityOptions options)
internal static object Run(ConsoleOptions options)
{
// Enable OpenTelemetry for the source "MyCompany.MyProduct.MyWebServer"
// and use a single pipeline with a custom MyProcessor, and Console exporter.
using var openTelemetry = OpenTelemetrySdk.EnableOpenTelemetry(
(builder) => builder.AddActivitySource("MyCompany.MyProduct.MyWebServer")
.SetResource(Resources.CreateServiceResource("MyServiceName"))
.UseConsoleActivityExporter(opt => opt.DisplayAsJson = options.DisplayAsJson,
.UseConsoleExporter(opt => opt.DisplayAsJson = options.DisplayAsJson,
(p) => p.AddProcessor((next) => new MyProcessor(next))));
// The above line is required only in Applications
// which decide to use OT.
@ -95,6 +95,8 @@ namespace Samples
}
}
Console.WriteLine("Press Enter key to exit.");
return null;
}

View File

@ -32,7 +32,7 @@ namespace Samples
(builder) => builder.AddHttpClientDependencyInstrumentation()
.SetResource(Resources.CreateServiceResource("http-service-example"))
.AddActivitySource("http-client-test")
.UseConsoleActivityExporter(opt => opt.DisplayAsJson = false));
.UseConsoleExporter(opt => opt.DisplayAsJson = false));
var source = new ActivitySource("http-client-test");
using (var parent = source.StartActivity("incoming request", ActivityKind.Server))

View File

@ -1,123 +0,0 @@
// <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.Resources;
using OpenTelemetry.Trace;
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 Kind - " + activity.Kind);
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}");
foreach (var attribute in activityEvent.Attributes)
{
System.Console.WriteLine($"\t {attribute.Key} : {attribute.Value}");
}
}
}
if (activity.Baggage.Any())
{
System.Console.WriteLine("Activity Baggage");
foreach (var baggage in activity.Baggage)
{
System.Console.WriteLine($"\t {baggage.Key} : {baggage.Value}");
}
}
var resource = activity.GetResource();
if (resource != Resource.Empty)
{
System.Console.WriteLine("Resource associated with Activity");
foreach (var resourceAttribute in resource.Attributes)
{
System.Console.WriteLine($"\t {resourceAttribute.Key} : {resourceAttribute.Value}");
}
}
System.Console.WriteLine("\n");
}
}
return Task.FromResult(ExportResult.Success);
}
public override Task ShutdownAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}
}

View File

@ -1,23 +0,0 @@
// <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; }
}
}

View File

@ -15,35 +15,100 @@
// </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.Resources;
using OpenTelemetry.Trace;
using OpenTelemetry.Trace.Export;
namespace OpenTelemetry.Exporter.Console
{
public class ConsoleExporter : SpanExporter
public class ConsoleExporter : ActivityExporter
{
private readonly JsonSerializerOptions serializerOptions;
private bool displayAsJson;
public ConsoleExporter(ConsoleExporterOptions options)
{
this.serializerOptions = new JsonSerializerOptions
this.serializerOptions = new JsonSerializerOptions()
{
WriteIndented = options.Pretty,
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<SpanData> batch, CancellationToken cancellationToken)
public override Task<ExportResult> ExportAsync(IEnumerable<Activity> activityBatch, CancellationToken cancellationToken)
{
foreach (var span in batch)
foreach (var activity in activityBatch)
{
System.Console.WriteLine(JsonSerializer.Serialize(span, this.serializerOptions));
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 DisplayName - " + activity.DisplayName);
System.Console.WriteLine("Activity Kind - " + activity.Kind);
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}");
foreach (var attribute in activityEvent.Attributes)
{
System.Console.WriteLine($"\t {attribute.Key} : {attribute.Value}");
}
}
}
if (activity.Baggage.Any())
{
System.Console.WriteLine("Activity Baggage");
foreach (var baggage in activity.Baggage)
{
System.Console.WriteLine($"\t {baggage.Key} : {baggage.Value}");
}
}
var resource = activity.GetResource();
if (resource != Resource.Empty)
{
System.Console.WriteLine("Resource associated with Activity");
foreach (var resourceAttribute in resource.Attributes)
{
System.Console.WriteLine($"\t {resourceAttribute.Key} : {resourceAttribute.Value}");
}
}
System.Console.WriteLine();
}
}
return Task.FromResult(ExportResult.Success);

View File

@ -1,4 +1,4 @@
// <copyright file="ConsoleExporterOptions.cs" company="OpenTelemetry Authors">
// <copyright file="ConsoleExporterOptions.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
@ -18,6 +18,6 @@ namespace OpenTelemetry.Exporter.Console
{
public class ConsoleExporterOptions
{
public bool Pretty { get; set; }
public bool DisplayAsJson { get; set; }
}
}

View File

@ -28,7 +28,7 @@ namespace OpenTelemetry.Exporter.Console
/// <param name="configure">Exporter configuration options.</param>
/// <param name="processorConfigure">Activity processor configuration.</param>
/// <returns>The instance of <see cref="OpenTelemetryBuilder"/> to chain the calls.</returns>
public static OpenTelemetryBuilder UseConsoleActivityExporter(this OpenTelemetryBuilder builder, Action<ConsoleActivityExporterOptions> configure = null, Action<ActivityProcessorPipelineBuilder> processorConfigure = null)
public static OpenTelemetryBuilder UseConsoleExporter(this OpenTelemetryBuilder builder, Action<ConsoleExporterOptions> configure = null, Action<ActivityProcessorPipelineBuilder> processorConfigure = null)
{
if (builder == null)
{
@ -37,10 +37,10 @@ namespace OpenTelemetry.Exporter.Console
return builder.AddProcessorPipeline(pipeline =>
{
var exporterOptions = new ConsoleActivityExporterOptions();
var exporterOptions = new ConsoleExporterOptions();
configure?.Invoke(exporterOptions);
var consoleExporter = new ConsoleActivityExporter(exporterOptions);
var consoleExporter = new ConsoleExporter(exporterOptions);
processorConfigure?.Invoke(pipeline);
pipeline.SetExporter(consoleExporter);
});

View File

@ -1,21 +1,7 @@
# OpenTelemetry.Exporter.Console
This is a simple exporter that that JSON serializes collected spans and prints them to the Console and is intended to be used during learning how spans are creating and exported.
This is a simple exporter that that JSON serializes collected activities and prints them to the Console and is intended to be used during learning how activities are created and exported.
**Note** This is not intended as a production tool
## Options
| Parameter | Description | Default |
| - | - | - |
| `-p` or `--pretty` | Specify if the output should be pretty printed | `false` |
## Examples
The default output of the test will be compressed JSON.
`dotnet run -p samples/Exporters/Exporters.csproj console`
To run the test with expanded JSON, you can use the `--pretty` flag like this.
`dotnet run -p samples/Exporters/Exporters.csproj console --pretty`
TODO: Add example here?

View File

@ -1,83 +0,0 @@
// <copyright file="TracerBuilderExtensions.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;
using OpenTelemetry.Trace.Export;
namespace OpenTelemetry.Exporter.Console
{
public static class TracerBuilderExtensions
{
/// <summary>
/// Registers a Console exporter.
/// </summary>
/// <param name="builder">Trace builder to use.</param>
/// <param name="configure">Exporter configuration options.</param>
/// <returns>The instance of <see cref="TracerBuilder"/> to chain the calls.</returns>
public static TracerBuilder UseConsole(this TracerBuilder builder, Action<ConsoleExporterOptions> configure)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (configure == null)
{
throw new ArgumentNullException(nameof(configure));
}
var options = new ConsoleExporterOptions();
configure(options);
return builder.AddProcessorPipeline(b => b
.SetExporter(new ConsoleExporter(options))
.SetExportingProcessor(e => new SimpleSpanProcessor(e)));
}
/// <summary>
/// Registers Console exporter.
/// </summary>
/// <param name="builder">Trace builder to use.</param>
/// <param name="configure">Exporter configuration options.</param>
/// <param name="processorConfigure">Span processor configuration.</param>
/// <returns>The instance of <see cref="TracerBuilder"/> to chain the calls.</returns>
public static TracerBuilder UseConsole(this TracerBuilder builder, Action<ConsoleExporterOptions> configure, Action<SpanProcessorPipelineBuilder> processorConfigure)
{
if (builder == null)
{
throw new ArgumentNullException(nameof(builder));
}
if (configure == null)
{
throw new ArgumentNullException(nameof(configure));
}
if (processorConfigure == null)
{
throw new ArgumentNullException(nameof(processorConfigure));
}
var options = new ConsoleExporterOptions();
configure(options);
return builder.AddProcessorPipeline(b =>
{
b.SetExporter(new ConsoleExporter(options));
processorConfigure.Invoke(b);
});
}
}
}