You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: site/docs/benchmarks.md
+4-4Lines changed: 4 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -17,7 +17,7 @@ The following tables summarize benchmark results as of `2026-02-10`.
17
17
18
18
> [!WARNING]
19
19
>
20
-
> These results should not be interpreted as an absolute ranking of libraries. The goal of these benchmarks was to make sure that `XenoAtom.Logging`is in the **right performance tier**, produces **zero allocations** and to track relative performance across versions as we optimize. Each library has different architectural trade-offs, so end-to-end call costs should be interpreted in the context of the specific benchmark scenarios and constraints.
20
+
> Do not treat these results as an absolute ranking. The goal is to verify that `XenoAtom.Logging`stays in the right performance tier, remains zero-allocation on targeted paths, and tracks progress over time. Libraries make different architectural trade-offs, so interpret end-to-end costs within these benchmark constraints.
21
21
22
22
### Sync suite (`LoggingSyncBenchmarks`)
23
23
@@ -152,7 +152,7 @@ Preset suite names:
152
152
153
153
Each category measures the same logical logging operation for each participating library.
154
154
155
-
Benchmark classes use explicit `SimpleJob` settings to keep runs stable and avoid unbounded auto-scaling of operations per iteration.
155
+
Benchmark classes use explicit `SimpleJob` settings to keep runs stable and avoid unbounded auto-scaling per iteration.
156
156
157
157
## Fairness strategy
158
158
@@ -162,10 +162,10 @@ To keep comparisons fair:
162
162
- Each library is configured with an in-memory/no-op sink.
163
163
- Enabled benchmarks still force each sink to consume the rendered message payload, so we measure logging + message materialization, not just level checks.
164
164
- Disabled benchmarks use the same category names and thresholds across all libraries (`Bench.Enabled` and `Bench.Disabled`).
165
-
- Async categories include only libraries with native asynchronous infrastructure and route payload lengths through an asynchronous consumer queue to compare call-site overhead under asynchronous sink pressure.
165
+
- Async categories include only libraries with native asynchronous infrastructure and route payload lengths through an asynchronous consumer queue to compare call-site overhead under sink pressure.
166
166
- Async consumer queues are bounded and drop on overflow to prevent unbounded memory growth from benchmark harness backpressure.
167
167
168
168
## Notes
169
169
170
-
- Different libraries have different internal architectures (sync vs async pipelines, template handling, interpolation handlers, etc.); results should be interpreted as *end-to-end call cost under equivalent benchmark constraints*, not as an absolute universal ranking.
170
+
- Different libraries use different architectures (sync vs async pipelines, template handling, interpolation handlers, etc.); interpret results as *end-to-end call cost under equivalent constraints*, not as a universal ranking.
171
171
- Run benchmarks on an idle machine and repeat multiple times before drawing conclusions.
Copy file name to clipboardExpand all lines: site/docs/log-formatter.md
+12-12Lines changed: 12 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,24 +6,24 @@ title: "Log Formatters"
6
6
7
7
`XenoAtom.Logging` formats a `LogMessage` into text using `LogFormatter` implementations.
8
8
9
-
Key goals:
9
+
Goals:
10
10
11
11
- Zero allocations on the hot path.
12
12
- Formatting into `Span<char>` (and optionally emitting segment metadata for styling).
13
13
- User-defined text formats via source generation (`[LogFormatter]`).
14
14
- Common formatter settings (`LevelFormat`, `TimestampFormat`) centralized on `LogFormatter`.
15
15
16
-
This page covers the user-facing API and common customization patterns. For implementation-level details, see the internal formatter spec (`site/docs/specs/formatter_specs.md`).
16
+
This page covers user-facing APIs and customization patterns. For implementation-level details, see the internal formatter spec (`site/docs/specs/formatter_specs.md`) in the repository.
17
17
18
18
## Built-in formatters
19
19
20
-
The core package includes a few ready-to-use text formatters:
20
+
The core package includes ready-to-use text formatters:
-`DetailedLogFormatter` (like standard + thread id and a sequence id)
24
+
-`DetailedLogFormatter` (like standard plus thread id and sequence id)
25
25
26
-
There is also `JsonLogFormatter` which is not template-based and has different semantics (JSON lines for ingestion).
26
+
`JsonLogFormatter` is also available. It is not template-based and targets JSON-line ingestion scenarios.
27
27
28
28
## Selecting a formatter
29
29
@@ -75,7 +75,7 @@ var terminalWriter = new TerminalLogWriter(Terminal.Instance)
75
75
76
76
## Runtime customization
77
77
78
-
`LevelFormat` and `TimestampFormat` are inherited from `LogFormatter`. Template-generated formatters initialize these values in generated constructors, and you can still override them with `with { ... }`:
78
+
`LevelFormat` and `TimestampFormat` are inherited from `LogFormatter`. Template-generated formatters initialize these values in generated constructors, and you can override them with `with { ... }`:
79
79
80
80
```csharp
81
81
usingXenoAtom.Logging;
@@ -88,7 +88,7 @@ var formatter = StandardLogFormatter.Instance with
88
88
};
89
89
```
90
90
91
-
Default `LevelFormat` is `Tri` (aligned 3-character levels like`INF`, `WRN`, `ERR`).
91
+
The default `LevelFormat` is `Tri` (aligned 3-character levels such as`INF`, `WRN`, `ERR`).
92
92
93
93
`TimestampFormat` defaults to `"yyyy-MM-dd HH:mm:ss.fffffff"` unless changed by the formatter template (for example `{Timestamp:HH:mm:ss}`).
94
94
@@ -113,7 +113,7 @@ var formatter = MyLogFormatter.Instance;
113
113
114
114
## Template syntax (user-facing)
115
115
116
-
Formatter templates look like a .NET composite format string, but the generator validates the template at compile time and produces a specialized `TryFormat(...)` implementation.
116
+
Formatter templates look like .NET composite format strings. The generator validates templates at compile time and emits a specialized `TryFormat(...)` implementation.
117
117
118
118
### Literals and escaping braces
119
119
@@ -162,7 +162,7 @@ Rules and behavior:
162
162
- A conditional section starts with `{?` and ends with `?}`.
163
163
- Conditional sections **cannot be nested**.
164
164
- A conditional section must contain at least one field placeholder.
165
-
- A conditional section is emitted only if **all emptyable fields referenced within the section are non-empty**.
165
+
- A conditional section is emitted only if **all emptyable fields referenced in that section are non-empty**.
166
166
- If a conditional contains no emptyable fields, the generator warns with `XLF0006` (it is always emitted).
167
167
168
168
Emptyable fields are:
@@ -177,7 +177,7 @@ All other fields are always considered present.
177
177
178
178
### Supported fields and format specifiers
179
179
180
-
Fields are case-insensitive and map to `LogMessage` data. This is a closed set.
180
+
Fields are case-insensitive and map to `LogMessage` data. The set is closed.
Text formatters can optionally emit segment metadata (`LogMessageFormatSegments`) while formatting. This enables writers to style output by segment kind (timestamp/level/logger name, etc.).
249
+
Text formatters can optionally emit segment metadata (`LogMessageFormatSegments`) while formatting. This lets writers style output by segment kind (timestamp/level/logger name, etc.).
250
250
251
251
`TerminalLogWriter` uses these segment kinds to apply styles:
252
252
@@ -268,4 +268,4 @@ Common generator diagnostics:
268
268
-`XLF0003`: invalid format specifier (e.g., `{Level:oops}` or `{Properties:sep=, }`).
269
269
-`XLF0006`: conditional section is always emitted (no emptyable fields inside).
270
270
271
-
If you are consuming NuGet packages and the generator does not run, ensure you are using the .NET 10 SDK and that analyzers are enabled in your build. If you are using project references and analyzers are not flowing, add an explicit analyzer reference to `XenoAtom.Logging.Generators.csproj`.
271
+
If you consume NuGet packages and the generator does not run, verify that you use the .NET 10 SDK and analyzers are enabled. If you use project references and analyzers are not flowing, add an explicit analyzer reference to `XenoAtom.Logging.Generators.csproj`.
<p class="mb-2">Add <code>XenoAtom.Logging.Terminal</code> for markup logs, rich segment styling, and <code>LogControl</code> support powered by <a href="https://xenoatom.github.io/terminal">XenoAtom.Terminal.UI</a>.</p>
35
+
<p class="mb-2">Add <code>XenoAtom.Logging.Terminal</code> for markup logs, rich segment styling, and <code>LogControl</code> integration powered by <a href="https://xenoatom.github.io/terminal">XenoAtom.Terminal.UI</a>.</p>
<p class="card-text mb-2">Use sync processing by default or switch to async with queue capacity and overflow policies (`Drop`, `Block`, `Allocate`).</p>
67
+
<p class="card-text mb-2">Use sync processing by default, or switch to async with explicit queue capacity and overflow policies.</p>
70
68
<p class="mb-0"><a href="{{site.basepath}}/docs/getting-started/">Getting started guide</a></p>
0 commit comments