Comments (8)
Collecting some notes; serilog/serilog-sinks-opentelemetry#50 is another case where clean formatting has been implemented; the amount of code involved makes a pretty strong case for adding a core Serilog API to do this.
from serilog-extensions-logging.
JSON output looks good! Yes, this repo will need changes if we're to pass the cleaner-style messages through to MEL providers.
from serilog-extensions-logging.
Hi, thanks for the ping. That doesn't look like console output - are you using a different sink?
from serilog-extensions-logging.
I'm sorry @nblumhardt, that was misleading. Here's more info, which I hope will prove more useful.
Serilog initialization:
_ = builder.UseSerilog((ctx, loggerConfig) => { /* redacted for clarity */ }, preserveStaticLogger: false, writeToProviders: true);
builder
is IHostBuilder
, writeToProviders
is set to true
.
I additionally configured the OpenTelemetry ILogger:
_ = builder.ConfigureLogging(loggingBuilder =>
{
loggingBuilder.AddOpenTelemetry(o =>
{
o.IncludeFormattedMessage = true;
o.IncludeScopes = true;
});
});
More examples:
Custom log
logger.LogInformation("strings: {QuotedString} {UnquotedString:l}", "quoted string", "unquoted string");
Aspire dashboard output for reference - it's the same formatted message, I assumed the separated non-Serilog OTel exporter is piggybacking on Serilog:
ASP.NET Core log, this should be the original string format: https://github.com/dotnet/aspnetcore/blob/release/8.0/src/Hosting/Hosting/src/Internal/HostingRequestStartingLog.cs#L12
private const string OriginalFormat = "Request starting {Protocol} {Method} {Scheme}://{Host}{PathBase}{Path}{QueryString} - {ContentType} {ContentLength}";
Thank you.
from serilog-extensions-logging.
Thanks; I see 👍 This is the Serilog.Sinks.Console repo, which doesn't play a part in your setup.
For Serilog sinks, the way to disable quoting is to use the ITextFormatter
implementation from Serilog.Expressions. Nothing like that exists for MEL providers (the console and OTel outputs you're using).
I think the Serilog.Extensions.Logging project would be the most likely place this could be addressed, if it turns out to be possible. I'll transfer the issue there and hopefully someone will spot it and take a look at what's involved. Cheers!
from serilog-extensions-logging.
Thanks, @nblumhardt.
I just realized the console output was duplicated: both Serilog's Console sink and MEL's Console sink were outputting to stdout - hence the wrong screenshot above; apologies for the confusion.
Serilog's Console rendering looks fine.
I amended the configuration:
_ = builder.ConfigureLogging(loggingBuilder =>
{
loggingBuilder.ClearProviders(); // <-- remove MEL Console sink
loggingBuilder.AddOpenTelemetry(o =>
{
o.IncludeFormattedMessage = true;
o.IncludeScopes = true;
configurator.ConfigureOpenTelemetryLogger(o);
});
});
Before calling
_ = builder.UseSerilog((ctx, loggerConfig) => { /* redacted for clarity */ }, preserveStaticLogger: false, writeToProviders: true);
with writeToProviders = true
.
By the way, this is the configuration I'm using so I assumed it was Serilog.Sinks.Console
the culprit but it's clearly something else affecting the output to other sinks just as you said.
{
"Serilog": {
"Using": [
"Serilog.Sinks.Console"
],
"MinimumLevel": {
"Default": "Information"
},
"WriteTo": [
{
"Name": "Async",
"Args": {
"configure": [
{
"Name": "Console",
"Args": {
"theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console",
"outputTemplate": "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}: {Message:lj}{NewLine}{Exception}"
}
}
]
}
}
],
"Enrich": [
"FromLogContext",
"WithMachineName",
"WithProcessId",
"WithThreadId"
]
}
}
Odd enough, I enabled a custom formatter inheriting from ExceptionAsObjectJsonFormatter
and the double quotes are there again - I assume there's something I can do on my own here like writing a formatter from scratch or copying it from somewhere.
Configuration:
{
"Serilog": {
"Using": [
"Serilog.Sinks.Console"
],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Audit": "Verbose"
}
},
"WriteTo": [
{
"Name": "Async",
"Args": {
"configure": [
{
"Name": "Console",
"Args": {
"formatter": "MyNamespace.ElasticStackFormatter, MyAssembly"
}
}
]
}
}
],
"Enrich": [
"FromLogContext",
"WithMachineName",
"WithProcessId",
"WithThreadId"
]
}
}
The formatter - it's not much at all, really
internal sealed class ElasticStackFormatter
: ExceptionAsObjectJsonFormatter
{
public ElasticStackFormatter(bool omitEnclosingObject = false,
string? closingDelimiter = null,
bool renderMessage = true,
IFormatProvider? formatProvider = null,
ISerializer? serializer = null,
bool inlineFields = false,
bool renderMessageTemplate = true,
bool formatStackTraceAsArray = false)
: base(omitEnclosingObject,
closingDelimiter,
renderMessage,
formatProvider,
serializer,
inlineFields,
renderMessageTemplate,
formatStackTraceAsArray)
{
}
}
The output:
{
"@timestamp": "2024-06-19T15:52:44.9203512+02:00",
"level": "Information",
"messageTemplate": "Request starting {Protocol} {Method} {Scheme}://{Host}{PathBase}{Path}{QueryString} - {ContentType} {ContentLength}",
"message": "Request starting \"HTTP/1.1\" \"GET\" \"http\"://\"localhost:3244\"\"\"\"/swagger/v1/swagger.json\"\"\" - null null",
"fields": {
"Protocol": "HTTP/1.1",
"Method": "GET",
"ContentType": null,
"ContentLength": null,
"Scheme": "http",
"Host": "localhost:3244",
"PathBase": "",
"Path": "/swagger/v1/swagger.json",
"QueryString": "",
"EventId": {
"Id": 1
},
"SourceContext": "Microsoft.AspNetCore.Hosting.Diagnostics",
"RequestId": "0HN4GCSC288FE:00000002",
"RequestPath": "/swagger/v1/swagger.json",
"ConnectionId": "0HN4GCSC288FE",
"MachineName": "NOTEBOOK",
"ProcessId": 33980,
"ThreadId": 19
}
}
Still, it would be nice to format the message once for all downstream consumers, as it were.
from serilog-extensions-logging.
Hi @rcollina,
The quoted string output is produced by the default MessageTemplate.Render()
, I looked into changing this fairly recently but there's a lot of existing historical usage that would likely break, so this is indefinitely on hold.
Serilog.Exprssions provides a flexible formatter that can be used in a variety of situations, and implements the same interface as your custom formatter above. The Serilog.Expressions formatter option looks like:
// dotnet add package Serilog.Expressions
var formatter = new ExpressionTemplate(
"{ { '@timestamp': @t, level: @l, message: @m, messageTemplate: @mt, fields: @p, exception: Inspect(@x) } }");
Aside from that I think we'll look at making it easier for components/sinks to use the more modern rendering style - some work is needed though.
from serilog-extensions-logging.
Hello @nblumhardt,
Thank you. Your suggestion helps - JSON output looks okay now.
{
"@timestamp": "2024-06-21T12:49:58.8373640+02:00",
"level": "Information",
"message": "Request starting HTTP/1.1 GET http://localhost:3244/swagger/v1/swagger.json - null null",
"messageTemplate": "Request starting {Protocol} {Method} {Scheme}://{Host}{PathBase}{Path}{QueryString} - {ContentType} {ContentLength}",
"fields": {
"Protocol": "HTTP/1.1",
"Method": "GET",
"ContentType": null,
"ContentLength": null,
"Scheme": "http",
"Host": "localhost:3244",
"PathBase": "",
"Path": "/swagger/v1/swagger.json",
"QueryString": "",
"EventId": {
"Id": 1
},
"SourceContext": "Microsoft.AspNetCore.Hosting.Diagnostics",
"RequestId": "0HN4HRVI3MEPK:00000002",
"RequestPath": "/swagger/v1/swagger.json",
"ConnectionId": "0HN4HRVI3MEPK",
"MachineName": "NOTEBOOK",
"ProcessId": 23312,
"ThreadId": 10
}
}
However, this has no impact on what gets passed to MEL ILoggers - so I assume MessageTemplate.Render()
is hardcoded somewhere. Unless there's a configuration that gets passed down through the layers just before MEL's ILogger that may apply here?
from serilog-extensions-logging.
Related Issues (20)
- AWSSeriLog not working with Maui Blazor App HOT 1
- No exceptions emitted when generated by faulty audit log configuration HOT 4
- Upgrade codebase HOT 2
- Serilog keeps throwing ArgumentNullException HOT 10
- Add API approval test
- Could not load file or assembly 'Microsoft.Extensions.Logging, Version=7.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60' HOT 2
- Serilog.Extensions.Logging 7.0.0 has a .NET 6.0 TFM with dependencies on 7.0 HOT 3
- Serilog.Extensions.Logging v7 .net6 requires v7 Microsoft.Extensions.Logging pkg
- Unit tests fail when run for .Net Framework HOT 2
- SerilogLogger.cs - Always calls formatter with the Exception parameter as null HOT 1
- SerilogLogger.cs: PrepareWrite Method not found Serilog.Events.LogEvent..ctor HOT 3
- Serilog .NET 8 Windows Service (worker) using BackgroundService Log file not found HOT 2
- Pass-through of `M.E.L.ILogger.BeginScope()` when using custom MEL `ILoggingProvider` as Serilog sink? HOT 5
- Avoid boxing of TState HOT 6
- M.E.L. Log category support exists but is non-obvious on how to include it in text sinks
- Support ActivityTrackingOptions to enrich logs with Activity tags and baggage HOT 5
- Collision with Microsoft.Extensions.Telemetry HOT 1
- `ISupportExternalScope` enrichment HOT 4
- Serilog ignores dotnet logging configuration HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from serilog-extensions-logging.