Skip to content

Commit ed89568

Browse files
authored
docs: integrated logging documentation (#900)
Add documentation page about logging, open telemetry and azure logging.
1 parent e2fccd6 commit ed89568

File tree

3 files changed

+179
-2
lines changed

3 files changed

+179
-2
lines changed

docs/docs/operator/deployment.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Deployment
33
description: Deploying your KubeOps Operator
4-
sidebar_position: 6
4+
sidebar_position: 7
55
---
66

77
# Deployment

docs/docs/operator/logging.mdx

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
---
2+
title: Logging
3+
description: Logging, Tracing, and OpenTelemetry
4+
sidebar_position: 6
5+
---
6+
7+
# Logging, Tracing, and OpenTelemetry
8+
9+
## 1. Logging with `ILogger` and Scopes
10+
11+
This project uses Microsoft's [`ILogger`](https://learn.microsoft.com/en-us/dotnet/core/extensions/logging) interface for logging. It provides a standardized and extensible way to capture events within the application.
12+
13+
Using *scopes* enables hierarchical organization of log messages and allows contextual information to be attached to each entry.
14+
15+
### 1.1 ILogger Basics
16+
17+
The `ILogger` interface is part of [`Microsoft.Extensions.Logging`](https://www.nuget.org/packages/Microsoft.Extensions.Logging) and provides methods to log messages at various severity levels (e.g., `Information`, `Warning`, `Error`).
18+
19+
Logging can be enabled using either `WebApplication.CreateBuilder`, `Host.CreateDefaultBuilder`, or the `AddLogging` extension method on the `IServiceCollection`.
20+
21+
You can log from your code by injecting `ILogger<MyEntityController>` (or a similar type) into your component.
22+
23+
### 1.2 Using Scopes
24+
25+
Scopes define a logical boundary in which all log entries are automatically enriched with contextual metadata. This is especially useful for correlating logs related to a specific request or operation.
26+
27+
By default, the [ResourceWatcher](https://github.com/buehler/dotnet-operator-sdk/blob/main/src/KubeOps.Operator/Watcher/ResourceWatcher%7BTEntity%7D.cs) starts a new scope for every watch event it processes. Each scope includes:
28+
29+
- `EventType`: Type of the received watch event (`Added`, `Modified`, `Deleted`, `Error`, `Bookmark`)
30+
- `Kind`: Custom Resource Definition (CRD) kind
31+
- `Namespace`: CRD namespace
32+
- `Name`: CRD name
33+
- `ResourceVersion`: CRD resource version
34+
35+
You can create additional scopes in your code using `logger.BeginScope(state)`, where `state` can be either a string or a custom object.
36+
37+
To include scopes in the logging output, they must be explicitly enabled either via configuration or code:
38+
39+
**`appsettings.json`:**
40+
41+
```json
42+
"Logging": {
43+
"Console": {
44+
"FormatterName": "Simple",
45+
"FormatterOptions": {
46+
"IncludeScopes": true
47+
}
48+
},
49+
"LogLevel": {
50+
"Default": "Information",
51+
"KubeOps": "Trace"
52+
}
53+
}
54+
```
55+
56+
**Programmatic configuration:**
57+
58+
```csharp
59+
builder
60+
.ConfigureLogging((hostBuilderContext, loggingBuilder) =>
61+
{
62+
loggingBuilder
63+
.AddSimpleConsole(options => options.IncludeScopes = true);
64+
});
65+
```
66+
67+
:::tip
68+
To enable scopes with OpenTelemetry, configure it as follows:
69+
70+
```json
71+
"OpenTelemetry": {
72+
"IncludeScopes": true,
73+
"ParseStateValues": true,
74+
"IncludeFormattedMessage": true
75+
}
76+
```
77+
78+
The scope state must be an `IReadOnlyDictionary<string, object?>` to ensure correct serialization and inclusion in log entries.
79+
:::
80+
81+
## 2. Tracing with `System.Diagnostics` and `ActivitySource`
82+
83+
For [distributed tracing](https://learn.microsoft.com/en-us/dotnet/core/diagnostics/distributed-tracing-concepts), this project uses `System.Diagnostics` in combination with `ActivitySource`.
84+
Activities can be started using `ActivitySource.StartActivity`.
85+
86+
The operator registers an `ActivitySource` instance with the operator name in the dependency injection (DI) container. To use a custom `ActivitySource`, simply register your own, the DI will provide the last registered instance when requested.
87+
88+
:::tip
89+
You can configure the operator name (and thus the `ActivitySource` name) via `OperatorSettings`:
90+
91+
```csharp
92+
const string OperatorName = "my-operator";
93+
94+
builder
95+
.Services
96+
.AddKubernetesOperator(settings => settings.Name = OperatorName);
97+
```
98+
99+
If you're using OpenTelemetry, tracing must be explicitly configured in code. Make sure to add the same source name used when creating the `ActivitySource`.
100+
101+
Also, create a `ResourceBuilder` to name your service properly in trace output:
102+
103+
```csharp
104+
builder.Services
105+
.AddOpenTelemetry()
106+
.WithTracing(tracerProviderBuilder =>
107+
tracerProviderBuilder
108+
.SetResourceBuilder(
109+
ResourceBuilder.CreateDefault()
110+
.AddService(serviceName: OperatorName, serviceVersion: "1.0.0"))
111+
.AddSource(OperatorName));
112+
```
113+
:::
114+
115+
## 3. OpenTelemetry Configuration for Azure Logging
116+
117+
To use OpenTelemetry with Azure, it is recommended to adopt the [Azure Monitor OpenTelemetry Distro](https://learn.microsoft.com/en-us/azure/azure-monitor/app/opentelemetry-enable).
118+
You can enable it via code:
119+
120+
```csharp
121+
builder.Services
122+
.AddOpenTelemetry()
123+
.UseAzureMonitor();
124+
```
125+
126+
### 3.2 Full Example Configuration in `Program.cs` (or `Startup.cs`)
127+
128+
A complete setup with logging, tracing, and OpenTelemetry might look like this:
129+
130+
**`appsettings.json`:**
131+
132+
```json
133+
{
134+
"Logging": {
135+
"LogLevel": {
136+
"Default": "Information",
137+
"KubeOps": "Trace"
138+
},
139+
"Console": {
140+
"FormatterName": "Simple",
141+
"FormatterOptions": {
142+
"IncludeScopes": true,
143+
"SingleLine": true
144+
}
145+
},
146+
"OpenTelemetry": {
147+
"IncludeScopes": true,
148+
"ParseStateValues": true,
149+
"IncludeFormattedMessage": true
150+
}
151+
}
152+
}
153+
```
154+
155+
**`Program.cs`:**
156+
157+
```csharp
158+
const string OperatorName = "my-platform-operator";
159+
160+
var builder = WebApplication.CreateBuilder(args);
161+
162+
builder
163+
.Services
164+
.AddKubernetesOperator(settings => settings.Name = OperatorName)
165+
.RegisterComponents();
166+
167+
builder
168+
.Services
169+
.AddOpenTelemetry()
170+
.WithTracing(tracerProviderBuilder =>
171+
tracerProviderBuilder
172+
.SetResourceBuilder(
173+
ResourceBuilder.CreateDefault()
174+
.AddService(serviceName: OperatorName, serviceVersion: "1.0.0"))
175+
.AddSource(OperatorName))
176+
.UseAzureMonitor();
177+
```

docs/docs/operator/testing/_category_.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"position": 7,
2+
"position": 8,
33
"label": "Testing",
44
"collapsible": true,
55
"collapsed": true

0 commit comments

Comments
 (0)