Skip to content

Commit e9a836b

Browse files
authored
Merge branch 'main' into feat/exception-endpoint
2 parents ab846dc + 3fb2ec5 commit e9a836b

File tree

53 files changed

+1034
-309
lines changed

Some content is hidden

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

53 files changed

+1034
-309
lines changed

.github/workflows/Component.BuildTest.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ jobs:
6868
run: dotnet-coverage merge -r -f cobertura -o ./TestResults/Cobertura.xml ./TestResults/*.coverage
6969

7070
- name: Upload code coverage ${{ inputs.code-cov-prefix }}-${{ inputs.code-cov-name }}
71-
uses: codecov/codecov-action@v3.1.4
71+
uses: codecov/codecov-action@v3.1.5
7272
continue-on-error: true # Note: Don't fail for upload failures
7373
env:
7474
OS: ${{ matrix.os }}

.github/workflows/ci.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ jobs:
138138
needs: detect-changes
139139
if: |
140140
contains(needs.detect-changes.outputs.changes, 'packaged-code')
141+
|| contains(needs.detect-changes.outputs.changes, 'md')
141142
|| contains(needs.detect-changes.outputs.changes, 'build')
142143
|| contains(needs.detect-changes.outputs.changes, 'shared')
143144
uses: ./.github/workflows/docfx.yml

Directory.Packages.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
<PackageVersion Include="Grpc.AspNetCore.Server" Version="[2.59.0, 3.0)" />
7777
<PackageVersion Include="Grpc.Tools" Version="[2.59.0,3.0)" />
7878
<PackageVersion Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="[3.11.0-beta1.23525.2]" />
79-
<PackageVersion Include="Microsoft.Data.SqlClient" Version="5.1.2" />
79+
<PackageVersion Include="Microsoft.Data.SqlClient" Version="5.1.3" />
8080
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="[8.0.0,)" />
8181
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="[8.0.0,)" />
8282
<PackageVersion Include="Microsoft.Extensions.Http" Version="[8.0.0,)" />

OpenTelemetry.sln

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
1515
.github\workflows\ci-concurrency.yml = .github\workflows\ci-concurrency.yml
1616
CONTRIBUTING.md = CONTRIBUTING.md
1717
global.json = global.json
18-
NuGet.config = NuGet.config
1918
LICENSE.TXT = LICENSE.TXT
19+
NuGet.config = NuGet.config
2020
OpenTelemetry.proj = OpenTelemetry.proj
2121
README.md = README.md
22-
VERSIONING.md = VERSIONING.md
2322
THIRD-PARTY-NOTICES.TXT = THIRD-PARTY-NOTICES.TXT
23+
VERSIONING.md = VERSIONING.md
2424
EndProjectSection
2525
EndProject
2626
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{7CB2F02E-03FA-4FFF-89A5-C51F107623FD}"
@@ -154,7 +154,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "metrics", "metrics", "{3277
154154
EndProject
155155
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "logs", "logs", "{3862190B-E2C5-418E-AFDC-DB281FB5C705}"
156156
ProjectSection(SolutionItems) = preProject
157-
docs\logs\getting-started-console\README.md = docs\logs\getting-started-console\README.md
157+
docs\logs\README.md = docs\logs\README.md
158158
EndProjectSection
159159
EndProject
160160
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MicroserviceExample", "MicroserviceExample", "{4D492D62-5150-45F9-817F-C99562E364E2}"
@@ -333,6 +333,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "experimental-apis", "experi
333333
docs\diagnostics\experimental-apis\README.md = docs\diagnostics\experimental-apis\README.md
334334
EndProjectSection
335335
EndProject
336+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "resources", "resources", "{A115CE4C-71A8-4B95-96A5-C1DF46FD94C2}"
337+
ProjectSection(SolutionItems) = preProject
338+
docs\resources\README.md = docs\resources\README.md
339+
EndProjectSection
340+
EndProject
341+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "extending-the-sdk", "docs\resources\extending-the-sdk\extending-the-sdk.csproj", "{7BE494FC-4B0D-4340-A62A-9C9F3E7389FE}"
342+
EndProject
336343
Global
337344
GlobalSection(SolutionConfigurationPlatforms) = preSolution
338345
Debug|Any CPU = Debug|Any CPU
@@ -615,6 +622,10 @@ Global
615622
{B4856711-6D4C-4246-A686-49458D4C1301}.Debug|Any CPU.Build.0 = Debug|Any CPU
616623
{B4856711-6D4C-4246-A686-49458D4C1301}.Release|Any CPU.ActiveCfg = Release|Any CPU
617624
{B4856711-6D4C-4246-A686-49458D4C1301}.Release|Any CPU.Build.0 = Release|Any CPU
625+
{7BE494FC-4B0D-4340-A62A-9C9F3E7389FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
626+
{7BE494FC-4B0D-4340-A62A-9C9F3E7389FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
627+
{7BE494FC-4B0D-4340-A62A-9C9F3E7389FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
628+
{7BE494FC-4B0D-4340-A62A-9C9F3E7389FE}.Release|Any CPU.Build.0 = Release|Any CPU
618629
EndGlobalSection
619630
GlobalSection(SolutionProperties) = preSolution
620631
HideSolutionNode = FALSE
@@ -667,6 +678,8 @@ Global
667678
{B4856711-6D4C-4246-A686-49458D4C1301} = {5B7FB835-3FFF-4BC2-99C5-A5B5FAE3C818}
668679
{52AF6D7D-9E66-4234-9A2C-5D16C6F22B40} = {7C87CAF9-79D7-4C26-9FFB-F3F1FB6911F1}
669680
{17A22B0E-6EC3-4A39-B955-0A486AD06699} = {52AF6D7D-9E66-4234-9A2C-5D16C6F22B40}
681+
{A115CE4C-71A8-4B95-96A5-C1DF46FD94C2} = {7C87CAF9-79D7-4C26-9FFB-F3F1FB6911F1}
682+
{7BE494FC-4B0D-4340-A62A-9C9F3E7389FE} = {A115CE4C-71A8-4B95-96A5-C1DF46FD94C2}
670683
EndGlobalSection
671684
GlobalSection(ExtensibilityGlobals) = postSolution
672685
SolutionGuid = {55639B5C-0770-4A22-AB56-859604650521}

README.md

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ doc](https://docs.google.com/document/d/1yjjD6aBcLxlRazYrawukDgrhZMObwHARJbB9glW
112112
If you have trouble accessing the doc, please get in touch on
113113
[Slack](https://cloud-native.slack.com/archives/C01N3BC2W7Q).
114114

115+
The meeting is open for all to join. We invite everyone to join our meeting,
116+
regardless of your experience level. Whether you're a seasoned OpenTelemetry
117+
developer, just starting your journey, or simply curious about the work we do,
118+
you're more than welcome to participate!
119+
115120
[Maintainers](https://github.com/open-telemetry/community/blob/main/community-membership.md#maintainer)
116121
([@open-telemetry/dotnet-maintainers](https://github.com/orgs/open-telemetry/teams/dotnet-maintainers)):
117122

@@ -149,20 +154,21 @@ Maintainer/Approver/Triager](https://github.com/open-telemetry/community/blob/ma
149154

150155
## Release Schedule
151156

152-
Only the [core components](./VERSIONING.md#core-components) of the repo have
153-
released a stable version. Components which are marked
154-
[pre-release](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/VERSIONING.md#pre-releases),
155-
are still work in progress and can undergo many breaking changes before stable
156-
release.
157+
See the [project
158+
milestones](https://github.com/open-telemetry/opentelemetry-dotnet/milestones)
159+
for details on upcoming releases. The dates and features described in issues and
160+
milestones are estimates, and subject to change.
157161

158162
See the [release
159163
notes](https://github.com/open-telemetry/opentelemetry-dotnet/releases) for
160164
existing releases.
161165

162-
See the [project
163-
milestones](https://github.com/open-telemetry/opentelemetry-dotnet/milestones)
164-
for details on upcoming releases. The dates and features described in issues and
165-
milestones are estimates, and subject to change.
166+
> [!CAUTION]
167+
> Certain components, marked as
168+
[pre-release](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/VERSIONING.md#pre-releases),
169+
are still work in progress and can undergo breaking changes before stable
170+
release. Check the individual `README.md` file for each component to understand its
171+
current state.
166172

167173
Daily builds from this repo are published to MyGet, and can be installed from
168174
[this source](https://www.myget.org/F/opentelemetry/api/v3/index.json).

docs/diagnostics/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ to specific code patterns identified through static analysis.
77

88
## Experimental APIs
99

10-
Range: OTEL1XXX
10+
Range: OTEL1000 - OTEL1999
1111

1212
Experimental APIs exposed in OpenTelemetry .NET pre-relase builds. APIs are
1313
exposed experimentally when either the OpenTelemetry Specification has

docs/docfx.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"files": [
3131
".editorconfig",
3232
"**.cs",
33+
"Directory.Packages.props",
3334
"LICENSE.TXT",
3435
"THIRD-PARTY-NOTICES.TXT"
3536
]

docs/logs/README.md

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
# OpenTelemetry .NET Logs
2+
3+
## Best Practices
4+
5+
The following tutorials have demonstrated the best practices for logging with
6+
OpenTelemetry .NET:
7+
8+
* [Getting Started - Console Application](./getting-started-console/README.md)
9+
* [Getting Started - ASP.NET Core
10+
Application](./getting-started-aspnetcore/README.md)
11+
* [Logging with Complex Objects](./complex-objects/README.md)
12+
13+
## Structured Logging
14+
15+
:heavy_check_mark: You should use structured logging.
16+
17+
* Structured logging is more efficient than unstructured logging.
18+
* Filtering and redaction can happen on invidual key-value pairs instead of
19+
the entire log message.
20+
* Storage and indexing are more efficient.
21+
* Structured logging makes it easier to manage and consume logs.
22+
23+
:stop_sign: You should avoid string interpolation.
24+
25+
> [!WARNING]
26+
> The following code has bad performance due to [string
27+
interpolation](https://learn.microsoft.com/dotnet/csharp/tutorials/string-interpolation):
28+
29+
```csharp
30+
var food = "tomato";
31+
var price = 2.99;
32+
33+
logger.LogInformation($"Hello from {food} {price}.");
34+
```
35+
36+
Refer to the [logging performance
37+
benchmark](../../test/Benchmarks/Logs/LogBenchmarks.cs) for more details.
38+
39+
## Package Version
40+
41+
:heavy_check_mark: You should always use the
42+
[`ILogger`](https://docs.microsoft.com/dotnet/api/microsoft.extensions.logging.ilogger)
43+
interface (including
44+
[`ILogger<TCategoryName>`](https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging.ilogger-1))
45+
from the latest stable version of
46+
[Microsoft.Extensions.Logging](https://www.nuget.org/packages/Microsoft.Extensions.Logging/)
47+
package, regardless of the .NET runtime version being used:
48+
49+
* If you're using the latest stable version of [OpenTelemetry .NET
50+
SDK](../../src/OpenTelemetry/README.md), you don't have to worry about the
51+
version of `Microsoft.Extensions.Logging` package because it is already taken
52+
care of for you via [package dependency](../../Directory.Packages.props).
53+
* Starting from version `3.1.0`, the .NET runtime team is holding a high bar for
54+
backward compatibility on `Microsoft.Extensions.Logging` even during major
55+
version bumps, so compatibility is not a concern here.
56+
57+
## Logging API
58+
59+
:heavy_check_mark: You should use [compile-time logging source
60+
generation](https://docs.microsoft.com/dotnet/core/extensions/logger-message-generator)
61+
pattern to achieve the best performance.
62+
63+
```csharp
64+
public static partial class Food
65+
{
66+
[LoggerMessage(Level = LogLevel.Information, Message = "Hello from {food} {price}.")]
67+
public static partial void SayHello(ILogger logger, string food, double price);
68+
}
69+
70+
var food = "tomato";
71+
var price = 2.99;
72+
73+
Food.SayHello(logger, food, price);
74+
```
75+
76+
> [!NOTE]
77+
> There is no need to pass in an explicit
78+
[EventId](https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging.eventid)
79+
while using
80+
[LoggerMessageAttribute](https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging.loggermessageattribute).
81+
A durable `EventId` will be automatically assigned based on the hash of the
82+
method name during code generation.
83+
84+
:heavy_check_mark: You can use
85+
[LogPropertiesAttribute](https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging.logpropertiesattribute)
86+
from
87+
[Microsoft.Extensions.Telemetry.Abstractions](https://www.nuget.org/packages/Microsoft.Extensions.Telemetry.Abstractions/)
88+
if you need to log complex objects. Check out the [Logging with Complex
89+
Objects](./complex-objects/README.md) tutorial for more details.
90+
91+
:stop_sign: You should avoid the extension methods from
92+
[LoggerExtensions](https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging.loggerextensions),
93+
these methods are not optimized for performance.
94+
95+
> [!WARNING]
96+
> The following code has bad performance due to
97+
[boxing](https://learn.microsoft.com/dotnet/csharp/programming-guide/types/boxing-and-unboxing):
98+
99+
```csharp
100+
var food = "tomato";
101+
var price = 2.99;
102+
103+
logger.LogInformation("Hello from {food} {price}.", food, price);
104+
```
105+
106+
Refer to the [logging performance
107+
benchmark](../../test/Benchmarks/Logs/LogBenchmarks.cs) for more details.
108+
109+
## Logger Management
110+
111+
In order to use
112+
[`ILogger`](https://docs.microsoft.com/dotnet/api/microsoft.extensions.logging.ilogger)
113+
interface (including
114+
[`ILogger<TCategoryName>`](https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging.ilogger-1)),
115+
you need to first get a logger. How to get a logger depends on two things:
116+
117+
* The type of application you are building.
118+
* The place where you want to log.
119+
120+
Here is the rule of thumb:
121+
122+
* If you are building an application with [dependency injection
123+
(DI)](https://learn.microsoft.com/dotnet/core/extensions/dependency-injection)
124+
(e.g. [ASP.NET Core](https://learn.microsoft.com/aspnet/core) and [.NET
125+
Worker](https://learn.microsoft.com/dotnet/core/extensions/workers)), in most
126+
cases you should use the logger provided by DI, there are special cases when
127+
you want log before DI logging pipeline is available or after DI logging
128+
pipeline is disposed. Refer to the [.NET official
129+
document](https://learn.microsoft.com/dotnet/core/extensions/logging#integration-with-hosts-and-dependency-injection)
130+
and [Getting Started with OpenTelemetry .NET Logs in 5 Minutes - ASP.NET Core
131+
Application](./getting-started-aspnetcore/README.md) tutorial to learn more.
132+
* If you are building an application without DI, create a `LoggerFactory`
133+
instance and configure OpenTelemetry to work with it. Refer to the [Getting
134+
Started with OpenTelemetry .NET Logs in 5 Minutes - Console
135+
Application](./getting-started-console/README.md) tutorial to learn more.
136+
137+
:stop_sign: You should avoid creating `LoggerFactory` instances too frequently,
138+
`LoggerFactory` is fairly expensive and meant to be reused throughout the
139+
application. For most applications, one `LoggerFactory` instance per process
140+
would be sufficient.
141+
142+
:heavy_check_mark: You should properly manage the lifecycle of
143+
[LoggerFactory](https://learn.microsoft.com/dotnet/api/microsoft.extensions.logging.loggerfactory)
144+
instances if they are created by you.
145+
146+
* If you forget to dispose the `LoggerFactory` instance before the application
147+
ends, logs might get dropped due to the lack of proper flush.
148+
* If you dispose the `LoggerFactory` instance too early, any subsequent logging
149+
API invocation associated with the logger factory could become no-op (i.e. no
150+
logs will be emitted).
151+
152+
:heavy_check_mark: You should use the fully qualified class name as the log
153+
category name. Refer to the [.NET official
154+
document](https://learn.microsoft.com/dotnet/core/extensions/logging#log-category)
155+
to learn more.
156+
157+
## Log Correlation
158+
159+
In OpenTelemetry, logs are automatically correlated to traces. Check the [Log
160+
Correlation](./correlation/README.md) tutorial to learn more.
161+
162+
## Log Enrichment
163+
164+
TBD
165+
166+
## Log Filtering
167+
168+
Check the [Customizing OpenTelemetry .NET SDK for
169+
Logs](./customizing-the-sdk/README.md#log-filtering) document to learn more.
170+
171+
## Log Redaction
172+
173+
Logs might contain sensitive information such as passwords and credit card
174+
numbers, proper redaction is required to prevent privacy and security incidents.
175+
Check the [Log Redaction](./redaction/README.md) tutorial to learn more.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
using Microsoft.Extensions.Logging;
5+
6+
internal static partial class LoggerExtensions
7+
{
8+
[LoggerMessage(LogLevel.Information, "Food `{name}` price changed to `{price}`.")]
9+
public static partial void FoodPriceChanged(this ILogger logger, string name, double price);
10+
}

docs/logs/correlation/Program.cs

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,40 +7,39 @@
77
using OpenTelemetry.Logs;
88
using OpenTelemetry.Trace;
99

10-
namespace Correlation;
11-
1210
public class Program
1311
{
14-
private static readonly ActivitySource MyActivitySource = new(
15-
"MyCompany.MyProduct.MyLibrary");
12+
private static readonly ActivitySource MyActivitySource = new("MyCompany.MyProduct.MyLibrary");
1613

1714
public static void Main()
1815
{
19-
// Setup Logging
20-
using var loggerFactory = LoggerFactory.Create(builder =>
16+
var tracerProvider = Sdk.CreateTracerProviderBuilder()
17+
.AddSource("MyCompany.MyProduct.MyLibrary")
18+
.AddConsoleExporter()
19+
.Build();
20+
21+
var loggerFactory = LoggerFactory.Create(builder =>
2122
{
22-
builder.AddOpenTelemetry(options =>
23+
builder.AddOpenTelemetry(logging =>
2324
{
24-
options.AddConsoleExporter();
25+
logging.AddConsoleExporter();
2526
});
2627
});
2728

2829
var logger = loggerFactory.CreateLogger<Program>();
2930

30-
// Setup Traces
31-
using var tracerProvider = Sdk.CreateTracerProviderBuilder()
32-
.AddSource("MyCompany.MyProduct.MyLibrary")
33-
.AddConsoleExporter()
34-
.Build();
35-
36-
// Emit activity
3731
using (var activity = MyActivitySource.StartActivity("SayHello"))
3832
{
39-
activity?.SetTag("foo", 1);
40-
41-
// emit logs within the context
42-
// of activity
43-
logger.LogInformation("Hello from {name} {price}.", "tomato", 2.99);
33+
// Write a log within the context of an activity
34+
logger.FoodPriceChanged("artichoke", 9.99);
4435
}
36+
37+
// Dispose logger factory before the application ends.
38+
// This will flush the remaining logs and shutdown the logging pipeline.
39+
loggerFactory.Dispose();
40+
41+
// Dispose tracer provider before the application ends.
42+
// This will flush the remaining spans and shutdown the tracing pipeline.
43+
tracerProvider.Dispose();
4544
}
4645
}

0 commit comments

Comments
 (0)