-
Notifications
You must be signed in to change notification settings - Fork 887
Add otel.sdk.processor.log.processed metric #7486
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
base: main
Are you sure you want to change the base?
Changes from 4 commits
6a8f28c
89ff78e
fa79e5a
48f2b86
6c5df34
c5c90ff
2a53a4a
d79a6af
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 |
|---|---|---|
| @@ -1,3 +1,6 @@ | ||
| OpenTelemetry.Resources.Resource.Resource(System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string!, object!>>! attributes, string? schemaUrl) -> void | ||
| OpenTelemetry.Resources.Resource.SchemaUrl.get -> string? | ||
| static OpenTelemetry.Resources.ResourceBuilderExtensions.AddAttributes(this OpenTelemetry.Resources.ResourceBuilder! resourceBuilder, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string!, object!>>! attributes, string? schemaUrl) -> OpenTelemetry.Resources.ResourceBuilder! | ||
| override OpenTelemetry.SimpleLogRecordExportProcessor.OnEnd(OpenTelemetry.Logs.LogRecord! data) -> void | ||
| override OpenTelemetry.BatchLogRecordExportProcessor.OnShutdown(int timeoutMilliseconds) -> bool | ||
| override OpenTelemetry.SimpleLogRecordExportProcessor.OnShutdown(int timeoutMilliseconds) -> bool | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| // Copyright The OpenTelemetry Authors | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| using System.Diagnostics.Metrics; | ||
|
|
||
| namespace OpenTelemetry; | ||
|
|
||
| /// <summary> | ||
| /// Shared infrastructure for SDK self-observability metrics. | ||
| /// </summary> | ||
| internal static class SdkSelfObservability | ||
| { | ||
| #pragma warning disable SA1202 // internal before private - initialization order requires Meter first | ||
|
cijothomas marked this conversation as resolved.
Outdated
|
||
| private static readonly Meter Meter = new(new MeterOptions("otel.sdk.experimental") | ||
| { | ||
| Version = typeof(SdkSelfObservability).Assembly.GetName().Version?.ToString(), | ||
| }); | ||
|
cijothomas marked this conversation as resolved.
Outdated
|
||
|
|
||
| internal static readonly Counter<long> LogProcessedCounter = Meter.CreateCounter<long>( | ||
| "otel.sdk.processor.log.processed", | ||
| "{log_record}", | ||
| "The number of log records for which the processing has finished, either successful or failed."); | ||
| #pragma warning restore SA1202 | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,13 @@ namespace OpenTelemetry; | |
| /// </summary> | ||
| public class BatchLogRecordExportProcessor : BatchExportProcessor<LogRecord> | ||
| { | ||
| private static int instanceCounter = -1; | ||
|
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. While unlikely there'd ever be that many created in the lifetime of a process, maybe use |
||
|
|
||
| private readonly KeyValuePair<string, object?>[] successTags; | ||
| private readonly KeyValuePair<string, object?>[] queueFullTags; | ||
| private readonly KeyValuePair<string, object?>[] alreadyShutdownTags; | ||
| private volatile bool isShutdown; | ||
|
|
||
| /// <summary> | ||
| /// Initializes a new instance of the <see cref="BatchLogRecordExportProcessor"/> class. | ||
| /// </summary> | ||
|
|
@@ -32,11 +39,32 @@ public BatchLogRecordExportProcessor( | |
| exporterTimeoutMilliseconds, | ||
| maxExportBatchSize) | ||
| { | ||
| var index = Interlocked.Increment(ref instanceCounter); | ||
| var componentName = "batching_log_processor/" + index.ToString(System.Globalization.CultureInfo.InvariantCulture); | ||
| this.successTags = | ||
| [ | ||
| new("otel.component.type", "batching_log_processor"), | ||
| new("otel.component.name", componentName), | ||
| ]; | ||
| this.queueFullTags = | ||
| [ | ||
| new("otel.component.type", "batching_log_processor"), | ||
| new("otel.component.name", componentName), | ||
| new("error.type", "queue_full"), | ||
| ]; | ||
| this.alreadyShutdownTags = | ||
| [ | ||
| new("otel.component.type", "batching_log_processor"), | ||
| new("otel.component.name", componentName), | ||
| new("error.type", "already_shutdown"), | ||
| ]; | ||
|
cijothomas marked this conversation as resolved.
Outdated
|
||
| } | ||
|
|
||
| /// <inheritdoc/> | ||
| public override void OnEnd(LogRecord data) | ||
| { | ||
| bool enqueued; | ||
|
|
||
| // Note: Intentionally not using Guard.ThrowIfNull to save prod cycles | ||
| #pragma warning disable CA1062 // Validate arguments of public methods | ||
| switch (data.Source) | ||
|
|
@@ -45,7 +73,8 @@ public override void OnEnd(LogRecord data) | |
| case LogRecord.LogRecordSource.FromSharedPool: | ||
| data.Buffer(); | ||
| data.AddReference(); | ||
| if (!this.TryExport(data)) | ||
| enqueued = this.TryExport(data); | ||
| if (!enqueued) | ||
| { | ||
| LogRecordSharedPool.Current.Return(data); | ||
| } | ||
|
|
@@ -54,16 +83,40 @@ public override void OnEnd(LogRecord data) | |
|
|
||
| case LogRecord.LogRecordSource.CreatedManually: | ||
| data.Buffer(); | ||
| this.TryExport(data); | ||
| enqueued = this.TryExport(data); | ||
| break; | ||
|
|
||
| case LogRecord.LogRecordSource.FromThreadStaticPool: | ||
| default: | ||
| Debug.Assert(data.Source == LogRecord.LogRecordSource.FromThreadStaticPool, "LogRecord source was something unexpected"); | ||
|
|
||
| // Note: If we are using ThreadStatic pool we make a copy of the record. | ||
| this.TryExport(data.Copy()); | ||
| enqueued = this.TryExport(data.Copy()); | ||
| break; | ||
| } | ||
|
|
||
| // TODO: Consider switching to an ObservableCounter that piggybacks on | ||
|
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. Issue for tracking?
Member
Author
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. Will file a tracking issue for this.
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. Cool - just add a link to the TODO once created. |
||
| // CircularBuffer.AddedCount and DroppedCount to eliminate per-item | ||
| // Counter.Add() overhead. This would require a registry pattern for | ||
| // multiple instances but avoids any hot-path cost when a listener is active. | ||
| if (this.isShutdown) | ||
| { | ||
| SdkSelfObservability.LogProcessedCounter.Add(1, this.alreadyShutdownTags); | ||
| } | ||
| else if (!enqueued) | ||
| { | ||
| SdkSelfObservability.LogProcessedCounter.Add(1, this.queueFullTags); | ||
| } | ||
| else | ||
| { | ||
| SdkSelfObservability.LogProcessedCounter.Add(1, this.successTags); | ||
| } | ||
|
cijothomas marked this conversation as resolved.
Outdated
|
||
| } | ||
|
|
||
| /// <inheritdoc/> | ||
| protected override bool OnShutdown(int timeoutMilliseconds) | ||
| { | ||
| this.isShutdown = true; | ||
| return base.OnShutdown(timeoutMilliseconds); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.