A high-performance Serilog formatter that outputs compact JSON optimized for AWS CloudWatch metric filters and structured log analysis.
$ dotnet add package LayeredCraft.Logging.CompactJsonFormatterA high-performance Serilog formatter that outputs compact JSON optimized for AWS CloudWatch metric filters and structured log analysis.
The standard Serilog CompactJsonFormatter uses @ prefixed properties for metadata (like @l for level, @t for timestamp, etc.). However, these @ prefixed properties are not compatible with AWS CloudWatch metric filters, which cannot parse escaped metadata keys.
This formatter solves that problem by replacing the @ prefix with _ (underscore) while maintaining all the performance benefits of the original compact formatter.
_ prefix instead of @ for metadata fieldsCompactJsonFormatterdotnet add package LayeredCraft.Logging.CompactJsonFormatterusing LayeredCraft.Logging.CompactJsonFormatter;
using Serilog;
Log.Logger = new LoggerConfiguration()
.WriteTo.Console(new CompactJsonFormatter())
.CreateLogger();
Log.Information("Hello, {Name}!", "World");using LayeredCraft.Logging.CompactJsonFormatter;
using Serilog;
using Serilog.Formatting.Json;
var customValueFormatter = new JsonValueFormatter(typeTagName: "$type");
Log.Logger = new LoggerConfiguration()
.WriteTo.Console(new CompactJsonFormatter(customValueFormatter))
.CreateLogger();using LayeredCraft.Logging.CompactJsonFormatter;
using Serilog;
using Serilog.Sinks.AwsCloudWatch;
Log.Logger = new LoggerConfiguration()
.WriteTo.AmazonCloudWatch(
logGroup: "/aws/lambda/my-function",
region: RegionEndpoint.USEast1,
formatter: new CompactJsonFormatter())
.CreateLogger();{"@t":"2025-01-14T10:30:00.000Z","@l":"Information","@mt":"Hello, {Name}!","Name":"World"}{"_t":"2025-01-14T10:30:00.000Z","_l":"Information","_mt":"Hello, {Name}!","Name":"World"}| Serilog Standard | LayeredCraft | Description |
|---|---|---|
@t | _t | Timestamp |
@l | _l | Log Level |
@mt | _mt | Message Template |
@m | _m | Rendered Message |
@r | _r | Renderings |
@x | _x | Exception |
@tr | _tr | Trace ID |
@sp | _sp | Span ID |
With the underscore prefix, you can easily create CloudWatch metric filters:
[_l="Error"]
[_l="Warning" && _t > "2025-01-01"]
compact-json-formatter/
├── src/
│ ├── LayeredCraft.Logging.CompactJsonFormatter.csproj
│ └── CompactJsonFormatter.cs
├── test/
│ └── LayeredCraft.Logging.CompactJsonFormatter.Tests.csproj
├── .github/
│ ├── workflows/
│ │ ├── build.yaml
│ │ └── pr-build.yaml
│ └── dependabot.yml
├── Directory.Build.props
├── README.md
├── CLAUDE.md
└── icon.png
dotnet builddotnet testdotnet packThis project is licensed under the MIT License - see the LICENSE file for details.