Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use TagTransformer for ConsoleExporter 💻 #3311

Merged
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions src/OpenTelemetry.Exporter.Console/ConsoleActivityExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
// limitations under the License.
// </copyright>

using System;
using System.Diagnostics;
using System.Linq;
using OpenTelemetry.Resources;
Expand Down Expand Up @@ -71,13 +70,10 @@ public override ExportResult Export(in Batch<Activity> batch)
continue;
}

if (tag.Value is not Array array)
if (ConsoleTagTransformer.Instance.TryTransformTag(tag, out var result))
{
this.WriteLine($" {tag.Key}: {tag.Value}");
continue;
this.WriteLine($" {result}");
}

this.WriteLine($" {tag.Key}: [{string.Join(", ", array.Cast<object>())}]");
}
}

Expand Down Expand Up @@ -106,7 +102,10 @@ public override ExportResult Export(in Batch<Activity> batch)
this.WriteLine($" {activityEvent.Name} [{activityEvent.Timestamp}]");
foreach (var attribute in activityEvent.Tags)
{
this.WriteLine($" {attribute.Key}: {attribute.Value}");
if (ConsoleTagTransformer.Instance.TryTransformTag(attribute, out var result))
{
this.WriteLine($" {result}");
}
}
}
}
Expand All @@ -117,6 +116,13 @@ public override ExportResult Export(in Batch<Activity> batch)
foreach (var activityLink in activity.Links)
{
this.WriteLine($" {activityLink.Context.TraceId} {activityLink.Context.SpanId}");
foreach (var attribute in activityLink.Tags)
{
if (ConsoleTagTransformer.Instance.TryTransformTag(attribute, out var result))
{
this.WriteLine($" {result}");
}
}
}
}

Expand All @@ -126,7 +132,10 @@ public override ExportResult Export(in Batch<Activity> batch)
this.WriteLine("Resource associated with Activity:");
foreach (var resourceAttribute in resource.Attributes)
{
this.WriteLine($" {resourceAttribute.Key}: {resourceAttribute.Value}");
if (ConsoleTagTransformer.Instance.TryTransformTag(resourceAttribute, out var result))
{
this.WriteLine($" {result}");
}
}
}

Expand Down
24 changes: 15 additions & 9 deletions src/OpenTelemetry.Exporter.Console/ConsoleLogRecordExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,18 +57,18 @@ public override ExportResult Export(in Batch<LogRecord> batch)
else if (logRecord.StateValues != null)
{
this.WriteLine("LogRecord.StateValues (Key:Value):");
for (int i = 0; i < logRecord.StateValues.Count; i++)
foreach (var value in logRecord.StateValues)
cijothomas marked this conversation as resolved.
Show resolved Hide resolved
{
// Special casing {OriginalFormat}
// See https://github.com/open-telemetry/opentelemetry-dotnet/pull/3182
// for explanation.
if (logRecord.StateValues[i].Key.Equals("{OriginalFormat}"))
{
this.WriteLine($"{string.Empty,-4}{"OriginalFormat (a.k.a. Body)",-RightPaddingLength}{logRecord.StateValues[i].Value}");
}
else
var valueToTransform = value.Key.Equals("{OriginalValue}")
? new KeyValuePair<string, object>("OriginalFormat (a.k.a Body)", value.Value)
: value;

if (ConsoleTagTransformer.Instance.TryTransformTag(valueToTransform, out var result))
{
this.WriteLine($"{string.Empty,-4}{logRecord.StateValues[i].Key,-RightPaddingLength}{logRecord.StateValues[i].Value}");
this.WriteLine($"{string.Empty,-4}{result}");
Copy link
Member Author

@alanwest alanwest May 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lost some formatting of alignment in a number of spots. If folks feel strongly about preserving this formatting, I had it on my mind to make an override of TryTransformTag that took a format string or the likes.

Before
LogRecord.Timestamp:               2022-05-27T22:19:45.7034956Z
LogRecord.TraceId:                 5040b69ef7389abf3edfeee5c9583dd2
LogRecord.SpanId:                  fdf9c630875f7415
LogRecord.TraceFlags:              Recorded
LogRecord.CategoryName:            Examples.AspNetCore.Controllers.WeatherForecastController
LogRecord.LogLevel:                Information
LogRecord.FormattedMessage:        WeatherForecasts generated 5: Examples.AspNetCore.WeatherForecast, Examples.AspNetCore.WeatherForecast, Examples.AspNetCore.WeatherForecast, Examples.AspNetCore.WeatherForecast, Examples.AspNetCore.WeatherForecast
LogRecord.StateValues (Key:Value):
    count                              5
    forecasts                          Examples.AspNetCore.WeatherForecast[]
    OriginalFormat (a.k.a. Body)       WeatherForecasts generated {count}: {forecasts}
LogRecord.ScopeValues (Key:Value):
[Scope.0]:SpanId                             fdf9c630875f7415
[Scope.0]:TraceId                            5040b69ef7389abf3edfeee5c9583dd2
[Scope.0]:ParentId                           0000000000000000
[Scope.1]:ConnectionId                       0HMI05RCLU4BE
[Scope.2]:RequestId                          0HMI05RCLU4BE:00000003
[Scope.2]:RequestPath                        /WeatherForecast
[Scope.3]:ActionId                           e810ba66-bead-4b98-aef9-f7d726b73a4f
[Scope.3]:ActionName                         Examples.AspNetCore.Controllers.WeatherForecastController.Get (Examples.AspNetCore)
[Scope.4]:Id                                 bbbe3422157247edab47fc32f1807b5d
[Scope.4]:{OriginalFormat}                   {Id}

Resource associated with LogRecord:
service.name: AspNetCoreExampleService
service.version: 1.0.0.0
service.instance.id: awest-win10
After
LogRecord.Timestamp:               2022-05-27T22:53:02.4762430Z
LogRecord.TraceId:                 7e8a593691b28893d4ca0e248845ea15
LogRecord.SpanId:                  5afcebdead5d82f9
LogRecord.TraceFlags:              Recorded
LogRecord.CategoryName:            Examples.AspNetCore.Controllers.WeatherForecastController
LogRecord.LogLevel:                Information
LogRecord.FormattedMessage:        WeatherForecasts generated 5: Examples.AspNetCore.WeatherForecast, Examples.AspNetCore.WeatherForecast, Examples.AspNetCore.WeatherForecast, Examples.AspNetCore.WeatherForecast, Examples.AspNetCore.WeatherForecast
LogRecord.StateValues (Key:Value):
    count: 5
    forecasts: ["Examples.AspNetCore.WeatherForecast","Examples.AspNetCore.WeatherForecast","Examples.AspNetCore.WeatherForecast","Examples.AspNetCore.WeatherForecast","Examples.AspNetCore.WeatherForecast"]
    {OriginalFormat}: WeatherForecasts generated {count}: {forecasts}
LogRecord.ScopeValues (Key:Value):
[Scope.0]:SpanId: 5afcebdead5d82f9
[Scope.0]:TraceId: 7e8a593691b28893d4ca0e248845ea15
[Scope.0]:ParentId: 0000000000000000
[Scope.1]:ConnectionId: 0HMI06EJIP8VD
[Scope.2]:RequestId: 0HMI06EJIP8VD:00000001
[Scope.2]:RequestPath: /WeatherForecast
[Scope.3]:ActionId: 4bfb0faf-fa8c-47bb-9350-e62957f1d350
[Scope.3]:ActionName: Examples.AspNetCore.Controllers.WeatherForecastController.Get (Examples.AspNetCore)
[Scope.4]:Id: e13f37de769345ceb76f3630ac478598
[Scope.4]:{OriginalFormat}: {Id}

Resource associated with LogRecord:
service.name: AspNetCoreExampleService
service.version: 1.0.0.0
service.instance.id: awest-win10

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually prefer that we remove all alignments.
For folks who want better alignments, we might consider an option to output markdown tables (like how Benchmark.NET is doing).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the current output format is very similar to YAML, maybe we can move towards that direction? 😆

}
}
}
Expand Down Expand Up @@ -100,7 +100,10 @@ void ProcessScope(LogRecordScope scope, ConsoleLogRecordExporter exporter)

foreach (KeyValuePair<string, object> scopeItem in scope)
{
exporter.WriteLine($"[Scope.{scopeDepth}]:{scopeItem.Key,-RightPaddingLength}{scopeItem.Value}");
if (ConsoleTagTransformer.Instance.TryTransformTag(scopeItem, out var result))
{
exporter.WriteLine($"[Scope.{scopeDepth}]:{result}");
}
}
}

Expand All @@ -110,7 +113,10 @@ void ProcessScope(LogRecordScope scope, ConsoleLogRecordExporter exporter)
this.WriteLine("\nResource associated with LogRecord:");
foreach (var resourceAttribute in resource.Attributes)
{
this.WriteLine($"{resourceAttribute.Key}: {resourceAttribute.Value}");
if (ConsoleTagTransformer.Instance.TryTransformTag(resourceAttribute, out var result))
{
this.WriteLine(result);
}
}
}

Expand Down
9 changes: 5 additions & 4 deletions src/OpenTelemetry.Exporter.Console/ConsoleMetricExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,11 @@ public override ExportResult Export(in Batch<Metric> batch)
StringBuilder tagsBuilder = new StringBuilder();
foreach (var tag in metricPoint.Tags)
{
tagsBuilder.Append(tag.Key);
tagsBuilder.Append(':');
tagsBuilder.Append(tag.Value);
tagsBuilder.Append(' ');
if (ConsoleTagTransformer.Instance.TryTransformTag(tag, out var result))
{
tagsBuilder.Append(result);
tagsBuilder.Append(' ');
}
}

var tags = tagsBuilder.ToString().TrimEnd();
Expand Down
40 changes: 40 additions & 0 deletions src/OpenTelemetry.Exporter.Console/ConsoleTagTransformer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// <copyright file="ConsoleTagTransformer.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.Internal;

namespace OpenTelemetry.Exporter;

internal sealed class ConsoleTagTransformer : TagTransformer<string>
{
private ConsoleTagTransformer()
{
}

public static ConsoleTagTransformer Instance { get; } = new();

protected override string TransformIntegralTag(string key, long value) => $"{key}: {value}";

protected override string TransformFloatingPointTag(string key, double value) => $"{key}: {value}";

protected override string TransformBooleanTag(string key, bool value) => $"{key}: {(value ? "true" : "false")}";

protected override string TransformStringTag(string key, string value) => $"{key}: {value}";

protected override string TransformArrayTag(string key, Array array)
=> this.TransformStringTag(key, System.Text.Json.JsonSerializer.Serialize(array));
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,20 @@
<RunApiCompat>false</RunApiCompat>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Text.Json" Version="$(SystemTextJsonPkgVer)" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry\OpenTelemetry.csproj" />
</ItemGroup>

<ItemGroup>
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\OpenTelemetrySdkEventSource.cs" Link="Includes\OpenTelemetrySdkEventSource.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\PeriodicExportingMetricReaderHelper.cs" Link="Includes\PeriodicExportingMetricReaderHelper.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\ServiceProviderExtensions.cs" Link="Includes\ServiceProviderExtensions.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry\Internal\TagTransformer.cs" Link="Includes\TagTransformer.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Api\Internal\ExceptionExtensions.cs" Link="Includes\ExceptionExtensions.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Api\Internal\Guard.cs" Link="Includes\Guard.cs" />
<Compile Include="$(RepoRoot)\src\OpenTelemetry.Api\Internal\SpanAttributeConstants.cs" Link="Includes\SpanAttributeConstants.cs" />
</ItemGroup>
Expand Down