### Install lunet tool
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/AGENTS.md
Install the lunet dotnet tool globally. Run once before building the site.
```bash
dotnet tool install -g lunet
```
--------------------------------
### Default style example output
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/terminal-visuals.md
Example log output with default styling, showing Info, Warning, and Error levels with timestamps and exception details.
```text
2026-02-09 18:21:04.7253194 INF Sample.App: Service started
2026-02-09 18:21:04.7319831 WRN Sample.App: Queue latency above threshold
2026-02-09 18:21:04.7424107 ERR Sample.App [42]: Failed to process request
System.InvalidOperationException: boom
```
--------------------------------
### Configure and use TerminalLogWriter
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/terminal.md
Shows how to initialize XenoAtom.Logging with a TerminalLogWriter, set the minimum log level to Info, and log a message. The example includes creating a LogManagerConfig, initializing the LogManager, getting a logger, and shutting down.
```csharp
using XenoAtom.Logging;
using XenoAtom.Logging.Writers;
var config = new LogManagerConfig
{
RootLogger =
{
MinimumLevel = LogLevel.Info,
Writers =
{
new TerminalLogWriter()
}
}
};
LogManager.Initialize(config);
var logger = LogManager.GetLogger("Sample.Terminal");
logger.Info("Hello terminal");
LogManager.Shutdown();
```
--------------------------------
### Alignment example with [LogFormatter]
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/log-formatter.md
Example formatter using alignment specifiers for Level and LoggerName. Demonstrates that values longer than alignment width are not truncated.
```csharp
[LogFormatter("{Level,-5} {LoggerName,30} {Text}")]
public sealed partial record Example : LogFormatter;
```
--------------------------------
### Markup message example output
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/terminal-visuals.md
Example log output with markup tags in messages, rendered when EnableMarkupMessages is enabled.
```text
2026-02-09 18:21:04.7501062 INF Sample.Terminal: ready worker=api-1
2026-02-09 18:21:04.7529450 ERR Sample.Terminal: failed request=REQ-0042
```
--------------------------------
### Minimal synchronous logging setup
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/getting-started.md
Initializes XenoAtom.Logging with synchronous processing, writes to standard output, and logs an info and warning message. Shutdown flushes and disposes writers.
```csharp
using XenoAtom.Logging;
using XenoAtom.Logging.Writers;
var config = new LogManagerConfig
{
RootLogger =
{
MinimumLevel = LogLevel.Info,
Writers =
{
new StreamLogWriter(Console.OpenStandardOutput())
}
}
};
LogManager.Initialize(config);
var logger = LogManager.GetLogger("App");
logger.Info("Application started");
logger.Warn($"Retry attempt = {3}");
LogManager.Shutdown();
```
--------------------------------
### Asynchronous logging setup with FileLogWriter
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/getting-started.md
Initializes logging for asynchronous processing with a queue capacity of 4096 and an error handler. Uses a file writer and Block overflow mode to preserve correctness.
```csharp
var config = new LogManagerConfig
{
AsyncLogMessageQueueCapacity = 4096,
AsyncErrorHandler = exception =>
{
Console.Error.WriteLine($"[async logging error] {exception.Message}");
},
RootLogger =
{
MinimumLevel = LogLevel.Info,
OverflowMode = LoggerOverflowMode.Block,
Writers =
{
new FileLogWriter("logs/app.log")
}
}
};
LogManager.InitializeForAsync(config);
```
--------------------------------
### Install XenoAtom.Logging core package
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/packages.md
Adds the core XenoAtom.Logging package to a project. Includes LogManager, Logger, scopes, processors, formatters, writers, and source generators.
```sh
dotnet add package XenoAtom.Logging
```
--------------------------------
### Install XenoAtom.Logging.Terminal package
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/packages.md
Adds the terminal sink package for CLI/console apps. Provides TerminalLogWriter and markup logging extensions.
```sh
dotnet add package XenoAtom.Logging.Terminal
```
--------------------------------
### HTML banner structure
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/banner.md
Banner markup with project logo, title, description, feature pills, install command, and links.
```html
{{site.project_name}}
{{site.description}}
Zero-allocation hot path
Sync + async modes
Source-generated APIs
File + JSON sinks
Terminal + LogControl visuals
Install:
dotnet add package {{site.project_package_id}}
```
--------------------------------
### Rendered output of visual attachment
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/terminal-visuals.md
Example terminal output showing the rendered table with the log message.
```text
2026-02-09 18:21:04.7604120 INF Sample.Terminal: Run summary
┌───────────────┬────────┬───────────┐
│ Step │ Status │ Duration │
├───────────────┼────────┼───────────┤
│ Initialize │ OK │ 00:00.045 │
│ ProcessRequest│ FAILED │ 00:00.003 │
└───────────────┴────────┴───────────┘
```
--------------------------------
### Add reject and accept filters to a writer
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/filtering.md
Adds a reject filter to suppress loggers whose name starts with 'App.Noisy' and an accept filter to only allow log entries with level Warn or higher.
```csharp
fileWriter.RejectFilters.Add(static m =>
m.Logger.Name.StartsWith("App.Noisy", StringComparison.Ordinal));
fileWriter.AcceptFilters.Add(static m =>
m.Level >= LogLevel.Warn);
```
--------------------------------
### Conditional sections example with [LogFormatter]
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/log-formatter.md
Shows conditional sections that emit content only when referenced emptyable fields are non-empty. Here, [{EventId}] appears only when EventId is present, and | {Exception} only when an exception is attached.
```csharp
[LogFormatter("{Timestamp} {Level} {LoggerName}{? [{EventId}]?} {Text}{? | {Exception}?}")]
public sealed partial record Standardish : LogFormatter;
```
--------------------------------
### Build the website with lunet
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/AGENTS.md
Build the site using lunet. Always run this after changing files under site/**. Execute from the site folder.
```bash
lunet build
```
--------------------------------
### Run HelloLogControl sample
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/samples/readme.md
Command to run the HelloLogControl sample project from the repository root. Demonstrates writing logs to a LogControl in a fullscreen UI with rich formatting and background-thread marshaling.
```sh
dotnet run --project samples/HelloLogControl/HelloLogControl.csproj -c Release
```
--------------------------------
### Build and test commands
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/AGENTS.md
Commands to build, test, and build the documentation site from the project root. Run from the project root folder.
```sh
# from the project root (this folder)
cd src
dotnet build -c Release
dotnet test -c Release
cd ../site
lunet build
```
--------------------------------
### Run HelloLogging sample
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/samples/readme.md
Command to run the HelloLogging sample project from the repository root. Demonstrates rich terminal styling, markup logging, visual attachments, scoped properties, and exception logging.
```sh
dotnet run --project samples/HelloLogging/HelloLogging.csproj -c Release
```
--------------------------------
### Run all benchmarks
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/benchmarks.md
Runs the full benchmark suite from the repository root in Release configuration.
```sh
dotnet run --project src/XenoAtom.Logging.Benchmark/XenoAtom.Logging.Benchmark.csproj -c Release
```
--------------------------------
### Run preset suites
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/benchmarks.md
Runs the predefined benchmark suites 'comparison' and 'async' as implemented in Program.cs.
```sh
dotnet run --project src/XenoAtom.Logging.Benchmark/XenoAtom.Logging.Benchmark.csproj -c Release -- --suite comparison
```
```sh
dotnet run --project src/XenoAtom.Logging.Benchmark/XenoAtom.Logging.Benchmark.csproj -c Release -- --suite async
```
--------------------------------
### List available suites
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/benchmarks.md
Lists all available preset suites and their aliases.
```sh
dotnet run --project src/XenoAtom.Logging.Benchmark/XenoAtom.Logging.Benchmark.csproj -c Release -- --list-suites
```
--------------------------------
### Run FileJsonLogging sample
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/samples/readme.md
Command to run the FileJsonLogging sample project from the repository root. Demonstrates text and JSON lines logging with rolling and retention options, structured properties, scopes, event IDs, and exception logging.
```sh
dotnet run --project samples/FileJsonLogging/FileJsonLogging.csproj -c Release
```
--------------------------------
### Configure and initialize XenoAtom.Logging with file writer
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/readme.md
Creates a LogManagerConfig with a FileLogWriter that rolls daily, limits file size to 10 MB, rolls on startup, and retains 7 files. Initializes the logger, logs a message, and shuts down. The default processor is synchronous.
```csharp
using XenoAtom.Logging;
using XenoAtom.Logging.Writers;
var config = new LogManagerConfig
{
RootLogger =
{
MinimumLevel = LogLevel.Info,
Writers =
{
new FileLogWriter(
new FileLogWriterOptions("logs/app.log")
{
FileSizeLimitBytes = 10 * 1024 * 1024,
RollingInterval = FileRollingInterval.Daily,
RollOnStartup = true,
RetainedFileCountLimit = 7
})
}
}
};
LogManager.Initialize(config); // sync processor by default
var logger = LogManager.GetLogger("Sample");
logger.Info($"Hello {42}");
LogManager.Shutdown();
```
--------------------------------
### XenoAtom.Logging minimal configuration
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/microsoft-extensions-logging.md
Initializes XenoAtom.Logging with a LogManagerConfig that sets minimum level to Info and uses a StreamLogWriter writing to standard output.
```csharp
using XenoAtom.Logging;
using XenoAtom.Logging.Writers;
var config = new LogManagerConfig
{
RootLogger =
{
MinimumLevel = LogLevel.Info,
Writers =
{
new StreamLogWriter(Console.OpenStandardOutput())
}
}
};
LogManager.Initialize(config);
```
--------------------------------
### Configure rolling and retention for FileLogWriter
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/file-writer.md
Creates a FileLogWriter with a 10 MB size limit, daily rolling, retention of 14 archives, and startup rollover. Archived files are named app..log using UTC timestamps. Set RetainedFileCountLimit to null to disable cleanup; FlushToDisk forces durable writes.
```csharp
var writer = new FileLogWriter(
new FileLogWriterOptions("logs/app.log")
{
FileSizeLimitBytes = 10 * 1024 * 1024, // 10 MB
RollingInterval = FileRollingInterval.Daily,
RetainedFileCountLimit = 14, // defaults to 31; set null to keep indefinitely
RollOnStartup = true,
AutoFlush = false,
ArchiveTimestampMode = FileArchiveTimestampMode.Utc,
FlushToDisk = false
});
```
--------------------------------
### Basic file logging with FileLogWriter
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/file-writer.md
Configures the root logger to write to logs/app.log at Info level. If the file already contains data, it is archived and a fresh file is created on startup.
```csharp
using XenoAtom.Logging;
using XenoAtom.Logging.Writers;
var config = new LogManagerConfig
{
RootLogger =
{
MinimumLevel = LogLevel.Info,
Writers =
{
new FileLogWriter("logs/app.log")
}
}
};
LogManager.Initialize(config);
```
--------------------------------
### Add XenoAtom.Logging NuGet packages
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/readme.md
Use these dotnet CLI commands to add the core and terminal packages to your project.
```sh
dotnet add package XenoAtom.Logging
dotnet add package XenoAtom.Logging.Terminal
```
--------------------------------
### Recommended usage for service/hosted apps
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/shutdown.md
Wrap the application run in a try-finally block to ensure LogManager.Shutdown() is called, guaranteeing a coordinated stop and resource cleanup.
```csharp
try
{
RunApplication();
}
finally
{
LogManager.Shutdown();
}
```
--------------------------------
### Run async-consumer scenarios
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/benchmarks.md
Runs only benchmarks in the AsyncEnabledStructured or AsyncEnabledException categories.
```sh
dotnet run --project src/XenoAtom.Logging.Benchmark/XenoAtom.Logging.Benchmark.csproj -c Release -- --anyCategories AsyncEnabledStructured AsyncEnabledException
```
--------------------------------
### Configure logger hierarchy with RootLogger and Loggers
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/filtering.md
Sets up a root logger with a file writer and adds a named logger config for 'App.Http' with Debug level and both file and JSON writers, with includeParents set to true.
```csharp
using XenoAtom.Logging;
using XenoAtom.Logging.Writers;
var fileWriter = new FileLogWriter("logs/app.log");
var jsonWriter = new JsonFileLogWriter("logs/app.jsonl");
var config = new LogManagerConfig
{
RootLogger =
{
MinimumLevel = LogLevel.Info,
Writers = { fileWriter }
}
};
// "App.Http" and children become Debug and fan out to both writers.
config.Loggers.Add("App.Http", LogLevel.Debug, [fileWriter, jsonWriter], includeParents: true);
```
--------------------------------
### MEL minimal logging configuration
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/microsoft-extensions-logging.md
Configures logging with Microsoft.Extensions.Logging, setting minimum level to Information and adding a console provider.
```csharp
builder.Services.AddLogging(logging =>
{
logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Information);
logging.AddConsole();
});
```
--------------------------------
### Configure StreamLogWriter with CompactLogFormatter
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/log-formatter.md
Sets a CompactLogFormatter on a StreamLogWriter writing to standard output. Requires the XenoAtom.Logging, XenoAtom.Logging.Formatters, and XenoAtom.Logging.Writers namespaces.
```csharp
using XenoAtom.Logging;
using XenoAtom.Logging.Formatters;
using XenoAtom.Logging.Writers;
var config = new LogManagerConfig
{
RootLogger =
{
Writers =
{
new StreamLogWriter(Console.OpenStandardOutput())
{
Formatter = CompactLogFormatter.Instance
}
}
}
};
LogManager.Initialize(config);
```
--------------------------------
### Add XenoAtom.Logging package reference
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/log-formatter.md
Adds the XenoAtom.Logging NuGet package to enable the generator/analyzer. A single package reference is sufficient.
```xml
```
--------------------------------
### Terminal output with markup
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/getting-started.md
Initializes logging with a TerminalLogWriter and logs a message with markup formatting. Requires the XenoAtom.Logging.Terminal package.
```csharp
using XenoAtom.Logging;
using XenoAtom.Logging.Writers;
var config = new LogManagerConfig
{
RootLogger =
{
Writers =
{
new TerminalLogWriter()
}
}
};
LogManager.Initialize(config);
LogManager.GetLogger("App").InfoMarkup("[green]ready[/]");
LogManager.Shutdown();
```
--------------------------------
### Use markup logging methods
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/terminal.md
Calls InfoMarkup and ErrorMarkup with markup tags to render colored messages.
```csharp
logger.InfoMarkup("[green]ready[/] [gray]service started[/]");
logger.ErrorMarkup($"[red]failed[/] request={requestId}");
```
--------------------------------
### Configure FileLogWriter with DetailedLogFormatter via options
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/log-formatter.md
Creates a FileLogWriter with a DetailedLogFormatter using FileLogWriterOptions. The log file path is 'logs/app.log'.
```csharp
using XenoAtom.Logging.Formatters;
using XenoAtom.Logging.Writers;
var writer = new FileLogWriter(
new FileLogWriterOptions("logs/app.log")
{
Formatter = DetailedLogFormatter.Instance
});
```
--------------------------------
### Enable async processing in XenoAtom.Logging
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/readme.md
Sets an async error handler and initializes the logger with an async processor. Use this instead of the default synchronous Initialize when you need asynchronous logging.
```csharp
config.AsyncErrorHandler = exception =>
{
Console.Error.WriteLine($"[logging async error] {exception}");
};
LogManager.InitializeForAsync(config);
```
--------------------------------
### dotnet publish command for Native AOT
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/aot.md
Recommended publish command for Native AOT and trimming. Replace win-x64 with your runtime identifier.
```sh
dotnet publish -c Release -r win-x64 -p:PublishAot=true -p:PublishTrimmed=true
```
--------------------------------
### Access generated Instance property
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/log-formatter.md
Retrieves the singleton instance of a template-generated formatter.
```csharp
var formatter = MyLogFormatter.Instance;
```
--------------------------------
### Run a single benchmark method
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/benchmarks.md
Runs only the benchmark method matching the given filter pattern, e.g., *XenoAtom_Enabled_Structured*.
```sh
dotnet run --project src/XenoAtom.Logging.Benchmark/XenoAtom.Logging.Benchmark.csproj -c Release -- --filter *XenoAtom_Enabled_Structured*
```
--------------------------------
### Run benchmarks by category
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/benchmarks.md
Runs only benchmarks matching the specified category, e.g., EnabledStructured.
```sh
dotnet run --project src/XenoAtom.Logging.Benchmark/XenoAtom.Logging.Benchmark.csproj -c Release -- --anyCategories EnabledStructured
```
--------------------------------
### Configure styles by segment kind and log level
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/terminal.md
Clears existing styles and sets styles for timestamp, logger name, and log levels. Use during startup; avoid concurrent mutation without synchronization.
```csharp
writer.Styles.Clear();
writer.Styles.SetStyle(LogMessageFormatSegmentKind.Timestamp, "dim");
writer.Styles.SetStyle(LogMessageFormatSegmentKind.LoggerName, "blue");
writer.Styles.SetLevelStyle(LogLevel.Info, "green");
writer.Styles.SetLevelStyle(LogLevel.Error, "bold white on red");
```
--------------------------------
### Configure failure handling with Retry mode
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/file-writer.md
Sets FailureMode to Retry with 5 retries and a 100ms delay, and defines a FailureHandler that logs failure details. The handler receives context with FilePath, Attempt, WillRetry, and Exception.Message.
```csharp
var options = new FileLogWriterOptions("logs/app.log")
{
FailureMode = FileLogWriterFailureMode.Retry,
RetryCount = 5,
RetryDelay = TimeSpan.FromMilliseconds(100),
FailureHandler = context =>
{
Console.WriteLine(
$"File log failure on {context.FilePath}. " +
$"Attempt={context.Attempt} Retry={context.WillRetry} " +
$"Error={context.Exception.Message}");
}
};
```
--------------------------------
### Attach Visual table to log messages
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/terminal.md
Creates a Table visual and attaches it to log messages using logger.Info and logger.InfoMarkup. Requires XenoAtom.Terminal.UI and XenoAtom.Terminal.UI.Controls namespaces.
```csharp
using XenoAtom.Terminal.UI;
using XenoAtom.Terminal.UI.Controls;
var table = new Table()
.Headers("Step", "Status")
.AddRow("Build", "OK")
.AddRow("Deploy", "Done");
logger.Info(table, "Deployment summary");
logger.InfoMarkup(table, "[bold]Deployment report[/]");
```
--------------------------------
### Configure FileLogWriter with StandardLogFormatter
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/log-formatter.md
Creates a FileLogWriter with a formatter that sets timestamp format to "HH:mm:ss" and level format to Tri. Use this when writing to a file sink.
```csharp
var writer = new FileLogWriter(
new FileLogWriterOptions("logs/app.log")
{
Formatter = StandardLogFormatter.Instance with
{
TimestampFormat = "HH:mm:ss",
LevelFormat = LogLevelFormat.Tri
}
});
```
--------------------------------
### XenoAtom.Logging per-message properties
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/microsoft-extensions-logging.md
Logs a message with explicit properties using LogProperties, demonstrating allocation-aware structured logging.
```csharp
logger.Info(
properties: new LogProperties { ("UserId", 42), ("Feature", "checkout") },
msg: "Validation failed");
```
--------------------------------
### Add logger config with includeParents false
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/filtering.md
Adds a logger config for 'App.Audit' with Info level and only the JSON writer, with includeParents set to false, so that App.Audit.* writes only to jsonWriter.
```csharp
config.Loggers.Add("App.Audit", LogLevel.Info, [jsonWriter], includeParents: false);
```
--------------------------------
### Custom archive file names with FileArchiveFileNameFormatters.DateTime
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/file-writer.md
Configures a FileLogWriter with daily rolling and a DateTime archive file name formatter, producing names like output.2026-02-19-19_16_03.txt.
```csharp
var writer = new FileLogWriter(
new FileLogWriterOptions("logs/output.txt")
{
RollingInterval = FileRollingInterval.Daily,
ArchiveFileNameFormatter = FileArchiveFileNameFormatters.DateTime
});
```
--------------------------------
### Attach visual table to log entries with TerminalLogWriter
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/readme.md
Creates a Table control from XenoAtom.Terminal.UI and attaches it to log entries. The table is rendered under the log line by TerminalLogWriter. Requires the XenoAtom.Terminal.UI package.
```csharp
using XenoAtom.Terminal.UI;
using XenoAtom.Terminal.UI.Controls;
var table = new Table()
.Headers("Step", "Status", "Duration")
.AddRow("Initialize", "OK", "00:00.045")
.AddRow("ProcessRequest", "FAILED", "00:00.003");
logger.Info(table, "Run summary");
logger.InfoMarkup(table, "[bold]Run summary (styled)[/]");
```
--------------------------------
### XenoAtom.Logging LogMethod source generator
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/microsoft-extensions-logging.md
Defines a partial method with LogMethod attribute for source-generated logging in XenoAtom.Logging.
```csharp
using XenoAtom.Logging;
public static partial class AppLog
{
[LogMethod(LogLevel.Info, "Processing item {itemId}", EventId = 1)]
public static partial void ProcessingItem(Logger logger, int itemId);
}
```
--------------------------------
### Attach visual object to log call
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/terminal-visuals.md
C# code showing how to attach a Table visual to log calls using Info and InfoMarkup methods.
```csharp
var table = new Table()
.Headers("Step", "Status", "Duration")
.AddRow("Initialize", "OK", "00:00.045")
.AddRow("ProcessRequest", "FAILED", "00:00.003");
logger.Info(table, "Run summary");
logger.InfoMarkup(table, "[bold]Run summary (styled)[/]");
```
--------------------------------
### XenoAtom.Logging scope with LogProperties
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/microsoft-extensions-logging.md
Uses BeginScope with LogProperties to add structured data to a log scope.
```csharp
using (logger.BeginScope(new LogProperties { ("RequestId", requestId) }))
{
logger.Info("Handling request");
}
```
--------------------------------
### Apply runtime configuration changes
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/filtering.md
Calls ApplyChanges() on the LogManagerConfig to apply runtime updates to the configuration collections.
```csharp
config.ApplyChanges();
```
--------------------------------
### Create custom text formatter with [LogFormatter]
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/source-generator.md
Declares a partial record inheriting LogFormatter with [LogFormatter] to generate a high-performance text formatter. The template uses placeholders like {Timestamp:HH:mm:ss} and conditional sections. See the Log Formatters page for usage and template reference.
```csharp
using XenoAtom.Logging;
[LogFormatter("{Timestamp:HH:mm:ss} {Level,-5} {LoggerName} {Text}{? | {Exception}?}")]
public sealed partial record MyFormatter : LogFormatter;
```
--------------------------------
### Declare markup-aware logging methods with [LogMethodMarkup]
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/source-generator.md
Declares static partial methods with [LogMethodMarkup] to generate markup-aware logging methods. Requires the XenoAtom.Logging.Terminal package. Generated code routes through terminal markup APIs and sets LogMessage.IsMarkup = true.
```csharp
using XenoAtom.Logging;
public static partial class AppLogs
{
[LogMethodMarkup(LogLevel.Info, "[green]User {userId} connected[/]")]
public static partial void UserConnectedMarkup(Logger logger, int userId);
}
```
--------------------------------
### Declare logging methods with [LogMethod]
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/source-generator.md
Declares static partial methods with [LogMethod] to generate strongly-typed logging methods. The generator emits level checks, optional LogEventId, and calls to LoggerExtensions methods. Placeholder names must match method parameter names.
```csharp
using XenoAtom.Logging;
public static partial class AppLogs
{
[LogMethod(LogLevel.Info, "User {userId} connected from {ip}")]
public static partial void UserConnected(Logger logger, int userId, string ip);
[LogMethod(LogLevel.Error, "Request {requestId} failed", EventId = 42, EventName = "RequestFailed")]
public static partial void RequestFailed(Logger logger, Exception exception, LogProperties properties, int requestId);
}
```
--------------------------------
### CSS for banner links and icons
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/banner.md
Styles for hover effects on banner links and spacing for Bootstrap icons.
```css
.banner-links a:hover {
color: rgba(220, 216, 228, 1);
border-bottom-color: rgba(220, 216, 228, 0.75);
}
.banner-links i.bi {
margin-right: 0.35rem;
}
```
--------------------------------
### Create TerminalLogControlWriter with LogControl
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/terminal.md
Shows how to instantiate a TerminalLogControlWriter with a LogControl, enabling rich formatting and markup messages. This writer marshals background thread writes to the UI thread and does not render attachments by default.
```csharp
using XenoAtom.Logging.Writers;
using XenoAtom.Terminal.UI.Controls;
var logControl = new LogControl();
var writer = new TerminalLogControlWriter(logControl)
{
EnableRichFormatting = true,
EnableMarkupMessages = true
};
```
--------------------------------
### Reset styles to defaults
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/terminal.md
Restores default styles on the writer's Styles configuration.
```csharp
writer.Styles.ResetToDefaults();
```
--------------------------------
### MEL scope with BeginScope
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/microsoft-extensions-logging.md
Uses BeginScope with a message template to add structured data to a log scope.
```csharp
using (_logger.BeginScope("Request {RequestId}", requestId))
{
_logger.LogInformation("Handling request");
}
```
--------------------------------
### JSON-lines logging with JsonFileLogWriter
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/file-writer.md
Creates a JsonFileLogWriter with daily rolling and a retained file count limit of 7, emitting one JSON object per line.
```csharp
var writer = new JsonFileLogWriter(
new FileLogWriterOptions("logs/app.jsonl")
{
RollingInterval = FileRollingInterval.Daily,
RetainedFileCountLimit = 7
});
```
--------------------------------
### Define custom formatter with [LogFormatter] attribute
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/log-formatter.md
Declares a partial record inheriting LogFormatter and decorated with [LogFormatter]. The generator emits a TryFormat implementation and a singleton Instance property.
```csharp
using XenoAtom.Logging;
namespace MyApp.Logging;
[LogFormatter("{Timestamp:HH:mm:ss} {Level,-5} {LoggerName} {Text}{? | {Exception}?}")]
public sealed partial record MyLogFormatter : LogFormatter;
```
--------------------------------
### Log structured properties
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/getting-started.md
Logs a message with structured properties using LogProperties, including requestId and tenant.
```csharp
var properties = new LogProperties
{
("requestId", 1423),
("tenant", "alpha")
};
logger.Info(properties: properties, msg: "Processing request");
```
--------------------------------
### Log with scoped context
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/getting-started.md
Uses BeginScope to add contextual data (traceId) to all log messages within the scope.
```csharp
using (logger.BeginScope(new LogProperties { ("traceId", "abc-123") }))
{
logger.Info("Inside request scope");
}
```
--------------------------------
### Configure TerminalLogWriter with StandardLogFormatter
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/log-formatter.md
Sets a StandardLogFormatter on a TerminalLogWriter for terminal output.
```csharp
var terminalWriter = new TerminalLogWriter()
{
Formatter = StandardLogFormatter.Instance
};
```
--------------------------------
### Enable rich formatting and markup messages on TerminalLogWriter
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/terminal.md
Creates a TerminalLogWriter with EnableRichFormatting and EnableMarkupMessages set to true, enabling rich formatting by default.
```csharp
var writer = new TerminalLogWriter()
{
EnableRichFormatting = true,
EnableMarkupMessages = true,
};
```
--------------------------------
### Log markup messages with InfoMarkup and ErrorMarkup
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/readme.md
Logs markup-formatted messages to the terminal sink. InfoMarkup writes an informational message, ErrorMarkup writes an error message with an interpolated request ID.
```csharp
logger.InfoMarkup("[green]ready[/]");
logger.ErrorMarkup($"[bold red]failed[/] id={requestId}");
```
--------------------------------
### Custom archive file name callback
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/file-writer.md
Provides a custom callback for ArchiveFileNameFormatter that formats the timestamp and includes base file name and extension.
```csharp
ArchiveFileNameFormatter = context =>
$"{context.BaseFileName}.{context.Timestamp:yyyy-MM-dd-HH_mm_ss}{context.Extension}";
```
--------------------------------
### Log markup message with InfoMarkup
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/log-formatter.md
Logs a message containing markup tags. The [green] and [/] tags are rendered by terminal writers or stripped by text-based writers.
```csharp
logger.InfoMarkup("[green]ready[/]");
```
--------------------------------
### Style customization with TerminalLogWriter
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/terminal-visuals.md
C# code configuring TerminalLogWriter with rich formatting, markup messages, and custom styles for log segments and levels.
```csharp
var writer = new TerminalLogWriter()
{
EnableRichFormatting = true,
EnableMarkupMessages = true,
};
writer.Styles.Clear();
writer.Styles.SetStyle(LogMessageFormatSegmentKind.Timestamp, "dim");
writer.Styles.SetStyle(LogMessageFormatSegmentKind.LoggerName, "blue");
writer.Styles.SetLevelStyle(LogLevel.Info, "green");
writer.Styles.SetLevelStyle(LogLevel.Warn, "bold yellow");
writer.Styles.SetLevelStyle(LogLevel.Error, "bold white on red");
```
--------------------------------
### JSON-lines logging with JsonLogFormatterOptions
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/file-writer.md
Passes JsonLogFormatterOptions to JsonFileLogWriter to use the Elastic Common Schema profile, include exceptions, and disable scopes.
```csharp
using XenoAtom.Logging.Formatters;
var writer = new JsonFileLogWriter(
new FileLogWriterOptions("logs/app.jsonl")
{
RollingInterval = FileRollingInterval.Daily
},
new JsonLogFormatterOptions
{
SchemaProfile = JsonLogSchemaProfile.ElasticCommonSchema,
IncludeException = true,
IncludeScopes = false
});
```
--------------------------------
### Replace default formatter with JsonLogFormatter
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/file-writer.md
Configures FileLogWriterOptions with a JsonLogFormatter that includes properties and scopes. Use this to change the default StandardLogFormatter to JSON output.
```csharp
var options = new FileLogWriterOptions("logs/app.log")
{
Formatter = new JsonLogFormatter(includeProperties: true, includeScopes: true)
};
var writer = new FileLogWriter(options);
```
--------------------------------
### Field placeholder syntax
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/log-formatter.md
Shows the general shape of a field placeholder: {FieldName[,alignment][:format]}. Field names are case-insensitive, whitespace is trimmed, and values are not truncated when longer than alignment width.
```text
{FieldName[,alignment][:format]}
```
--------------------------------
### MEL LoggerMessageAttribute source generator
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/microsoft-extensions-logging.md
Defines a partial method with LoggerMessageAttribute for source-generated logging in MEL.
```csharp
[LoggerMessage(EventId = 1, Level = LogLevel.Information, Message = "Processing item {ItemId}")]
public static partial void ProcessingItem(ILogger logger, int itemId);
```
--------------------------------
### Override TimestampFormat and LevelFormat with with expression
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/log-formatter.md
Creates a StandardLogFormatter instance with a custom timestamp format and long level format. Defaults are Tri for LevelFormat and "yyyy-MM-dd HH:mm:ss.fffffff" for TimestampFormat unless overridden.
```csharp
using XenoAtom.Logging;
using XenoAtom.Logging.Formatters;
var formatter = StandardLogFormatter.Instance with
{
TimestampFormat = "HH:mm:ss",
LevelFormat = LogLevelFormat.Long
};
```
--------------------------------
### Configure terminal writer styles for segments
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/log-formatter.md
Clears existing styles and sets styles for timestamp and error level. TerminalLogWriter uses these segment kinds to apply styling.
```csharp
terminalWriter.Styles.Clear();
terminalWriter.Styles.SetStyle(LogMessageFormatSegmentKind.Timestamp, "dim");
terminalWriter.Styles.SetLevelStyle(LogLevel.Error, "bold white on red");
```
--------------------------------
### Override styles with SegmentStyleResolver
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/terminal.md
Sets a SegmentStyleResolver that returns a style for EventId segments, otherwise null to fall back to Styles.
```csharp
writer.SegmentStyleResolver = (kind, level) =>
kind == LogMessageFormatSegmentKind.EventId ? "bold magenta" : null;
```
--------------------------------
### Interpolated markup messages escape formatted values
Source: https://github.com/xenoatom/xenoatom.logging/blob/main/site/docs/terminal.md
Shows that interpolated values in markup messages are escaped, so user input is rendered literally.
```csharp
var userInput = "[red]not a tag[/]";
logger.InfoMarkup($"User input: {userInput}");
```