-
Notifications
You must be signed in to change notification settings - Fork 857
Add Console Activity Json Exporter #4548
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,7 +2,6 @@ | |
| <PropertyGroup> | ||
| <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> | ||
| </PropertyGroup> | ||
|
|
||
| <!-- prod packages --> | ||
| <ItemGroup> | ||
| <PackageVersion Include="Google.Protobuf" Version="[3.19.4,4.0)" /> | ||
|
|
@@ -26,11 +25,10 @@ | |
| <PackageVersion Include="StyleCop.Analyzers" Version="[1.2.0-beta.435,2.0)" /> | ||
| <PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="7.0.0" /> | ||
| <PackageVersion Include="System.Reflection.Emit.Lightweight" Version="4.7.0" /> | ||
| <PackageVersion Include="System.Text.Encodings.Web" Version="4.7.2" /> | ||
| <PackageVersion Include="System.Text.Json" Version="4.7.2" /> | ||
| <PackageVersion Include="System.Text.Encodings.Web" Version="7.0.0" /> | ||
| <PackageVersion Include="System.Text.Json" Version="7.0.2" /> | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the impact of this version bump? How many breaking changes would this introduce? E.g. https://blog.georgekosmidis.net/net-6-a-guide-for-the-high-impact-breaking-changes.html |
||
| <PackageVersion Include="System.Threading.Tasks.Extensions" Version="4.5.4" /> | ||
| </ItemGroup> | ||
|
|
||
| <!-- non-prod packages --> | ||
| <!-- 'net7.0' is the default `TargetFramework`. Use `VersionOverride` in the project to override the package versions from a different `TargetFramework` --> | ||
| <ItemGroup> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| OpenTelemetry.Exporter.ConsoleActivityJsonExporter | ||
| OpenTelemetry.Exporter.ConsoleActivityJsonExporter.ConsoleActivityJsonExporter(OpenTelemetry.Exporter.ConsoleExporterOptions options) -> void | ||
| override OpenTelemetry.Exporter.ConsoleActivityJsonExporter.Export(in OpenTelemetry.Batch<System.Diagnostics.Activity> batch) -> OpenTelemetry.ExportResult | ||
| static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleJsonExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder) -> OpenTelemetry.Trace.TracerProviderBuilder | ||
| static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleJsonExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, string name, System.Action<OpenTelemetry.Exporter.ConsoleExporterOptions> configure) -> OpenTelemetry.Trace.TracerProviderBuilder | ||
| static OpenTelemetry.Trace.ConsoleExporterHelperExtensions.AddConsoleJsonExporter(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action<OpenTelemetry.Exporter.ConsoleExporterOptions> configure) -> OpenTelemetry.Trace.TracerProviderBuilder |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,160 @@ | ||
| using System.Diagnostics; | ||
| using System.Text.Json; | ||
| using System.Text.Json.Serialization; | ||
| using OpenTelemetry.Resources; | ||
| using OpenTelemetry.Trace; | ||
|
|
||
| namespace OpenTelemetry.Exporter | ||
| { | ||
| public class ConsoleActivityJsonExporter : ConsoleExporter<Activity> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @brunomartinspro What's the motivation behind adding this new exporter to the repo?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we just need an option to existing exporter to write json output
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cijothomas Why do we want to add this to the existing exporter though? Users are allowed to create their own custom exporters and use them.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Its good to support a more standard/predictable output in the consoleexporter, without forcing everyone to author their own exporter.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I definitely see value in standardizing the ConsoleExporter output. If we decide to go forward with this though, I think the implementation should meet certain requirements:
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree with this. |
||
| { | ||
| public ConsoleActivityJsonExporter(ConsoleExporterOptions options) | ||
| : base(options) | ||
| { | ||
| } | ||
|
|
||
| public override ExportResult Export(in Batch<Activity> batch) | ||
| { | ||
| foreach (var activity in batch) | ||
| { | ||
| dynamic activityBuilder = new System.Dynamic.ExpandoObject(); | ||
|
|
||
|
|
||
| activityBuilder.TraceId = activity.TraceId.ToString(); | ||
| activityBuilder.SpanId = activity.SpanId.ToString(); | ||
| activityBuilder.ActivityTraceFlags = activity.ActivityTraceFlags; | ||
| activityBuilder.ActivitySourceName = activity.Source.Name; | ||
| activityBuilder.DisplayName = activity.DisplayName; | ||
| activityBuilder.Kind = activity.Kind; | ||
| activityBuilder.StartTime = activity.StartTimeUtc.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ"); | ||
| activityBuilder.Duration = activity.Duration; | ||
|
|
||
| if (!string.IsNullOrEmpty(activity.TraceStateString)) | ||
| { | ||
| activityBuilder.TraceState = activity.TraceStateString; | ||
| } | ||
|
|
||
| if (activity.ParentSpanId != default) | ||
| { | ||
| activityBuilder.ParentSpanId = activity.ParentSpanId.ToString(); | ||
| } | ||
|
|
||
| var statusCode = string.Empty; | ||
| var statusDesc = string.Empty; | ||
|
|
||
| if (activity.TagObjects.Any()) | ||
| { | ||
| foreach (ref readonly var tag in activity.EnumerateTagObjects()) | ||
| { | ||
| if (tag.Key == SpanAttributeConstants.StatusCodeKey) | ||
| { | ||
| statusCode = tag.Value as string; | ||
| continue; | ||
| } | ||
|
|
||
| if (tag.Key == SpanAttributeConstants.StatusDescriptionKey) | ||
| { | ||
| statusDesc = tag.Value as string; | ||
| continue; | ||
| } | ||
|
|
||
| if (ConsoleTagTransformer.Instance.TryTransformTag(tag, out var result)) | ||
| { | ||
| activityBuilder.Tags = result; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (activity.Status != ActivityStatusCode.Unset) | ||
| { | ||
| activityBuilder.StatusCode = activity.Status; | ||
|
|
||
| if (!string.IsNullOrEmpty(activity.StatusDescription)) | ||
| { | ||
| activityBuilder.StatusDescription = activity.StatusDescription; | ||
| } | ||
| } | ||
| else if (!string.IsNullOrEmpty(statusCode)) | ||
| { | ||
| activityBuilder.StatusCode = statusCode; | ||
| if (!string.IsNullOrEmpty(statusDesc)) | ||
| { | ||
| activityBuilder.StatusDescription = statusDesc; | ||
| } | ||
| } | ||
|
|
||
| if (activity.Events.Any()) | ||
| { | ||
| activityBuilder.Events = new List<dynamic>(); | ||
|
|
||
| foreach (ref readonly var activityEvent in activity.EnumerateEvents()) | ||
| { | ||
| dynamic activityEventBuilder = new System.Dynamic.ExpandoObject(); | ||
|
|
||
| activityEventBuilder.Name = activityEvent.Name; | ||
| activityEventBuilder.Timestamp = activityEvent.Timestamp; | ||
|
|
||
| foreach (ref readonly var attribute in activityEvent.EnumerateTagObjects()) | ||
| { | ||
| if (ConsoleTagTransformer.Instance.TryTransformTag(attribute, out var result)) | ||
| { | ||
| activityEventBuilder.Tags = result; | ||
| } | ||
| } | ||
|
|
||
| activityBuilder.Events.add(activityEventBuilder); | ||
| } | ||
| } | ||
|
|
||
| if (activity.Links.Any()) | ||
| { | ||
| activityBuilder.Links = new List<dynamic>(); | ||
|
|
||
| foreach (ref readonly var activityLink in activity.EnumerateLinks()) | ||
| { | ||
| dynamic activityLinkBuilder = new System.Dynamic.ExpandoObject(); | ||
|
|
||
| activityLinkBuilder.TraceId = activityLink.Context.TraceId.ToString(); | ||
| activityLinkBuilder.SpanId = activityLink.Context.SpanId.ToString(); | ||
|
|
||
| foreach (ref readonly var attribute in activityLink.EnumerateTagObjects()) | ||
| { | ||
| if (ConsoleTagTransformer.Instance.TryTransformTag(attribute, out var result)) | ||
| { | ||
| activityLinkBuilder.Tags = result; | ||
| } | ||
| } | ||
|
|
||
| activityBuilder.Links.add(activityLinkBuilder); | ||
| } | ||
| } | ||
|
|
||
| var resource = this.ParentProvider.GetResource(); | ||
| if (resource != Resource.Empty) | ||
| { | ||
|
|
||
| foreach (var resourceAttribute in resource.Attributes) | ||
| { | ||
| if (ConsoleTagTransformer.Instance.TryTransformTag(resourceAttribute, out var result)) | ||
| { | ||
| activityBuilder.Attributes = result; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| var options = new JsonSerializerOptions | ||
| { | ||
| WriteIndented = false, | ||
| ReferenceHandler = ReferenceHandler.IgnoreCycles, | ||
| PropertyNamingPolicy = JsonNamingPolicy.CamelCase, | ||
| }; | ||
|
|
||
| string json = JsonSerializer.Serialize(activityBuilder, options); | ||
|
|
||
| this.WriteLine(json); | ||
| } | ||
|
|
||
| return ExportResult.Success; | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit, indent