From 5269bcb35a2998586466929c2f627795461993ec Mon Sep 17 00:00:00 2001 From: Tim Salva Date: Fri, 3 Jan 2025 00:46:47 +0000 Subject: [PATCH 1/3] [Feature] Generate metrics from traces #3389 --- Directory.Packages.props | 1 + docker-compose-prometheus.yaml | 2 + docker-compose.yaml | 2 + prometheus.yml | 9 + .../GreetingsWeb/GreetingsWeb.csproj | 1 + .../WebAPI_Dapper/GreetingsWeb/Startup.cs | 11 +- .../SalutationAnalytics/Program.cs | 2 +- .../BrighterTracerBuilderExtensions.cs | 26 ++- .../BrighterMetricsFromTracesProcessor.cs | 85 ++++++++ .../BrighterSemanticConventions.cs | 20 +- .../Observability/BrighterTracer.cs | 22 +- .../Observability/DbMeter.cs | 85 ++++++++ .../Observability/IAmABrighterDbMeter.cs | 42 ++++ .../IAmABrighterMessagingMeter.cs | 61 ++++++ .../Observability/MessagingMeter.cs | 190 ++++++++++++++++++ .../Observability/MeterProviderExtensions.cs | 46 +++++ .../Observability/TagObjectsExtensions.cs | 69 +++++++ .../Observability/TailSamplerProcessor.cs | 41 ++++ 18 files changed, 706 insertions(+), 9 deletions(-) create mode 100644 src/Paramore.Brighter/Observability/BrighterMetricsFromTracesProcessor.cs create mode 100644 src/Paramore.Brighter/Observability/DbMeter.cs create mode 100644 src/Paramore.Brighter/Observability/IAmABrighterDbMeter.cs create mode 100644 src/Paramore.Brighter/Observability/IAmABrighterMessagingMeter.cs create mode 100644 src/Paramore.Brighter/Observability/MessagingMeter.cs create mode 100644 src/Paramore.Brighter/Observability/MeterProviderExtensions.cs create mode 100644 src/Paramore.Brighter/Observability/TagObjectsExtensions.cs create mode 100644 src/Paramore.Brighter/Observability/TailSamplerProcessor.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index 9b284502b3..5c14ff4c17 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -67,6 +67,7 @@ + diff --git a/docker-compose-prometheus.yaml b/docker-compose-prometheus.yaml index dc7dd865ad..4719310d32 100644 --- a/docker-compose-prometheus.yaml +++ b/docker-compose-prometheus.yaml @@ -7,3 +7,5 @@ services: - ./prometheus.yml:/etc/prometheus/prometheus.yml ports: - "9090:9090" + extra_hosts: + - "host.docker.internal:host-gateway" \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index e3b26c62e9..d4f2b11a05 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -113,6 +113,8 @@ services: - ./prometheus.yml:/etc/prometheus/prometheus.yml ports: - "9090:9090" + extra_hosts: + - "host.docker.internal:host-gateway" networks: kafka: diff --git a/prometheus.yml b/prometheus.yml index 27557ccb95..f2c23fa20d 100644 --- a/prometheus.yml +++ b/prometheus.yml @@ -5,3 +5,12 @@ scrape_configs: - job_name: 'otel-collector' static_configs: - targets: ['otel-collector:9090'] + + - job_name: 'brighter-sample-app' + scheme: https + tls_config: + insecure_skip_verify: true + static_configs: + - targets: + - 'host.docker.internal:5001' + metrics_path: /metrics diff --git a/samples/WebAPI/WebAPI_Dapper/GreetingsWeb/GreetingsWeb.csproj b/samples/WebAPI/WebAPI_Dapper/GreetingsWeb/GreetingsWeb.csproj index db84d46a44..5e71745707 100644 --- a/samples/WebAPI/WebAPI_Dapper/GreetingsWeb/GreetingsWeb.csproj +++ b/samples/WebAPI/WebAPI_Dapper/GreetingsWeb/GreetingsWeb.csproj @@ -9,6 +9,7 @@ + diff --git a/samples/WebAPI/WebAPI_Dapper/GreetingsWeb/Startup.cs b/samples/WebAPI/WebAPI_Dapper/GreetingsWeb/Startup.cs index 89eaf5d7c6..2eaaef0502 100644 --- a/samples/WebAPI/WebAPI_Dapper/GreetingsWeb/Startup.cs +++ b/samples/WebAPI/WebAPI_Dapper/GreetingsWeb/Startup.cs @@ -18,6 +18,8 @@ using Paramore.Brighter; using Paramore.Brighter.Extensions.DependencyInjection; using Paramore.Brighter.Extensions.Diagnostics; +using Paramore.Brighter.Extensions.Diagnostics.obj; +using Paramore.Brighter.Observability; using Paramore.Darker.AspNetCore; using Paramore.Darker.Policies; using Paramore.Darker.QueryLogging; @@ -47,6 +49,8 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); + + app.UseOpenTelemetryPrometheusScrapingEndpoint(); } @@ -153,12 +157,13 @@ private void ConfigureObservability(IServiceCollection services) serviceName: "GreetingsWeb", serviceVersion: typeof(Program).Assembly.GetName().Version?.ToString() ?? "unknown", serviceInstanceId: Environment.MachineName); - }).WithTracing(builder => + }) + .WithTracing(builder => { builder .AddBrighterInstrumentation() .AddSource("RabbitMQ.Client.*") - .SetSampler(new AlwaysOnSampler()) + .SetTailSampler() .AddAspNetCoreInstrumentation() .AddConsoleExporter() .AddOtlpExporter(options => @@ -169,7 +174,9 @@ private void ConfigureObservability(IServiceCollection services) .WithMetrics(builder => builder .AddAspNetCoreInstrumentation() .AddConsoleExporter() + .AddPrometheusExporter() .AddOtlpExporter() + .AddBrighterInstrumentation() ); } diff --git a/samples/WebAPI/WebAPI_Dapper/SalutationAnalytics/Program.cs b/samples/WebAPI/WebAPI_Dapper/SalutationAnalytics/Program.cs index 3ffa60a81c..83c937a332 100644 --- a/samples/WebAPI/WebAPI_Dapper/SalutationAnalytics/Program.cs +++ b/samples/WebAPI/WebAPI_Dapper/SalutationAnalytics/Program.cs @@ -167,7 +167,7 @@ static void ConfigureObservability(IServiceCollection services) builder .AddBrighterInstrumentation() .AddSource("RabbitMQ.Client.*") - .SetSampler(new AlwaysOnSampler()) + .SetTailSampler() .AddAspNetCoreInstrumentation() .AddConsoleExporter() .AddOtlpExporter(options => diff --git a/src/Paramore.Brighter.Extensions.Diagnostics/BrighterTracerBuilderExtensions.cs b/src/Paramore.Brighter.Extensions.Diagnostics/BrighterTracerBuilderExtensions.cs index a06471a99f..6127e37731 100644 --- a/src/Paramore.Brighter.Extensions.Diagnostics/BrighterTracerBuilderExtensions.cs +++ b/src/Paramore.Brighter.Extensions.Diagnostics/BrighterTracerBuilderExtensions.cs @@ -17,9 +17,33 @@ public static TracerProviderBuilder AddBrighterInstrumentation(this TracerProvid builder.AddSource(brighterTracer.ActivitySource.Name); + builder.AddProcessor(); }); return builder; } - + + /// + /// Register a tail-based sampler delegating the sampling decision to any OpenTelemetry Sampler. + /// + /// + /// Examples: + /// + /// // Use a TraceIdRatioBasedSampler with 25% sampling rate + /// builder.SetTailSampler(new TraceIdRatioBasedSampler(0.25)); + /// + /// // Use default constructor of AlwaysOnSampler + /// builder.SetTailSampler<AlwaysOnSampler>(); + /// + /// + /// The TracerProviderBuilder to configure + /// Optional sampler instance. If null, will create new instance using default constructor + /// Type of sampler to use + /// The TracerProviderBuilder for chaining + public static TracerProviderBuilder SetTailSampler(this TracerProviderBuilder builder, TSampler sampler = null) + where TSampler : Sampler, new() + { + builder.AddProcessor(new TailSamplerProcessor(sampler ?? new TSampler())); + return builder; + } } diff --git a/src/Paramore.Brighter/Observability/BrighterMetricsFromTracesProcessor.cs b/src/Paramore.Brighter/Observability/BrighterMetricsFromTracesProcessor.cs new file mode 100644 index 0000000000..9a0c1dad0a --- /dev/null +++ b/src/Paramore.Brighter/Observability/BrighterMetricsFromTracesProcessor.cs @@ -0,0 +1,85 @@ +#region Licence + +/* The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the “Software”), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. */ + +#endregion + +using System.Diagnostics; +using OpenTelemetry; + +namespace Paramore.Brighter.Observability; + +/// +/// Generates metrics from traces following OpenTelemetry Semantic Conventions 1.29.0 +/// Unstable due to depending on experimental parts of the OpenTelemetry spec +/// +public sealed class BrighterMetricsFromTracesProcessor( + IAmABrighterTracer brighterTracer, + IAmABrighterDbMeter dbMeter, + IAmABrighterMessagingMeter messagingMeter) + : BaseProcessor +{ + private readonly string _brighterActivitySourceName = brighterTracer.ActivitySource.Name; + + private bool Enabled => dbMeter.Enabled || messagingMeter.Enabled; + + public override void OnEnd(Activity? activity) + { + if (!Enabled) return; + + if (activity == null) return; + + if (!activity.Source.Name.Equals(_brighterActivitySourceName)) return; + + if (activity.GetTagItem(BrighterSemanticConventions.InstrumentationDomain) is not string instrumentationDomain) return; + + switch (instrumentationDomain) + { + case BrighterSemanticConventions.MessagingInstrumentationDomain: + if (activity.GetTagItem(BrighterSemanticConventions.MessagingOperationType) is string operation) + { + switch (operation) + { + case "publish": + messagingMeter.RecordClientOperation(activity); + messagingMeter.AddClientSentMessage(activity); + break; + case "receive": + messagingMeter.RecordClientOperation(activity); + messagingMeter.AddClientConsumedMessage(activity); + break; + case "process": + messagingMeter.RecordProcess(activity); + break; + default: + messagingMeter.RecordClientOperation(activity); + break; + } + } + break; + case BrighterSemanticConventions.DbInstrumentationDomain: + dbMeter.RecordClientOperation(activity); + break; + } + + base.OnEnd(activity); + } +} diff --git a/src/Paramore.Brighter/Observability/BrighterSemanticConventions.cs b/src/Paramore.Brighter/Observability/BrighterSemanticConventions.cs index 306e41d2e6..0256c4ff60 100644 --- a/src/Paramore.Brighter/Observability/BrighterSemanticConventions.cs +++ b/src/Paramore.Brighter/Observability/BrighterSemanticConventions.cs @@ -35,10 +35,18 @@ public static class BrighterSemanticConventions public const string CeMessageId = "cloudevents.event_id"; public const string CeVersion = "cloudevents.event_spec_version"; public const string ClearMessages = "paramore.brighter.clear_messages"; + public const string ConsumerGroupName = "messaging.consumer.group.name"; public const string ConversationId = "messaging.message.conversation_id"; + public const string DbCollectionName = "db.collection.name"; public const string DbInstanceId = "db.instance.id"; + public const string DbInstrumentationDomain = "db"; public const string DbName = "db.name"; + public const string DbNamespace = "db.namespace"; public const string DbOperation = "db.operation"; + public const string DbOperationName = "db.operation.name"; + public const string DbQuerySummary = "db.query.summary"; + public const string DbQueryText = "db.query.text"; + public const string DbResponseStatusCode = "db.response.status_code"; public const string DbStatement = "db.statement"; public const string DbSystem = "db.system"; public const string DbTable = "db.table"; @@ -47,6 +55,7 @@ public static class BrighterSemanticConventions public const string HandledCount = "paramore.brighter.handled_count"; public const string HandlerName = "paramore.brighter.handler.name"; public const string HandlerType = "paramore.brighter.handler.type"; + public const string InstrumentationDomain = "instrumentation.domain"; public const string IsSink = "paramore.brighter.is_sink"; public const string MapperName = "paramore.brighter.mapper.name"; public const string MapperType = "paramore.brighter.mapper.type"; @@ -57,9 +66,14 @@ public static class BrighterSemanticConventions public const string MessagingDestination = "messaging.destination.name"; public const string MessagingDestinationAnonymous = "messaging.destination.anonymous"; public const string MessagingDestinationPartitionId = "messaging.destination.partition.id"; + public const string MessagingDestinationSubscriptionName = "messaging.destination.subscription.name"; + public const string MessagingDestinationTemplate = "messaging.destination.template"; + public const string MessagingInstrumentationDomain = "messaging"; + public const string MessagingOperationName = "messaging.operation.name"; public const string MessagingOperationType = "messaging.operation.type"; public const string MessagingSystem = "messaging.system"; public const string MessageBodySize = "messaging.message.body.size"; + public const string MeterName = "Paramore.Brighter"; public const string NetworkPeerAddress = "network.peer.address"; public const string NetworkPeerPort = "network.peer.port"; public const string Operation = "paramore.brighter.operation"; @@ -70,7 +84,11 @@ public static class BrighterSemanticConventions public const string RequestType = "paramore.brighter.request.type"; public const string RequestBody = "paramore.brighter.request.body"; public const string ServerAddress = "server.address"; - public const string ServerPort ="server.port"; + public const string ServerPort = "server.port"; + public const string ServiceInstanceId = "service.instance.id"; + public const string ServiceName = "service.name"; + public const string ServiceNamespace = "service.namespace"; + public const string ServiceVersion = "service.version"; public const string SourceName = "Paramore.Brighter"; public const string CeSubject = "cloudevents.event_subject"; public const string CeType = "cloudevents.event_type"; diff --git a/src/Paramore.Brighter/Observability/BrighterTracer.cs b/src/Paramore.Brighter/Observability/BrighterTracer.cs index d21424b8f0..7834016e01 100644 --- a/src/Paramore.Brighter/Observability/BrighterTracer.cs +++ b/src/Paramore.Brighter/Observability/BrighterTracer.cs @@ -115,10 +115,12 @@ public void AddExceptionToSpan(Activity? span, IEnumerable exceptions var tags = new ActivityTagsCollection { + { BrighterSemanticConventions.InstrumentationDomain, BrighterSemanticConventions.MessagingInstrumentationDomain }, + { BrighterSemanticConventions.MessagingOperationType, operation.ToSpanName() }, + { BrighterSemanticConventions.Operation, operation.ToSpanName() }, { BrighterSemanticConventions.RequestId, request.Id }, { BrighterSemanticConventions.RequestType, request.GetType().Name }, - { BrighterSemanticConventions.RequestBody, JsonSerializer.Serialize(request) }, - { BrighterSemanticConventions.Operation, operation.ToSpanName() } + { BrighterSemanticConventions.RequestBody, JsonSerializer.Serialize(request) } }; var activity = ActivitySource.StartActivity( @@ -156,6 +158,7 @@ public void AddExceptionToSpan(Activity? span, IEnumerable exceptions var tags = new ActivityTagsCollection() { + { BrighterSemanticConventions.InstrumentationDomain, BrighterSemanticConventions.MessagingInstrumentationDomain }, { BrighterSemanticConventions.MessagingOperationType, operation.ToSpanName() }, { BrighterSemanticConventions.MessagingDestination, message.Header.Topic }, { BrighterSemanticConventions.MessagingDestinationPartitionId, message.Header.PartitionKey }, @@ -173,7 +176,6 @@ public void AddExceptionToSpan(Activity? span, IEnumerable exceptions { BrighterSemanticConventions.CeType, message.Header.Type}, { BrighterSemanticConventions.ReplyTo, message.Header.ReplyTo }, { BrighterSemanticConventions.HandledCount, message.Header.HandledCount } - }; var activity = ActivitySource.StartActivity( @@ -214,6 +216,8 @@ public void AddExceptionToSpan(Activity? span, IEnumerable exceptions var tags = new ActivityTagsCollection { + { BrighterSemanticConventions.InstrumentationDomain, BrighterSemanticConventions.MessagingInstrumentationDomain }, + { BrighterSemanticConventions.MessagingOperationType, operation.ToSpanName() }, { BrighterSemanticConventions.RequestType, requestType.Name }, { BrighterSemanticConventions.Operation, operation.ToSpanName() } }; @@ -254,6 +258,8 @@ public void AddExceptionToSpan(Activity? span, IEnumerable exceptions var tags = new ActivityTagsCollection() { + { BrighterSemanticConventions.InstrumentationDomain, BrighterSemanticConventions.MessagingInstrumentationDomain }, + { BrighterSemanticConventions.MessagingOperationType, operation.ToSpanName() }, { BrighterSemanticConventions.MessagingSystem, messagingSystem.ToMessagingSystemName() }, { BrighterSemanticConventions.MessagingDestination, topic }, { BrighterSemanticConventions.Operation, operation.ToSpanName() } @@ -290,6 +296,7 @@ public void AddExceptionToSpan(Activity? span, IEnumerable exceptions var tags = new ActivityTagsCollection() { + { BrighterSemanticConventions.InstrumentationDomain, BrighterSemanticConventions.MessagingInstrumentationDomain }, { BrighterSemanticConventions.MessagingOperationType, operation.ToSpanName() }, { BrighterSemanticConventions.MessagingSystem, messagingSystem.ToMessagingSystemName() }, { BrighterSemanticConventions.MessagingDestination, topic }, @@ -332,6 +339,8 @@ public void AddExceptionToSpan(Activity? span, IEnumerable exceptions var tags = new ActivityTagsCollection() { + { BrighterSemanticConventions.InstrumentationDomain, BrighterSemanticConventions.MessagingInstrumentationDomain }, + { BrighterSemanticConventions.MessagingOperationType, operation.ToSpanName() }, { BrighterSemanticConventions.Operation, operation.ToSpanName() }, { BrighterSemanticConventions.ArchiveAge, dispatchedSince.TotalMilliseconds } }; @@ -369,6 +378,8 @@ public void AddExceptionToSpan(Activity? span, IEnumerable exceptions var tags = new ActivityTagsCollection { + { BrighterSemanticConventions.InstrumentationDomain, BrighterSemanticConventions.MessagingInstrumentationDomain }, + { BrighterSemanticConventions.MessagingOperationType, operation.ToSpanName() }, { BrighterSemanticConventions.Operation, CommandProcessorSpanOperation.Clear.ToSpanName() } }; @@ -405,8 +416,9 @@ public void AddExceptionToSpan(Activity? span, IEnumerable exceptions var tags = new ActivityTagsCollection { - { BrighterSemanticConventions.DbName, info.dbName }, + { BrighterSemanticConventions.InstrumentationDomain, BrighterSemanticConventions.DbInstrumentationDomain }, { BrighterSemanticConventions.DbOperation, info.dbOperation.ToSpanName() }, + { BrighterSemanticConventions.DbName, info.dbName }, { BrighterSemanticConventions.DbTable, info.dbTable }, { BrighterSemanticConventions.DbSystem, info.dbSystem.ToDbName() } }; @@ -458,6 +470,8 @@ public void AddExceptionToSpan(Activity? span, IEnumerable exceptions var tags = new ActivityTagsCollection { + { BrighterSemanticConventions.InstrumentationDomain, BrighterSemanticConventions.MessagingInstrumentationDomain }, + //OTel specification attributes { BrighterSemanticConventions.MessagingOperationType, CommandProcessorSpanOperation.Publish.ToSpanName() }, diff --git a/src/Paramore.Brighter/Observability/DbMeter.cs b/src/Paramore.Brighter/Observability/DbMeter.cs new file mode 100644 index 0000000000..8aee6babec --- /dev/null +++ b/src/Paramore.Brighter/Observability/DbMeter.cs @@ -0,0 +1,85 @@ +#region Licence + +/* The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. */ + +#endregion + +using System.Collections.Generic; +#if NET8_0_OR_GREATER +using System.Collections.Frozen; +#endif +using System.Diagnostics; +using System.Diagnostics.Metrics; +using OpenTelemetry.Metrics; + +namespace Paramore.Brighter.Observability; + +/// +/// Meter for generating db metrics from traces following OpenTelemetry Semantic Conventions 1.29.0 +/// Unstable due to depending on experimental parts of the OpenTelemetry spec +/// +public sealed class DbMeter( + IMeterFactory meterFactory, + MeterProvider meterProvider) + : IAmABrighterDbMeter +{ + private readonly KeyValuePair[] _serviceAttributes = meterProvider.GetServiceAttributes(); + + private readonly Histogram _clientOperationDurationHistogram = meterFactory + .Create(BrighterSemanticConventions.MeterName) + .CreateHistogram( + name: "db.client.operation.duration", + description: "Duration of database client operations.", + unit: "s"); + +#if NET8_0_OR_GREATER + private static readonly FrozenSet s_clientOperationDurationHistogramAllowedTags = new[] +#else + private static readonly HashSet s_clientOperationDurationHistogramAllowedTags = new() +#endif + { + BrighterSemanticConventions.DbSystem, + BrighterSemanticConventions.DbCollectionName, + BrighterSemanticConventions.DbNamespace, + BrighterSemanticConventions.DbOperationName, + BrighterSemanticConventions.DbResponseStatusCode, + BrighterSemanticConventions.ErrorType, + BrighterSemanticConventions.ServerPort, + BrighterSemanticConventions.DbQuerySummary, + BrighterSemanticConventions.NetworkPeerAddress, + BrighterSemanticConventions.NetworkPeerPort, + BrighterSemanticConventions.ServerAddress, + BrighterSemanticConventions.DbQueryText +#if NET8_0_OR_GREATER + }.ToFrozenSet(); +#else + }; +#endif + + public void RecordClientOperation(Activity activity) + { + _clientOperationDurationHistogram.Record( + activity.Duration.TotalSeconds, + [..activity.TagObjects.Filter(s_clientOperationDurationHistogramAllowedTags), .._serviceAttributes]); + } + + public bool Enabled => _clientOperationDurationHistogram.Enabled; +} diff --git a/src/Paramore.Brighter/Observability/IAmABrighterDbMeter.cs b/src/Paramore.Brighter/Observability/IAmABrighterDbMeter.cs new file mode 100644 index 0000000000..f9f71c4b39 --- /dev/null +++ b/src/Paramore.Brighter/Observability/IAmABrighterDbMeter.cs @@ -0,0 +1,42 @@ +#region Licence + +/* The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the “Software”), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. */ + +#endregion + +using System.Diagnostics; + +namespace Paramore.Brighter.Observability; + +public interface IAmABrighterDbMeter +{ + /// + /// Record duration of database client operations. + /// + /// Activity to record + void RecordClientOperation(Activity activity); + + /// + /// Checks if any of the instrument members has any listeners + /// For example, this will be false if the associated meters are registered + /// + bool Enabled { get; } +} \ No newline at end of file diff --git a/src/Paramore.Brighter/Observability/IAmABrighterMessagingMeter.cs b/src/Paramore.Brighter/Observability/IAmABrighterMessagingMeter.cs new file mode 100644 index 0000000000..01c2f13d15 --- /dev/null +++ b/src/Paramore.Brighter/Observability/IAmABrighterMessagingMeter.cs @@ -0,0 +1,61 @@ +#region Licence + +/* The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the “Software”), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. */ + +#endregion + +using System.Diagnostics; + +namespace Paramore.Brighter.Observability; + +public interface IAmABrighterMessagingMeter +{ + /// + /// Record duration of messaging operation initiated by a producer or consumer client. + /// SHOULD NOT be used to report processing duration - processing duration is reported in RecordProcess + /// + /// Activity to record + void RecordClientOperation(Activity activity); + + /// + /// Add number of messages producer attempted to send to the broker. + /// + /// Activity to add + void AddClientSentMessage(Activity activity); + + /// + /// Add number of messages that were delivered to the application. + /// + /// Activity to add + void AddClientConsumedMessage(Activity activity); + + /// + /// Record duration of processing operation. + /// + /// Activity to record + void RecordProcess(Activity activity); + + /// + /// Checks if any of the instrument members has any listeners + /// For example, this will be false if the associated meters are registered + /// + bool Enabled { get; } +} \ No newline at end of file diff --git a/src/Paramore.Brighter/Observability/MessagingMeter.cs b/src/Paramore.Brighter/Observability/MessagingMeter.cs new file mode 100644 index 0000000000..e9396643ff --- /dev/null +++ b/src/Paramore.Brighter/Observability/MessagingMeter.cs @@ -0,0 +1,190 @@ +#region Licence + +/* The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. */ + +#endregion + +using System.Collections.Generic; +#if NET8_0_OR_GREATER +using System.Collections.Frozen; +#endif +using System.Diagnostics; +using System.Diagnostics.Metrics; +using OpenTelemetry.Metrics; + +namespace Paramore.Brighter.Observability; + +/// +/// Meter for generating messaging metrics from traces following OpenTelemetry Semantic Conventions 1.29.0 +/// Unstable due to depending on experimental parts of the OpenTelemetry spec +/// +public sealed class MessagingMeter( + IMeterFactory meterFactory, + MeterProvider meterProvider) + : IAmABrighterMessagingMeter +{ + private readonly KeyValuePair[] _serviceAttributes = meterProvider.GetServiceAttributes(); + + private readonly Histogram _clientOperationDurationHistogram = meterFactory + .Create(BrighterSemanticConventions.MeterName) + .CreateHistogram( + name: "messaging.client.operation.duration", + description: "Duration of messaging operation initiated by a producer or consumer client.", + unit: "s"); + + private readonly Counter _sentMessagesCounter = meterFactory + .Create(BrighterSemanticConventions.MeterName) + .CreateCounter( + name: "messaging.client.sent.messages", + description: "Number of messages producer attempted to send to the broker.", + unit: "{message}"); + + private readonly Counter _consumedMessagesCounter = meterFactory + .Create(BrighterSemanticConventions.MeterName) + .CreateCounter( + name: "messaging.client.consumed.messages", + description: "Number of messages that were delivered to the application.", + unit: "{message}"); + + private readonly Histogram _processedMessagesHistogram = meterFactory + .Create(BrighterSemanticConventions.MeterName) + .CreateHistogram( + name: "messaging.process.duration", + description: "Duration of processing operation.", + unit: "s"); + +#if NET8_0_OR_GREATER + private static readonly FrozenSet s_clientOperationDurationHistogramAllowedTags = new[] +#else + private static readonly HashSet s_clientOperationDurationHistogramAllowedTags = new() +#endif + { + BrighterSemanticConventions.MessagingOperationName, + BrighterSemanticConventions.MessagingSystem, + BrighterSemanticConventions.ErrorType, + BrighterSemanticConventions.ConsumerGroupName, + BrighterSemanticConventions.MessagingDestination, + BrighterSemanticConventions.MessagingDestinationSubscriptionName, + BrighterSemanticConventions.MessagingDestinationTemplate, + BrighterSemanticConventions.MessagingOperationType, + BrighterSemanticConventions.ServerAddress, + BrighterSemanticConventions.MessagingDestinationPartitionId, + BrighterSemanticConventions.ServerPort +#if NET8_0_OR_GREATER + }.ToFrozenSet(); +#else + }; +#endif + +#if NET8_0_OR_GREATER + private static readonly FrozenSet s_sentMessagesCounterAllowedTags = new[] +#else + private static readonly HashSet s_sentMessagesCounterAllowedTags = new() +#endif + { + BrighterSemanticConventions.MessagingOperationName, + BrighterSemanticConventions.MessagingSystem, + BrighterSemanticConventions.ErrorType, + BrighterSemanticConventions.MessagingDestination, + BrighterSemanticConventions.MessagingDestinationTemplate, + BrighterSemanticConventions.ServerAddress, + BrighterSemanticConventions.MessagingDestinationPartitionId, + BrighterSemanticConventions.ServerPort +#if NET8_0_OR_GREATER + }.ToFrozenSet(); +#else + }; +#endif + +#if NET8_0_OR_GREATER + private static readonly FrozenSet s_consumedMessagesCounterAllowedTags = new[] +#else + private static readonly HashSet s_consumedMessagesCounterAllowedTags = new() +#endif + { + BrighterSemanticConventions.MessagingOperationName, + BrighterSemanticConventions.MessagingSystem, + BrighterSemanticConventions.ErrorType, + BrighterSemanticConventions.ConsumerGroupName, + BrighterSemanticConventions.MessagingDestination, + BrighterSemanticConventions.MessagingDestinationSubscriptionName, + BrighterSemanticConventions.MessagingDestinationTemplate, + BrighterSemanticConventions.ServerAddress, + BrighterSemanticConventions.MessagingDestinationPartitionId, + BrighterSemanticConventions.ServerPort +#if NET8_0_OR_GREATER + }.ToFrozenSet(); +#else + }; +#endif + +#if NET8_0_OR_GREATER + private static readonly FrozenSet s_processedMessagesHistogramAllowedTags = new[] +#else + private static readonly HashSet s_processedMessagesHistogramAllowedTags = new() +#endif + { + BrighterSemanticConventions.MessagingOperationName, + BrighterSemanticConventions.MessagingSystem, + BrighterSemanticConventions.ErrorType, + BrighterSemanticConventions.ConsumerGroupName, + BrighterSemanticConventions.MessagingDestination, + BrighterSemanticConventions.MessagingDestinationSubscriptionName, + BrighterSemanticConventions.MessagingDestinationTemplate, + BrighterSemanticConventions.ServerAddress, + BrighterSemanticConventions.MessagingDestinationPartitionId, + BrighterSemanticConventions.ServerPort +#if NET8_0_OR_GREATER + }.ToFrozenSet(); +#else + }; +#endif + + public void RecordClientOperation(Activity activity) + { + _clientOperationDurationHistogram.Record( + activity.Duration.TotalSeconds, + [..activity.TagObjects.Filter(s_clientOperationDurationHistogramAllowedTags), .._serviceAttributes]); + } + + public void AddClientSentMessage(Activity activity) + { + _sentMessagesCounter.Add(1, [..activity.TagObjects.Filter(s_sentMessagesCounterAllowedTags), .._serviceAttributes]); + } + + public void AddClientConsumedMessage(Activity activity) + { + _consumedMessagesCounter.Add(1, [..activity.TagObjects.Filter(s_consumedMessagesCounterAllowedTags), .._serviceAttributes]); + } + + public void RecordProcess(Activity activity) + { + _processedMessagesHistogram.Record( + activity.Duration.TotalSeconds, + [..activity.TagObjects.Filter(s_processedMessagesHistogramAllowedTags), .._serviceAttributes]); + } + + public bool Enabled => + _clientOperationDurationHistogram.Enabled || + _sentMessagesCounter.Enabled || + _consumedMessagesCounter.Enabled || + _processedMessagesHistogram.Enabled; +} diff --git a/src/Paramore.Brighter/Observability/MeterProviderExtensions.cs b/src/Paramore.Brighter/Observability/MeterProviderExtensions.cs new file mode 100644 index 0000000000..33ad08f66b --- /dev/null +++ b/src/Paramore.Brighter/Observability/MeterProviderExtensions.cs @@ -0,0 +1,46 @@ +#region Licence + +/* The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the “Software”), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. */ + +#endregion + +using System.Collections.Generic; +using System.Linq; +using OpenTelemetry; + +namespace Paramore.Brighter.Observability; + +internal static class MeterProviderExtensions +{ + /// + /// Service level attributes used to enrich tags from the activity + /// + internal static KeyValuePair[] GetServiceAttributes(this OpenTelemetry.Metrics.MeterProvider meterProvider) + { + return meterProvider.GetResource().Attributes + .Where(a => a.Key == BrighterSemanticConventions.ServiceName || + a.Key == BrighterSemanticConventions.ServiceVersion || + a.Key == BrighterSemanticConventions.ServiceInstanceId || + a.Key == BrighterSemanticConventions.ServiceNamespace) + .Cast>() + .ToArray(); + } +} \ No newline at end of file diff --git a/src/Paramore.Brighter/Observability/TagObjectsExtensions.cs b/src/Paramore.Brighter/Observability/TagObjectsExtensions.cs new file mode 100644 index 0000000000..5d53b258fa --- /dev/null +++ b/src/Paramore.Brighter/Observability/TagObjectsExtensions.cs @@ -0,0 +1,69 @@ +#region Licence + +/* The MIT License (MIT) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the “Software”), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. */ + +#endregion + +#if NET8_0_OR_GREATER +using System.Collections.Frozen; +#endif +using System; +using System.Collections.Generic; + +namespace Paramore.Brighter.Observability; + +internal static class TagObjectsExtensions +{ + /// + /// Avoids LINQ overhead when filtering activity tags + /// + /// Tags to be filtered + /// Allowed tags to filter for + /// + internal static KeyValuePair[] Filter( + this IEnumerable> tags, +#if NET8_0_OR_GREATER + FrozenSet allowedTags) +#else + HashSet allowedTags) +#endif + { + var buffer = new KeyValuePair[allowedTags.Count]; + var insertIndex = 0; + + foreach (var tag in tags) + { + if (allowedTags.Contains(tag.Key)) + { + buffer[insertIndex++] = tag; + } + + if (insertIndex == allowedTags.Count) + { + return buffer; + } + } + + var filtered = new KeyValuePair[insertIndex]; + Array.Copy(buffer, filtered, insertIndex); + return filtered; + } +} \ No newline at end of file diff --git a/src/Paramore.Brighter/Observability/TailSamplerProcessor.cs b/src/Paramore.Brighter/Observability/TailSamplerProcessor.cs new file mode 100644 index 0000000000..8a645c7d46 --- /dev/null +++ b/src/Paramore.Brighter/Observability/TailSamplerProcessor.cs @@ -0,0 +1,41 @@ +using System; +using System.Diagnostics; +using OpenTelemetry; +using OpenTelemetry.Trace; + +namespace Paramore.Brighter.Observability; + +/// +/// A processor that delegates sampling decisions to an OpenTelemetry Sampler. +/// This allows for using sampling logic after the span is completed. +/// Provided to ease adoption of BrighterMetricsFromTracesProcessor +/// +public sealed class TailSamplerProcessor(Sampler sampler) + : BaseProcessor +{ + private readonly Sampler _sampler = sampler ?? throw new ArgumentNullException(nameof(sampler)); + + public override void OnEnd(Activity? activity) + { + if (activity == null) return; + + var samplingParameters = new SamplingParameters( + parentContext: activity.Parent?.Context ?? default, + traceId: activity.TraceId, + name: activity.OperationName, + kind: activity.Kind, + tags: activity.TagObjects, + links: activity.Links); + + var result = _sampler.ShouldSample(samplingParameters); + + if (result.Decision is not SamplingDecision.RecordAndSample) + { + // exporters check this value to determine if the span should be exported + activity.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded; + activity.IsAllDataRequested = false; + } + + base.OnEnd(activity); + } +} \ No newline at end of file From 6384a5e5fb1bf55a49b73ae5a9fd6d5829c10518 Mon Sep 17 00:00:00 2001 From: Tim Salva Date: Fri, 3 Jan 2025 13:53:20 +0000 Subject: [PATCH 2/3] Minor fixes --- .../WebAPI_Dapper/GreetingsWeb/Startup.cs | 1 - .../BrighterMetricsBuilderExtensions.cs | 21 +++++++++++++++++ .../Observability/IAmABrighterDbMeter.cs | 2 +- .../IAmABrighterMessagingMeter.cs | 2 +- .../Observability/TailSamplerProcessor.cs | 23 ++++++++++++++++++- 5 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 src/Paramore.Brighter.Extensions.Diagnostics/BrighterMetricsBuilderExtensions.cs diff --git a/samples/WebAPI/WebAPI_Dapper/GreetingsWeb/Startup.cs b/samples/WebAPI/WebAPI_Dapper/GreetingsWeb/Startup.cs index 2eaaef0502..e1609aac7f 100644 --- a/samples/WebAPI/WebAPI_Dapper/GreetingsWeb/Startup.cs +++ b/samples/WebAPI/WebAPI_Dapper/GreetingsWeb/Startup.cs @@ -18,7 +18,6 @@ using Paramore.Brighter; using Paramore.Brighter.Extensions.DependencyInjection; using Paramore.Brighter.Extensions.Diagnostics; -using Paramore.Brighter.Extensions.Diagnostics.obj; using Paramore.Brighter.Observability; using Paramore.Darker.AspNetCore; using Paramore.Darker.Policies; diff --git a/src/Paramore.Brighter.Extensions.Diagnostics/BrighterMetricsBuilderExtensions.cs b/src/Paramore.Brighter.Extensions.Diagnostics/BrighterMetricsBuilderExtensions.cs new file mode 100644 index 0000000000..d1384f2054 --- /dev/null +++ b/src/Paramore.Brighter.Extensions.Diagnostics/BrighterMetricsBuilderExtensions.cs @@ -0,0 +1,21 @@ +using Microsoft.Extensions.DependencyInjection.Extensions; +using OpenTelemetry.Metrics; +using Paramore.Brighter.Observability; + +namespace Paramore.Brighter.Extensions.Diagnostics; + +public static class BrighterMetricsBuilderExtensions +{ + public static MeterProviderBuilder AddBrighterInstrumentation(this MeterProviderBuilder builder) + { + builder.ConfigureServices(services => + { + services.TryAddSingleton(); + services.TryAddSingleton(); + + builder.AddMeter(BrighterSemanticConventions.MeterName); + }); + + return builder; + } +} \ No newline at end of file diff --git a/src/Paramore.Brighter/Observability/IAmABrighterDbMeter.cs b/src/Paramore.Brighter/Observability/IAmABrighterDbMeter.cs index f9f71c4b39..82df549564 100644 --- a/src/Paramore.Brighter/Observability/IAmABrighterDbMeter.cs +++ b/src/Paramore.Brighter/Observability/IAmABrighterDbMeter.cs @@ -36,7 +36,7 @@ public interface IAmABrighterDbMeter /// /// Checks if any of the instrument members has any listeners - /// For example, this will be false if the associated meters are registered + /// For example, this will be false if the associated meters are not registered /// bool Enabled { get; } } \ No newline at end of file diff --git a/src/Paramore.Brighter/Observability/IAmABrighterMessagingMeter.cs b/src/Paramore.Brighter/Observability/IAmABrighterMessagingMeter.cs index 01c2f13d15..ba71f6622d 100644 --- a/src/Paramore.Brighter/Observability/IAmABrighterMessagingMeter.cs +++ b/src/Paramore.Brighter/Observability/IAmABrighterMessagingMeter.cs @@ -55,7 +55,7 @@ public interface IAmABrighterMessagingMeter /// /// Checks if any of the instrument members has any listeners - /// For example, this will be false if the associated meters are registered + /// For example, this will be false if the associated meters are not registered /// bool Enabled { get; } } \ No newline at end of file diff --git a/src/Paramore.Brighter/Observability/TailSamplerProcessor.cs b/src/Paramore.Brighter/Observability/TailSamplerProcessor.cs index 8a645c7d46..0124723361 100644 --- a/src/Paramore.Brighter/Observability/TailSamplerProcessor.cs +++ b/src/Paramore.Brighter/Observability/TailSamplerProcessor.cs @@ -1,3 +1,24 @@ +#region Licence + +/* The MIT License (MIT) +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. */ + +#endregion + using System; using System.Diagnostics; using OpenTelemetry; @@ -22,7 +43,7 @@ public override void OnEnd(Activity? activity) var samplingParameters = new SamplingParameters( parentContext: activity.Parent?.Context ?? default, traceId: activity.TraceId, - name: activity.OperationName, + name: activity.DisplayName, kind: activity.Kind, tags: activity.TagObjects, links: activity.Links); From 913d66f7689fd2596d28e373f5d74fd8c2fbfc32 Mon Sep 17 00:00:00 2001 From: Tim Salva Date: Fri, 3 Jan 2025 16:25:39 +0000 Subject: [PATCH 3/3] Add name to new files --- .../BrighterMetricsBuilderExtensions.cs | 25 +++++++++++++++++++ .../BrighterMetricsFromTracesProcessor.cs | 7 +++--- .../Observability/DbMeter.cs | 1 + .../Observability/IAmABrighterDbMeter.cs | 5 ++-- .../IAmABrighterMessagingMeter.cs | 5 ++-- .../Observability/MessagingMeter.cs | 1 + .../Observability/MeterProviderExtensions.cs | 5 ++-- .../Observability/TagObjectsExtensions.cs | 5 ++-- .../Observability/TailSamplerProcessor.cs | 2 ++ 9 files changed, 45 insertions(+), 11 deletions(-) diff --git a/src/Paramore.Brighter.Extensions.Diagnostics/BrighterMetricsBuilderExtensions.cs b/src/Paramore.Brighter.Extensions.Diagnostics/BrighterMetricsBuilderExtensions.cs index d1384f2054..8f4a13993a 100644 --- a/src/Paramore.Brighter.Extensions.Diagnostics/BrighterMetricsBuilderExtensions.cs +++ b/src/Paramore.Brighter.Extensions.Diagnostics/BrighterMetricsBuilderExtensions.cs @@ -1,3 +1,28 @@ +#region Licence + +/* The MIT License (MIT) +Copyright © 2025 Tim Salva + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. */ + +#endregion + using Microsoft.Extensions.DependencyInjection.Extensions; using OpenTelemetry.Metrics; using Paramore.Brighter.Observability; diff --git a/src/Paramore.Brighter/Observability/BrighterMetricsFromTracesProcessor.cs b/src/Paramore.Brighter/Observability/BrighterMetricsFromTracesProcessor.cs index 9a0c1dad0a..d98cfe1a1c 100644 --- a/src/Paramore.Brighter/Observability/BrighterMetricsFromTracesProcessor.cs +++ b/src/Paramore.Brighter/Observability/BrighterMetricsFromTracesProcessor.cs @@ -1,9 +1,10 @@ #region Licence /* The MIT License (MIT) - +Copyright © 2025 Tim Salva + Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the “Software”), to deal +of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is @@ -12,7 +13,7 @@ of this software and associated documentation files (the “Software”), to dea The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER diff --git a/src/Paramore.Brighter/Observability/DbMeter.cs b/src/Paramore.Brighter/Observability/DbMeter.cs index 8aee6babec..b2033b2257 100644 --- a/src/Paramore.Brighter/Observability/DbMeter.cs +++ b/src/Paramore.Brighter/Observability/DbMeter.cs @@ -1,6 +1,7 @@ #region Licence /* The MIT License (MIT) +Copyright © 2025 Tim Salva Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Paramore.Brighter/Observability/IAmABrighterDbMeter.cs b/src/Paramore.Brighter/Observability/IAmABrighterDbMeter.cs index 82df549564..c034541496 100644 --- a/src/Paramore.Brighter/Observability/IAmABrighterDbMeter.cs +++ b/src/Paramore.Brighter/Observability/IAmABrighterDbMeter.cs @@ -1,9 +1,10 @@ #region Licence /* The MIT License (MIT) +Copyright © 2025 Tim Salva Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the “Software”), to deal +of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is @@ -12,7 +13,7 @@ of this software and associated documentation files (the “Software”), to dea The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER diff --git a/src/Paramore.Brighter/Observability/IAmABrighterMessagingMeter.cs b/src/Paramore.Brighter/Observability/IAmABrighterMessagingMeter.cs index ba71f6622d..13bfed4f12 100644 --- a/src/Paramore.Brighter/Observability/IAmABrighterMessagingMeter.cs +++ b/src/Paramore.Brighter/Observability/IAmABrighterMessagingMeter.cs @@ -1,9 +1,10 @@ #region Licence /* The MIT License (MIT) +Copyright © 2025 Tim Salva Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the “Software”), to deal +of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is @@ -12,7 +13,7 @@ of this software and associated documentation files (the “Software”), to dea The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER diff --git a/src/Paramore.Brighter/Observability/MessagingMeter.cs b/src/Paramore.Brighter/Observability/MessagingMeter.cs index e9396643ff..21f644e191 100644 --- a/src/Paramore.Brighter/Observability/MessagingMeter.cs +++ b/src/Paramore.Brighter/Observability/MessagingMeter.cs @@ -1,6 +1,7 @@ #region Licence /* The MIT License (MIT) +Copyright © 2025 Tim Salva Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/src/Paramore.Brighter/Observability/MeterProviderExtensions.cs b/src/Paramore.Brighter/Observability/MeterProviderExtensions.cs index 33ad08f66b..43b4648839 100644 --- a/src/Paramore.Brighter/Observability/MeterProviderExtensions.cs +++ b/src/Paramore.Brighter/Observability/MeterProviderExtensions.cs @@ -1,9 +1,10 @@ #region Licence /* The MIT License (MIT) +Copyright © 2025 Tim Salva Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the “Software”), to deal +of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is @@ -12,7 +13,7 @@ of this software and associated documentation files (the “Software”), to dea The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER diff --git a/src/Paramore.Brighter/Observability/TagObjectsExtensions.cs b/src/Paramore.Brighter/Observability/TagObjectsExtensions.cs index 5d53b258fa..37541413cc 100644 --- a/src/Paramore.Brighter/Observability/TagObjectsExtensions.cs +++ b/src/Paramore.Brighter/Observability/TagObjectsExtensions.cs @@ -1,9 +1,10 @@ #region Licence /* The MIT License (MIT) +Copyright © 2025 Tim Salva Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the “Software”), to deal +of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is @@ -12,7 +13,7 @@ of this software and associated documentation files (the “Software”), to dea The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER diff --git a/src/Paramore.Brighter/Observability/TailSamplerProcessor.cs b/src/Paramore.Brighter/Observability/TailSamplerProcessor.cs index 0124723361..d072554932 100644 --- a/src/Paramore.Brighter/Observability/TailSamplerProcessor.cs +++ b/src/Paramore.Brighter/Observability/TailSamplerProcessor.cs @@ -1,6 +1,8 @@ #region Licence /* The MIT License (MIT) +Copyright © 2025 Tim Salva + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights