Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
17 changes: 7 additions & 10 deletions src/OpenTelemetry.Exporter.Console/ConsoleExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading;
Expand All @@ -27,10 +28,10 @@

namespace OpenTelemetry.Exporter.Console
{
public class ConsoleExporter : ActivityExporter
public class ConsoleExporter : ActivityExporterSync
{
private readonly JsonSerializerOptions serializerOptions;
private bool displayAsJson;
private readonly bool displayAsJson;

public ConsoleExporter(ConsoleExporterOptions options)
{
Expand All @@ -46,9 +47,10 @@ public ConsoleExporter(ConsoleExporterOptions options)
this.serializerOptions.Converters.Add(new ActivityTraceIdConverter());
}

public override Task<ExportResult> ExportAsync(IEnumerable<Activity> activityBatch, CancellationToken cancellationToken)
[MethodImpl(MethodImplOptions.Synchronized)]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I didn't even notice this until I read the description. My initial reaction... feels a little hackish. We shouldn't rely on users to add this, we should wrap the call in a lock if we want to make sure it isn't called concurrently? The spec says something about Export shouldn't be called concurrently, it doesn't say Exporters should implement Export so it isn't callable concurrently, which is what this feels like. 🤷

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Or how about having the SimpleExportActivityProcessor taking a parameter which allows people to specify whether it is reentrant or not (and by default use lock), I was thinking about ETW/LTTng scenario where folks want ultimate concurrency.

Something like this.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I like the idea of a flag to opt into different behavior than what the spec says. We could also have a SimpleProcessor and a BatchingProcessor that are fully spec-compliant but also ship something like a ConcurrentProcessor or ReentrantProcessor that can be explicit in its changing of the rules?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

That's works, too! 😄

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I moved the current logic to ReentrantExportActivityProcessor, and changed SimpleExportActivityProcessor to simply call the reentrant one with a lock guard.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Now the PR got merged and OOP fans are staring at us - "Why are you guys making a non-reentrant class a child of reentrant one" 😂

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It is a bit odd, isn't it? I know you were shooting for code re-use, maybe the flag/option idea would be better? You could make a base class that has everything but the OnEnd part?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Tracked by #898.

public override ExportResultSync Export(IEnumerable<Activity> batch)
{
foreach (var activity in activityBatch)
foreach (var activity in batch)
{
if (this.displayAsJson)
{
Expand Down Expand Up @@ -127,12 +129,7 @@ public override Task<ExportResult> ExportAsync(IEnumerable<Activity> activityBat
}
}

return Task.FromResult(ExportResult.Success);
}

public override Task ShutdownAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
return ExportResultSync.Success;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public static TracerProviderBuilder AddConsoleExporter(this TracerProviderBuilde

var options = new ConsoleExporterOptions();
configure?.Invoke(options);
return builder.AddProcessor(new SimpleActivityProcessor(new ConsoleExporter(options)));
return builder.AddProcessor(new SimpleExportActivityProcessor(new ConsoleExporter(options)));
}
}
}
2 changes: 1 addition & 1 deletion src/OpenTelemetry/Trace/ActivityExporterSync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public abstract class ActivityExporterSync : IDisposable
/// </summary>
/// <param name="batch">Batch of activities to export.</param>
/// <returns>Result of export.</returns>
public abstract ExportResult Export(IEnumerable<Activity> batch);
public abstract ExportResultSync Export(IEnumerable<Activity> batch);

/// <summary>
/// Shuts down the exporter.
Expand Down