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

Add support for multiple pipelines in OpenTelemetryBuilder with Activity #735

Merged
merged 6 commits into from
Jun 18, 2020
Merged

Add support for multiple pipelines in OpenTelemetryBuilder with Activity #735

merged 6 commits into from
Jun 18, 2020

Conversation

cijothomas
Copy link
Member

Towards 1c in #684

Changes

Add ability to have multiple processing pipeline, exposed via AddProcessorPipeline on OpenTelemetryBuilder. (this capability already existed in Span based pipeline)

Checklist

  • I ran Unit Tests locally.

For significant contributions please make sure you have completed the following items:

  • Design discussion issue #
  • Changes in public API reviewed

The PR will automatically request reviews from code owners and trigger CI build and tests.

@cijothomas cijothomas requested a review from a team June 17, 2020 07:40

namespace OpenTelemetry.Trace.Export.Internal
{
internal class BroadcastActivityProcessor : ActivityProcessor, IDisposable
Copy link
Member

Choose a reason for hiding this comment

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

The name is misleading since "broadcast" normally means there is no need to specify the target.

Probably borrow from Java/Python:

Copy link
Member

Choose a reason for hiding this comment

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

FanOutActivityProcessor? 🤷

{
internal class BroadcastActivityProcessor : ActivityProcessor, IDisposable
{
private readonly IEnumerable<ActivityProcessor> processors;
Copy link
Member

Choose a reason for hiding this comment

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

Potential perf concern:
IEnumerable<T> implies a new enumerator object creation on the hot path (each span will result in a foreach (var processor in this.processors).
Probably worth considering array or list (which maintains the count and can be accessed via index).

throw new ArgumentException($"{nameof(processors)} collection is empty");
}

this.processors = processors;
Copy link
Member

Choose a reason for hiding this comment

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

Should this be a shallow copy? What if the passed in processors got updated later?

using OpenTelemetry.Trace.Export;
using Xunit;

namespace OpenTelemetry.Tests.Impl.Trace.Config
Copy link
Member

Choose a reason for hiding this comment

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

nit: "Impl" -> "Implementation"

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes. we need to rearrange this quite a lot. "impl" is used in many other places as well. - i'll do it as a separate PR where we will do consistent namespace. If product is namespace, then test would be namespace.test. something like that. (currently its a mix with no consistency)

}
}

public override void OnStart(Activity activity)
Copy link
Member

Choose a reason for hiding this comment

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

nit: Probably more common to have Start before End.

return Task.WhenAll(tasks);
}

public void Dispose()
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

IMO because it's internal it's fine as-is. That being said, OpenTelemetrySdk isn't calling shutdown or dispose on the ActivityProcessor it is maintaining. That's a problem. We need to flush out spans & perform cleanup on app shutdown right? I think OpenTelemetrySdk.Dispose should call ActivityProcessor.Dispose which should invoke ActivityProcessor.ShutdownAsync? We might want to look at using IAsyncDisposable for that.

Copy link
Member

Choose a reason for hiding this comment

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

There are few things we need to address:

  1. Improvements to SimpleSpanProcessor. #674 SimpleSpanProcessor needs to be a synchronous call (e.g. when the control is returned to the caller, the span got processed - current it is not guaranteed).
  2. The life-cycle management of processors/exporters, related to this comment. For example, if we have the same processor/exporter registered twice, would we flush the exporter on the first OnEnd, or maintain a refcount and call OnEnd during Dispose? Does OnEnd need to be ref-counted as well?
  3. We need to have a deterministic flush semantic. By default I would imagine we want to flush traces/logs before app shutdown, metrics is something debatable. And we need to give option to the user whether they want to wait indefinitely or have a timeout or no wait at all.

Copy link
Member Author

Choose a reason for hiding this comment

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

Agree with all of the above - But my goal with this PR is to just mimic the existing behavior with Spans (this pr was made with pure 'copy paste & minor adjustments' ). I'd prefer to get the parity 1st, then fix underlying issues.

Let me know if this approach is okay?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, these are not blockers for this PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

IMO because it's internal it's fine as-is. That being said, OpenTelemetrySdk isn't calling shutdown or dispose on the ActivityProcessor it is maintaining. That's a problem. We need to flush out spans & perform cleanup on app shutdown right? I think OpenTelemetrySdk.Dispose should call ActivityProcessor.Dispose which should invoke ActivityProcessor.ShutdownAsync? We might want to look at using IAsyncDisposable for that.

Yes this is needed. Modified OTSDK to call dispose on the Activityprocessor it has.

Copy link
Member Author

Choose a reason for hiding this comment

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

Will follow up on why Span was not calling Shutdown in SimpleProcessor! (Was doing it right for batching one). Anyway - both will be fixed in next PR.

@cijothomas cijothomas mentioned this pull request Jun 17, 2020
32 tasks
Copy link
Contributor

@pjanotti pjanotti left a comment

Choose a reason for hiding this comment

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

LGTM

tasks.Add(processor.ShutdownAsync(cancellationToken));
}

return Task.WhenAll(tasks);
Copy link
Contributor

Choose a reason for hiding this comment

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

The cancellationToken is passed to all ShutdownAsync but if one misbehaves this line can wait forever. Is this relying on cancellation by the caller?

Copy link
Member Author

Choose a reason for hiding this comment

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

The current code is vulnerable to one misbehaving processor. Not just in shutdown but even in start/stop as well. We need to address it properly.

@cijothomas
Copy link
Member Author

Merging this as this makes Activity processing pipeline as same features as Span pipeline.
(Fully agree about a lot of issues with both :), will address them as follow ups)

@cijothomas cijothomas merged commit afd9135 into open-telemetry:master Jun 18, 2020
@cijothomas cijothomas deleted the cijothomas/activityprocessingpipeline branch June 18, 2020 00:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants