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

Align the telemetry tags with official guidelines #1583

Merged
merged 4 commits into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
68 changes: 34 additions & 34 deletions docs/advanced/telemetry.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,15 @@ var serviceCollection = new ServiceCollection()

## Metrics

The metrics are emitted under the `Polly` meter name. The subsequent sections provide insights into the metrics produced by Polly. Please note that any custom enriched dimensions are not depicted in the following tables.
The metrics are emitted under the `Polly` meter name. The subsequent sections provide insights into the metrics produced by Polly. Please note that any custom enriched tags are not depicted in the following tables.

Every telemetry event has the following dimensions:
Every telemetry event has the following tags:

- `pipeline-name`: Optional, comes from `ResiliencePipelineBuilder.Name`.
- `pipeline-instance`: Optional, comes from `ResiliencePipelineBuilder.InstanceName`.
- `strategy-name`: Optional, comes from `RetryStrategyOptions.Name`.
- `pipeline.name`: Optional, comes from `ResiliencePipelineBuilder.Name`.
- `pipeline.instance`: Optional, comes from `ResiliencePipelineBuilder.InstanceName`.
- `strategy.name`: Optional, comes from `RetryStrategyOptions.Name`.

The sample below demonstrates how to assign these dimensions:
The sample below demonstrates how to assign these tags:

<!-- snippet: telemetry-coordinates -->
```cs
Expand All @@ -99,59 +99,59 @@ builder.AddRetry(new RetryStrategyOptions
```
<!-- endSnippet -->

These values are subsequently reflected in the metrics below:
These values are subsequently reflected in the following metering instruments exposed by the Polly:

### resilience-events
### Instrument: `resilience.polly.strategy.events`

- Type: *Counter*
- Description: Emitted upon the occurrence of a resilience event.

Dimensions:
Tags:

|Name|Description|
|---| ---|
|`event-name`| The name of the emitted event.|
|`event-severity`| The severity of the event (`Debug`, `Information`, `Warning`, `Error`, `Critical`).|
|`pipeline-name`| The name of the pipeline corresponding to the resilience pipeline.|
|`pipeline-instance`| The instance name of the pipeline corresponding to the resilience pipeline.|
|`strategy-name`| The name of the strategy generating this event.|
|`operation-key`| The operation key associated with the call site. |
|`exception-name`| The full name of the exception assigned to the execution result (`System.InvalidOperationException`). |
|`event.name`| The name of the emitted event.|
|`event.severity`| The severity of the event (`Debug`, `Information`, `Warning`, `Error`, `Critical`).|
|`pipeline.name`| The name of the pipeline corresponding to the resilience pipeline.|
|`pipeline.instance`| The instance name of the pipeline corresponding to the resilience pipeline.|
|`strategy.name`| The name of the strategy generating this event.|
|`operation.key`| The operation key associated with the call site. |
|`exception.type`| The full name of the exception assigned to the execution result (`System.InvalidOperationException`). |

### execution-attempt-duration
### Instrument: `resilience.polly.strategy.attempt.duration`

- Type: *Histogram*
- Unit: *milliseconds*
- Description: Tracks the duration of execution attempts, produced by `Retry` and `Hedging` resilience strategies.

Dimensions:
Tags:

|Name|Description|
|---| ---|
|`event-name`| The name of the emitted event.|
|`event-severity`| The severity of the event (`Debug`, `Information`, `Warning`, `Error`, `Critical`).|
|`pipeline-name`| The name of the pipeline corresponding to the resilience pipeline.|
|`pipeline-instance`| The instance name of the pipeline corresponding to the resilience pipeline.|
|`strategy-name`| The name of the strategy generating this event.|
|`operation-key`| The operation key associated with the call site. |
|`exception-name`| The full name of the exception assigned to the execution result (`System.InvalidOperationException`). |
|`attempt-number`| The execution attempt number, starting at 0 (0, 1, 2, etc.). |
|`attempt-handled`| Indicates if the execution outcome was handled. A handled outcome indicates execution failure and the need for retry (`true`, `false`). |

### pipeline-execution-duration
|`event.name`| The name of the emitted event.|
|`event.severity`| The severity of the event (`Debug`, `Information`, `Warning`, `Error`, `Critical`).|
|`pipeline.name`| The name of the pipeline corresponding to the resilience pipeline.|
|`pipeline.instance`| The instance name of the pipeline corresponding to the resilience pipeline.|
|`strategy.name`| The name of the strategy generating this event.|
|`operation.key`| The operation key associated with the call site. |
|`exception.type`| The full name of the exception assigned to the execution result (`System.InvalidOperationException`). |
|`attempt.number`| The execution attempt number, starting at 0 (0, 1, 2, etc.). |
|`attempt.handled`| Indicates if the execution outcome was handled. A handled outcome indicates execution failure and the need for retry (`true`, `false`). |

### Instrument: `resilience.polly.pipeline.duration`

- Type: *Histogram*
- Unit: *milliseconds*
- Description: Measures the duration of resilience pipelines.

Dimensions:
Tags:

|Name|Description|
|---| ---|
|`pipeline-name`| The name of the pipeline corresponding to the resilience pipeline.|
|`pipeline-instance`| The instance name of the pipeline corresponding to the resilience pipeline.|
|`operation-key`| The operation key associated with the call site. |
|`exception-name`| The full name of the exception assigned to the execution result (`System.InvalidOperationException`). |
|`pipeline.name`| The name of the pipeline corresponding to the resilience pipeline.|
|`pipeline.instance`| The instance name of the pipeline corresponding to the resilience pipeline.|
|`operation.key`| The operation key associated with the call site. |
|`exception.type`| The full name of the exception assigned to the execution result (`System.InvalidOperationException`). |

## Logs

Expand Down
18 changes: 9 additions & 9 deletions src/Polly.Extensions/Telemetry/ResilienceTelemetryTags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@ namespace Polly.Telemetry;

internal class ResilienceTelemetryTags
{
public const string EventName = "event-name";
public const string EventName = "event.name";

public const string EventSeverity = "event-severity";
public const string EventSeverity = "event.severity";

public const string PipelineName = "pipeline-name";
public const string PipelineName = "pipeline.name";

public const string PipelineInstance = "pipeline-instance";
public const string PipelineInstance = "pipeline.instance";

public const string StrategyName = "strategy-name";
public const string StrategyName = "strategy.name";

public const string OperationKey = "operation-key";
public const string OperationKey = "operation.key";

public const string ExceptionName = "exception-name";
public const string ExceptionType = "exception.type";

public const string AttemptNumber = "attempt-number";
public const string AttemptNumber = "attempt.number";

public const string AttemptHandled = "attempt-handled";
public const string AttemptHandled = "attempt.handled";
}
8 changes: 4 additions & 4 deletions src/Polly.Extensions/Telemetry/TelemetryListenerImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ public TelemetryListenerImpl(TelemetryOptions options)
_listeners = options.TelemetryListeners.ToList();

Counter = Meter.CreateCounter<int>(
"resilience-events",
"resilience.polly.strategy.events",
description: "Tracks the number of resilience events that occurred in resilience strategies.");

AttemptDuration = Meter.CreateHistogram<double>(
"execution-attempt-duration",
"resilience.polly.strategy.attempt.duration",
unit: "ms",
description: "Tracks the duration of execution attempts.");

ExecutionDuration = Meter.CreateHistogram<double>(
"pipeline-execution-duration",
"resilience.polly.pipeline.duration",
unit: "ms",
description: "The execution duration of resilience pipelines.");
}
Expand Down Expand Up @@ -98,7 +98,7 @@ private static void AddCommonTags<TResult, TArgs>(in EnrichmentContext<TResult,

if (context.TelemetryEvent.Outcome?.Exception is Exception e)
{
context.Tags.Add(new(ResilienceTelemetryTags.ExceptionName, e.GetType().FullName));
context.Tags.Add(new(ResilienceTelemetryTags.ExceptionType, e.GetType().FullName));
}
}

Expand Down
8 changes: 4 additions & 4 deletions test/Polly.Core.Tests/ResiliencePipelineBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -326,27 +326,27 @@ public void Build_EnsureCorrectContext()
context =>
{
context.Telemetry.TelemetrySource.PipelineName.Should().Be("builder-name");
context.Telemetry.TelemetrySource.StrategyName.Should().Be("strategy-name");
context.Telemetry.TelemetrySource.StrategyName.Should().Be("strategy_name");
context.Telemetry.Should().NotBeNull();
context.TimeProvider.Should().Be(builder.TimeProvider);
verified1 = true;

return new TestResilienceStrategy();
},
new TestResilienceStrategyOptions { Name = "strategy-name" });
new TestResilienceStrategyOptions { Name = "strategy_name" });

builder.AddStrategy(
context =>
{
context.Telemetry.TelemetrySource.PipelineName.Should().Be("builder-name");
context.Telemetry.TelemetrySource.StrategyName.Should().Be("strategy-name-2");
context.Telemetry.TelemetrySource.StrategyName.Should().Be("strategy_name-2");
context.Telemetry.Should().NotBeNull();
context.TimeProvider.Should().Be(builder.TimeProvider);
verified2 = true;

return new TestResilienceStrategy();
},
new TestResilienceStrategyOptions { Name = "strategy-name-2" });
new TestResilienceStrategyOptions { Name = "strategy_name-2" });

// act
builder.Build();
Expand Down
6 changes: 3 additions & 3 deletions test/Polly.Core.Tests/StrategyBuilderContextTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ public void Ctor_EnsureDefaults()
{
var timeProvider = new FakeTimeProvider();
var context = new StrategyBuilderContext(
new ResilienceStrategyTelemetry(new ResilienceTelemetrySource("builder-name", "instance", "strategy-name"),
new ResilienceStrategyTelemetry(new ResilienceTelemetrySource("builder-name", "instance", "strategy_name"),
Substitute.For<TelemetryListener>()), timeProvider);

context.Telemetry.TelemetrySource.PipelineName.Should().Be("builder-name");
context.Telemetry.TelemetrySource.PipelineInstanceName.Should().Be("instance");
context.Telemetry.TelemetrySource.StrategyName.Should().Be("strategy-name");
context.Telemetry.TelemetrySource.StrategyName.Should().Be("strategy_name");
context.TimeProvider.Should().Be(timeProvider);
context.Telemetry.Should().NotBeNull();

context.Telemetry.TelemetrySource.PipelineName.Should().Be("builder-name");
context.Telemetry.TelemetrySource.StrategyName.Should().Be("strategy-name");
context.Telemetry.TelemetrySource.StrategyName.Should().Be("strategy_name");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public ResilienceStrategyTelemetryTests()
_source = new ResilienceTelemetrySource(
"builder",
"instance",
"strategy-name");
"strategy_name");

_sut = TestUtilities.CreateResilienceTelemetry(args => _args.Add(args));
}
Expand All @@ -35,7 +35,7 @@ public void Report_NoOutcome_OK()
args.Event.EventName.Should().Be("dummy-event");
args.Event.Severity.Should().Be(ResilienceEventSeverity.Warning);
args.Outcome.Should().BeNull();
args.Source.StrategyName.Should().Be("strategy-name");
args.Source.StrategyName.Should().Be("strategy_name");
args.Arguments.Should().BeOfType<TestArguments>();
args.Outcome.Should().BeNull();
args.Context.Should().NotBeNull();
Expand All @@ -44,7 +44,7 @@ public void Report_NoOutcome_OK()
[Fact]
public void ResiliencePipelineTelemetry_NoDiagnosticSource_Ok()
{
var source = new ResilienceTelemetrySource("builder", "instance", "strategy-name");
var source = new ResilienceTelemetrySource("builder", "instance", "strategy_name");
var sut = new ResilienceStrategyTelemetry(source, null);
var context = ResilienceContextPool.Shared.Get();

Expand All @@ -62,7 +62,7 @@ public void Report_Outcome_OK()
var args = _args.Single();
args.Event.EventName.Should().Be("dummy-event");
args.Event.Severity.Should().Be(ResilienceEventSeverity.Warning);
args.Source.StrategyName.Should().Be("strategy-name");
args.Source.StrategyName.Should().Be("strategy_name");
args.Arguments.Should().BeOfType<TestArguments>();
args.Outcome.Should().NotBeNull();
args.Outcome!.Value.Result.Should().Be(99);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ public void AddResiliencePipeline_CustomInstanceName_EnsureReported(bool usingBu
// arrange
using var loggerFactory = new FakeLoggerFactory();

var context = ResilienceContextPool.Shared.Get("my-operation-key");
var context = ResilienceContextPool.Shared.Get("my-operation_key");
var services = new ServiceCollection();
var listener = new FakeTelemetryListener();
var registry = services
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ public void StrategiesPerEndpoint_1365()

pipeline1.Execute(() => { });
events.Should().HaveCount(5);
events[0].Tags["pipeline-name"].Should().Be("endpoint-pipeline");
events[0].Tags["pipeline-instance"].Should().Be("Endpoint 1/Resource 1");
events[0].Tags["pipeline.name"].Should().Be("endpoint-pipeline");
events[0].Tags["pipeline.instance"].Should().Be("Endpoint 1/Resource 1");
}

public class EndpointOptions
Expand Down
Loading