Add example for InMemory Exporter (#1639)

* Added example for InMemory exporter

* Update examples/Console/Examples.Console.csproj

Co-authored-by: Reiley Yang <reyang@microsoft.com>

* Addressed the PR comments

* Fix comments

* Fix markdown

Co-authored-by: Reiley Yang <reyang@microsoft.com>
Co-authored-by: Cijo Thomas <cithomas@microsoft.com>
This commit is contained in:
Utkarsh Umesan Pillai 2020-12-01 15:15:34 -08:00 committed by GitHub
parent 9e5995535f
commit c0e27a83fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 102 additions and 88 deletions

View File

@ -36,5 +36,6 @@
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry\OpenTelemetry.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Zipkin\OpenTelemetry.Exporter.Zipkin.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Jaeger\OpenTelemetry.Exporter.Jaeger.csproj" />
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.InMemory\OpenTelemetry.Exporter.InMemory.csproj" />
</ItemGroup>
</Project>

View File

@ -28,6 +28,7 @@ namespace Examples.Console
/// For example:
///
/// dotnet run -p Examples.Console.csproj console
/// dotnet run -p Examples.Console.csproj inmemory
/// dotnet run -p Examples.Console.csproj zipkin -u http://localhost:9411/api/v2/spans
/// dotnet run -p Examples.Console.csproj jaeger -h localhost -p 6831
/// dotnet run -p Examples.Console.csproj prometheus -i 15 -p 9184 -d 2
@ -40,7 +41,7 @@ namespace Examples.Console
/// <param name="args">Arguments from command line.</param>
public static void Main(string[] args)
{
Parser.Default.ParseArguments<JaegerOptions, ZipkinOptions, PrometheusOptions, GrpcNetClientOptions, HttpClientOptions, RedisOptions, ZPagesOptions, ConsoleOptions, OpenTelemetryShimOptions, OpenTracingShimOptions, OtlpOptions>(args)
Parser.Default.ParseArguments<JaegerOptions, ZipkinOptions, PrometheusOptions, GrpcNetClientOptions, HttpClientOptions, RedisOptions, ZPagesOptions, ConsoleOptions, OpenTelemetryShimOptions, OpenTracingShimOptions, OtlpOptions, InMemoryOptions>(args)
.MapResult(
(JaegerOptions options) => TestJaegerExporter.Run(options.Host, options.Port),
(ZipkinOptions options) => TestZipkinExporter.Run(options.Uri),
@ -53,6 +54,7 @@ namespace Examples.Console
(OpenTelemetryShimOptions options) => TestOTelShimWithConsoleExporter.Run(options),
(OpenTracingShimOptions options) => TestOpenTracingShim.Run(options),
(OtlpOptions options) => TestOtlpExporter.Run(options.Endpoint),
(InMemoryOptions options) => TestInMemoryExporter.Run(options),
errs => 1);
System.Console.ReadLine();
@ -135,6 +137,11 @@ namespace Examples.Console
public string Endpoint { get; set; }
}
[Verb("inmemory", HelpText = "Specify the options required to test InMemory Exporter")]
internal class InMemoryOptions
{
}
#pragma warning restore SA1402 // File may only contain a single type
}

View File

@ -31,94 +31,32 @@ namespace Examples.Console
// dotnet run console
internal static object Run(ConsoleOptions options)
{
// Enable TracerProvider for the source "MyCompany.MyProduct.MyWebServer"
// and use a custom MyProcessor, along with Console exporter.
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
.AddSource("MyCompany.MyProduct.MyWebServer")
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MyServiceName"))
.AddProcessor(new MyProcessor()) // This must be added before ConsoleExporter
.AddConsoleExporter()
.Build();
return RunWithActivitySource();
}
private static object RunWithActivitySource()
{
// Enable OpenTelemetry for the sources "Samples.SampleServer" and "Samples.SampleClient"
// and use Console exporter.
using var openTelemetry = Sdk.CreateTracerProviderBuilder()
.AddSource("Samples.SampleClient", "Samples.SampleServer")
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("console-test"))
.AddConsoleExporter()
.Build();
// The above line is required only in applications
// which decide to use OpenTelemetry.
// Libraries would simply write the following lines of code to
// emit activities, which are the .NET representation of OpenTelemetry 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))
using (var sample = new InstrumentationWithActivitySource())
{
// TagNames can follow the OpenTelemetry guidelines
// from https://github.com/open-telemetry/opentelemetry-specification/tree/master/specification/trace/semantic_conventions
parent?.SetTag("http.method", "GET");
parent?.SetTag("http.host", "MyHostName");
if (parent != null)
{
parent.DisplayName = "HttpIn DisplayName";
sample.Start();
// IsAllDataRequested is the equivalent of Span.IsRecording
if (parent.IsAllDataRequested)
{
parent.SetTag("expensive data", "This data is expensive to obtain. Avoid it if activity is not being recorded");
}
}
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?.SetTag("http.url", "www.mydependencyapi.com");
try
{
// do actual work.
child?.AddEvent(new ActivityEvent("sample activity event."));
child?.SetTag("http.status_code", "200");
}
catch (Exception)
{
child?.SetTag("http.status_code", "500");
}
}
parent?.SetTag("http.status_code", "200");
}
catch (Exception)
{
parent?.SetTag("http.status_code", "500");
}
System.Console.WriteLine("Traces are being created and exported " +
"to Console in the background. " +
"Press ENTER to stop.");
System.Console.ReadLine();
}
System.Console.WriteLine("Press Enter key to exit.");
return null;
}
internal class MyProcessor : BaseProcessor<Activity>
{
public override void OnStart(Activity activity)
{
if (activity.IsAllDataRequested)
{
if (activity.Kind == ActivityKind.Server)
{
activity.SetTag("customServerTag", "Custom Tag Value for server");
}
else if (activity.Kind == ActivityKind.Client)
{
activity.SetTag("customClientTag", "Custom Tag Value for Client");
}
}
}
}
}
}

View File

@ -0,0 +1,72 @@
// <copyright file="TestInMemoryExporter.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 System.Diagnostics;
using OpenTelemetry;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
namespace Examples.Console
{
internal class TestInMemoryExporter
{
// To run this example, run the following command from
// the reporoot\examples\Console\.
// (eg: C:\repos\opentelemetry-dotnet\examples\Console\)
//
// dotnet run inmemory
internal static object Run(InMemoryOptions options)
{
// List that will be populated with the traces by InMemoryExporter
var exportedItems = new List<Activity>();
RunWithActivitySource(exportedItems);
// List exportedItems is populated with the Activity objects logged by TracerProvider
foreach (var activity in exportedItems)
{
System.Console.WriteLine($"ActivitySource: {activity.Source.Name} logged the activity {activity.DisplayName}");
}
return null;
}
private static void RunWithActivitySource(ICollection<Activity> exportedItems)
{
// Enable OpenTelemetry for the sources "Samples.SampleServer" and "Samples.SampleClient"
// and use InMemory exporter.
using var openTelemetry = Sdk.CreateTracerProviderBuilder()
.AddSource("Samples.SampleClient", "Samples.SampleServer")
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("inmemory-test"))
.AddInMemoryExporter(exportedItems)
.Build();
// The above line is required only in applications
// which decide to use OpenTelemetry.
using (var sample = new InstrumentationWithActivitySource())
{
sample.Start();
System.Console.WriteLine("Traces are being created and exported " +
"to the collection passed in the background. " +
"Press ENTER to stop.");
System.Console.ReadLine();
}
}
}
}

View File

@ -13,13 +13,9 @@ dotnet add package OpenTelemetry.Exporter.InMemory
## Configuration
```csharp
var activityList = new List<Activity>();
var activityExporter = new InMemoryExporter<Activity>(activityList);
var logRecordList = new List<LogRecord>();
var logExporter = new InMemoryExporter<LogRecord>(logRecordList);
```
See the
[`TestInMemoryExporter.cs`](../../examples/Console/TestInMemoryExporter.cs) for
an example of how to use the exporter for exporting traces to a collection.
## References