Skip to content

Commit a7407be

Browse files
committed
2 parents 21de55a + 40e8bac commit a7407be

File tree

115 files changed

+524
-469
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

115 files changed

+524
-469
lines changed

CONTRIBUTING.md

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -203,13 +203,19 @@ Open a pull request against the main `opentelemetry-dotnet` repo.
203203
* If the PR is not ready for review, please mark it as
204204
[`draft`](https://github.blog/2019-02-14-introducing-draft-pull-requests/).
205205
* Make sure CLA is signed and all required CI checks are clear.
206-
* Submit small, focused PRs addressing a single
207-
concern/issue.
206+
* Submit small, focused PRs addressing a single concern/issue.
208207
* Make sure the PR title reflects the contribution.
209208
* Write a summary that helps understand the change.
210209
* Include usage examples in the summary, where applicable.
211210
* Include benchmarks (before/after) in the summary, for contributions that are
212211
performance enhancements.
212+
* We are open to bot generated PRs or AI/LLM assisted PRs. Actually, we are
213+
using
214+
[dependabot](https://docs.github.com/en/code-security/dependabot/dependabot-security-updates/configuring-dependabot-security-updates)
215+
to automate the security updates. However, if you use bots to generate spam
216+
PRs (e.g. incorrect, noisy, non-improvements, unintelligible, trying to sell
217+
your product, etc.), we might close the PR right away with a warning, and if
218+
you keep doing so, we might block your user account.
213219

214220
### How to get pull requests merged
215221

@@ -302,23 +308,6 @@ analysis](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/overview
302308
[Common.props](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/build/Common.props)
303309
new projects must NOT manually override these settings.
304310

305-
## New code
306-
307-
New code files MUST enable [nullable reference
308-
types](https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/nullable-reference-types)
309-
manually in projects where it is not automatically enabled project-wide. This is
310-
done by specifying `#nullable enable` towards the top of the file (usually after
311-
the copyright header). We are currently working towards enabling nullable
312-
context in every project by updating code as it is worked on, this requirement
313-
is to make sure the surface area of code needing updates is shrinking and not
314-
expanding.
315-
316-
> [!NOTE]
317-
> The first time a project is updated to use nullable context in public APIs
318-
some housekeeping needs to be done in public API definitions (`.publicApi`
319-
folder). This can be done automatically via a code fix offered by the public API
320-
analyzer.
321-
322311
## License requirements
323312

324313
OpenTelemetry .NET is licensed under the [Apache License, Version

Directory.Packages.props

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
55
<OTelLatestStableVer>1.9.0</OTelLatestStableVer>
66

7+
<!--
8+
This is typically the latest annual release of .NET. Use this wherever
9+
possible and only deviate (use a specific version) when a package has a
10+
more specific patch which must be reference directly.
11+
-->
12+
<LatestRuntimeOutOfBandVer>9.0.0-rc.1.24431.7</LatestRuntimeOutOfBandVer>
13+
714
<!-- Mitigate https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-43485. -->
815
<SystemTextEncodingsWebOutOfBandMinimumCoreAppVer>8.0.0</SystemTextEncodingsWebOutOfBandMinimumCoreAppVer>
916
<SystemTextJsonOutOfBandMinimumCoreAppVer>8.0.5</SystemTextJsonOutOfBandMinimumCoreAppVer>
@@ -15,12 +22,6 @@
1522
vulnerability in the NuGet packages that are published from this repository.
1623
-->
1724
<ItemGroup>
18-
<PackageVersion Include="Google.Protobuf" Version="[3.22.5,4.0)" />
19-
<PackageVersion Include="Grpc" Version="[2.44.0,3.0)" />
20-
<PackageVersion Include="Grpc.Net.Client" Version="[2.52.0,3.0)" />
21-
<PackageVersion Include="Microsoft.AspNetCore.Http.Abstractions" Version="[2.1.1,6.0)" />
22-
<PackageVersion Include="Microsoft.AspNetCore.Http.Features" Version="[2.1.1,6.0)" />
23-
2425
<!--
2526
Typically, for the Microsoft.Extensions.* packages relating to DI Abstractions, Hosting Abstractions, and Logging,
2627
the latest stable version should be used because:
@@ -30,16 +31,18 @@
3031
3) Since version 3.1.0, the .NET runtime team is holding a high bar for backward compatibility on
3132
these packages even during major version bumps, so compatibility is not a concern here.
3233
-->
34+
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="$(LatestRuntimeOutOfBandVer)" />
35+
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="$(LatestRuntimeOutOfBandVer)" />
36+
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="$(LatestRuntimeOutOfBandVer)" />
37+
<PackageVersion Include="Microsoft.Extensions.Diagnostics.Abstractions" Version="$(LatestRuntimeOutOfBandVer)" />
38+
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="$(LatestRuntimeOutOfBandVer)" />
39+
<PackageVersion Include="Microsoft.Extensions.Logging" Version="$(LatestRuntimeOutOfBandVer)" />
40+
<PackageVersion Include="Microsoft.Extensions.Logging.Configuration" Version="$(LatestRuntimeOutOfBandVer)" />
41+
<PackageVersion Include="Microsoft.Extensions.Options" Version="$(LatestRuntimeOutOfBandVer)" />
3342

34-
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="9.0.0-rc.1.24431.7" />
35-
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.0-rc.1.24431.7" />
36-
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.0-rc.1.24431.7" />
37-
<PackageVersion Include="Microsoft.Extensions.Diagnostics.Abstractions" Version="9.0.0-rc.1.24431.7" />
38-
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="9.0.0-rc.1.24431.7" />
39-
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.0-rc.1.24431.7" />
40-
<PackageVersion Include="Microsoft.Extensions.Logging.Configuration" Version="9.0.0-rc.1.24431.7" />
41-
<PackageVersion Include="Microsoft.Extensions.Options" Version="9.0.0-rc.1.24431.7" />
42-
43+
<!--
44+
OTel packages always point to latest stable release.
45+
-->
4346
<PackageVersion Include="OpenTelemetry" Version="[$(OTelLatestStableVer),2.0)" />
4447
<PackageVersion Include="OpenTelemetry.Api" Version="[$(OTelLatestStableVer),2.0)" />
4548
<PackageVersion Include="OpenTelemetry.Api.ProviderBuilderExtensions" Version="[$(OTelLatestStableVer),2.0)" />
@@ -50,14 +53,22 @@
5053

5154
<!--
5255
Typically, the latest stable version of System.Diagnostics.DiagnosticSource should be used here because:
53-
1) Each major version bump will have some new OpenTelemetry API capabilities (e.g. .NET 6 introduced Meter
54-
API, .NET 7 added UpDownCounter, .NET 8 is adding Meter/Instrument level attributes support, .NET 9 might
55-
add Advice/Hint API) that the OpenTelemetry components rely on.
56+
1) Each major version bump will likely have some new OpenTelemetry capabilities (e.g. .NET 6 introduced Meter
57+
API, .NET 7 added UpDownCounter, .NET 8 added Meter/Instrument level attributes support, .NET 9 added
58+
Advice/Hint API, etc.).
5659
2) Each minor version bump is normally security hotfixes or critical bug fixes.
5760
3) The .NET runtime team provides extra backward compatibility guarantee to System.Diagnostics.DiagnosticSource
5861
even during major version bumps, so compatibility is not a concern here.
5962
-->
60-
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="9.0.0-rc.1.24431.7" />
63+
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="$(LatestRuntimeOutOfBandVer)" />
64+
65+
<!--
66+
We use conservative versions of these packages where an upgrade might
67+
introduce breaking changes.
68+
-->
69+
<PackageVersion Include="Google.Protobuf" Version="[3.22.5,4.0)" />
70+
<PackageVersion Include="Grpc" Version="[2.44.0,3.0)" />
71+
<PackageVersion Include="Grpc.Net.Client" Version="[2.52.0,3.0)" />
6172
</ItemGroup>
6273

6374
<ItemGroup>
@@ -92,10 +103,10 @@
92103
<PackageVersion Include="Microsoft.CSharp" Version="[4.7.0]" />
93104
<PackageVersion Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="[3.11.0-beta1.23525.2]" />
94105
<PackageVersion Include="Microsoft.Coyote" Version="1.7.11" />
95-
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="[9.0.0-rc.1.24431.7,)" />
96-
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="[9.0.0-rc.1.24431.7,)" />
97-
<PackageVersion Include="Microsoft.Extensions.Http" Version="[9.0.0-rc.1.24431.7,)" />
98-
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="[9.0.0-rc.1.24431.7,)" />
106+
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="$(LatestRuntimeOutOfBandVer)" />
107+
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="$(LatestRuntimeOutOfBandVer)" />
108+
<PackageVersion Include="Microsoft.Extensions.Http" Version="$(LatestRuntimeOutOfBandVer)" />
109+
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="$(LatestRuntimeOutOfBandVer)" />
99110
<PackageVersion Include="Microsoft.Extensions.Telemetry.Abstractions" Version="[9.0.0-preview.8.24460.1,)" />
100111
<PackageVersion Include="Microsoft.NETFramework.ReferenceAssemblies" Version="[1.0.3,2.0)" />
101112
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="[17.11.0,18.0.0)" />

docs/logs/redaction/MyRedactionProcessor.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,33 +15,33 @@ public override void OnEnd(LogRecord logRecord)
1515
}
1616
}
1717

18-
internal sealed class MyClassWithRedactionEnumerator : IReadOnlyList<KeyValuePair<string, object>>
18+
internal sealed class MyClassWithRedactionEnumerator : IReadOnlyList<KeyValuePair<string, object?>>
1919
{
20-
private readonly IReadOnlyList<KeyValuePair<string, object>> state;
20+
private readonly IReadOnlyList<KeyValuePair<string, object?>> state;
2121

22-
public MyClassWithRedactionEnumerator(IReadOnlyList<KeyValuePair<string, object>> state)
22+
public MyClassWithRedactionEnumerator(IReadOnlyList<KeyValuePair<string, object?>> state)
2323
{
2424
this.state = state;
2525
}
2626

2727
public int Count => this.state.Count;
2828

29-
public KeyValuePair<string, object> this[int index]
29+
public KeyValuePair<string, object?> this[int index]
3030
{
3131
get
3232
{
3333
var item = this.state[index];
3434
var entryVal = item.Value?.ToString();
3535
if (entryVal != null && entryVal.Contains("<secret>"))
3636
{
37-
return new KeyValuePair<string, object>(item.Key, "newRedactedValueHere");
37+
return new KeyValuePair<string, object?>(item.Key, "newRedactedValueHere");
3838
}
3939

4040
return item;
4141
}
4242
}
4343

44-
public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
44+
public IEnumerator<KeyValuePair<string, object?>> GetEnumerator()
4545
{
4646
for (var i = 0; i < this.Count; i++)
4747
{

docs/logs/redaction/redaction.csproj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11
<Project Sdk="Microsoft.NET.Sdk">
2-
<PropertyGroup>
3-
<!-- this is temporary. will remove in future PR. -->
4-
<Nullable>disable</Nullable>
5-
</PropertyGroup>
62
<ItemGroup>
73
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Console\OpenTelemetry.Exporter.Console.csproj" />
84
</ItemGroup>

docs/metrics/customizing-the-sdk/Program.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ public static void Main()
4040
// Drop the instrument "MyCounterDrop".
4141
.AddView(instrumentName: "MyCounterDrop", MetricStreamConfiguration.Drop)
4242

43+
// Configure the Explicit Bucket Histogram aggregation with custom boundaries and new name.
44+
.AddView(instrumentName: "histogramWithMultipleAggregations", new ExplicitBucketHistogramConfiguration() { Boundaries = new double[] { 10, 20 }, Name = "MyHistogramWithExplicitHistogram" })
45+
46+
// Use Base2 Exponential Bucket Histogram aggregation and new name.
47+
.AddView(instrumentName: "histogramWithMultipleAggregations", new Base2ExponentialBucketHistogramConfiguration() { Name = "MyHistogramWithBase2ExponentialBucketHistogram" })
48+
4349
// An instrument which does not match any views
4450
// gets processed with default behavior. (SDK default)
4551
// Uncommenting the following line will
@@ -70,6 +76,12 @@ public static void Main()
7076
exponentialBucketHistogram.Record(random.Next(1, 1000), new("tag1", "value1"), new("tag2", "value2"));
7177
}
7278

79+
var histogramWithMultipleAggregations = Meter1.CreateHistogram<long>("histogramWithMultipleAggregations");
80+
for (int i = 0; i < 20000; i++)
81+
{
82+
histogramWithMultipleAggregations.Record(random.Next(1, 1000), new("tag1", "value1"), new("tag2", "value2"));
83+
}
84+
7385
var counterCustomTags = Meter1.CreateCounter<long>("MyCounterCustomTags");
7486
for (int i = 0; i < 20000; i++)
7587
{

docs/metrics/customizing-the-sdk/README.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,90 @@ within the maximum number of buckets defined by `MaxSize`. The default
245245
new Base2ExponentialBucketHistogramConfiguration { MaxSize = 40 })
246246
```
247247

248+
#### Produce multiple metrics from single instrument
249+
250+
When an instrument matches multiple views, it can generate multiple metrics. For
251+
instance, if an instrument is matched by two different view configurations, it
252+
will result in two separate metrics being produced from that single instrument.
253+
Below is an example demonstrating how to leverage this capability to create two
254+
independent metrics from a single instrument. In this example, a histogram
255+
instrument is used to report measurements, and views are configured to produce
256+
two metrics : one aggregated using `ExplicitBucketHistogramConfiguration` and the
257+
other using `Base2ExponentialBucketHistogramConfiguration`.
258+
259+
```csharp
260+
var histogramWithMultipleAggregations = meter.CreateHistogram<long>("HistogramWithMultipleAggregations");
261+
262+
// Configure the Explicit Bucket Histogram aggregation with custom boundaries and new name.
263+
.AddView(instrumentName: "HistogramWithMultipleAggregations", new ExplicitBucketHistogramConfiguration() { Boundaries = new double[] { 10, 20 }, Name = "MyHistogramWithExplicitHistogram" })
264+
265+
// Use Base2 Exponential Bucket Histogram aggregation and new name.
266+
.AddView(instrumentName: "HistogramWithMultipleAggregations", new Base2ExponentialBucketHistogramConfiguration() { Name = "MyHistogramWithBase2ExponentialBucketHistogram" })
267+
268+
// Both views rename the metric to avoid name conflicts. However, in this case,
269+
// renaming one would be sufficient.
270+
271+
// This measurement will be aggregated into two separate metrics.
272+
histogramWithMultipleAggregations.Record(10, new("tag1", "value1"), new("tag2", "value2"));
273+
```
274+
275+
When using views that produce multiple metrics from single instrument, it's
276+
crucial to rename the metric to prevent conflicts. In the event of conflict,
277+
OpenTelemetry will emit an internal warning but will still export both metrics.
278+
The impact of this behavior depends on the backend or receiver being used. You
279+
can refer to [OpenTelemetry's
280+
specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/data-model.md#opentelemetry-protocol-data-model-consumer-recommendations)
281+
for more details.
282+
283+
Below example is showing the *BAD* practice. DO NOT FOLLOW it.
284+
285+
```csharp
286+
var histogram = meter.CreateHistogram<long>("MyHistogram");
287+
288+
// Configure a view to aggregate based only on the "location" tag.
289+
.AddView(instrumentName: "MyHistogram", metricStreamConfiguration: new MetricStreamConfiguration
290+
{
291+
TagKeys = new string[] { "location" },
292+
})
293+
294+
// Configure another view to aggregate based only on the "status" tag.
295+
.AddView(instrumentName: "MyHistogram", metricStreamConfiguration: new MetricStreamConfiguration
296+
{
297+
TagKeys = new string[] { "status" },
298+
})
299+
300+
// The measurement below will be aggregated into two metric streams, but both will have the same name.
301+
// OpenTelemetry will issue a warning about this conflict and pass both streams to the exporter.
302+
// However, this may cause issues depending on the backend.
303+
histogram.Record(10, new("location", "seattle"), new("status", "OK"));
304+
```
305+
306+
The modified version, avoiding name conflict is shown below:
307+
308+
```csharp
309+
var histogram = meter.CreateHistogram<long>("MyHistogram");
310+
311+
// Configure a view to aggregate based only on the "location" tag,
312+
// and rename the metric.
313+
.AddView(instrumentName: "MyHistogram", metricStreamConfiguration: new MetricStreamConfiguration
314+
{
315+
Name = "MyHistogramWithLocation",
316+
TagKeys = new string[] { "location" },
317+
})
318+
319+
// Configure a view to aggregate based only on the "status" tag,
320+
// and rename the metric.
321+
.AddView(instrumentName: "MyHistogram", metricStreamConfiguration: new MetricStreamConfiguration
322+
{
323+
Name = "MyHistogramWithStatus",
324+
TagKeys = new string[] { "status" },
325+
})
326+
327+
// The measurement below will be aggregated into two separate metrics, "MyHistogramWithLocation"
328+
// and "MyHistogramWithStatus".
329+
histogram.Record(10, new("location", "seattle"), new("status", "OK"));
330+
```
331+
248332
> [!NOTE]
249333
> The SDK currently does not support any changes to `Aggregation` type
250334
by using Views.

docs/trace/customizing-the-sdk/customizing-the-sdk.csproj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11
<Project Sdk="Microsoft.NET.Sdk">
2-
<PropertyGroup>
3-
<!-- this is temporary. will remove in future PR. -->
4-
<Nullable>disable</Nullable>
5-
</PropertyGroup>
62
<ItemGroup>
73
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Exporter.Console\OpenTelemetry.Exporter.Console.csproj" />
84
</ItemGroup>

examples/Console/Examples.Console.csproj

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
<OutputType>Exe</OutputType>
55
<TargetFramework>$(DefaultTargetFrameworkForExampleApps)</TargetFramework>
66
<NoWarn>$(NoWarn),CS0618</NoWarn>
7-
8-
<!-- this is temporary. will remove in future PR. -->
9-
<Nullable>disable</Nullable>
107
</PropertyGroup>
118

129
<ItemGroup>

examples/Console/InstrumentationWithActivitySource.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ public void Start(string url)
4747
var context = this.listener.GetContext();
4848

4949
using var activity = source.StartActivity(
50-
$"{context.Request.HttpMethod}:{context.Request.Url.AbsolutePath}",
50+
$"{context.Request.HttpMethod}:{context.Request.Url!.AbsolutePath}",
5151
ActivityKind.Server);
5252

5353
var headerKeys = context.Request.Headers.AllKeys;
5454
foreach (var headerKey in headerKeys)
5555
{
56-
string headerValue = context.Request.Headers[headerKey];
56+
string? headerValue = context.Request.Headers[headerKey];
5757
activity?.SetTag($"http.header.{headerKey}", headerValue);
5858
}
5959

@@ -62,7 +62,7 @@ public void Start(string url)
6262
using (var reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding))
6363
{
6464
requestContent = reader.ReadToEnd();
65-
childSpan.AddEvent(new ActivityEvent("StreamReader.ReadToEnd"));
65+
childSpan?.AddEvent(new ActivityEvent("StreamReader.ReadToEnd"));
6666
}
6767

6868
activity?.SetTag("request.content", requestContent);
@@ -90,8 +90,8 @@ public void Dispose()
9090

9191
private class SampleClient : IDisposable
9292
{
93-
private CancellationTokenSource cts;
94-
private Task requestTask;
93+
private CancellationTokenSource? cts;
94+
private Task? requestTask;
9595

9696
public void Start(string url)
9797
{
@@ -154,7 +154,7 @@ public void Dispose()
154154
if (this.cts != null)
155155
{
156156
this.cts.Cancel();
157-
this.requestTask.Wait();
157+
this.requestTask!.Wait();
158158
this.requestTask.Dispose();
159159
this.cts.Dispose();
160160
}

0 commit comments

Comments
 (0)