[backend/logging] Display log level in text form in systemd logs

This commit is contained in:
Laura Hausmann 2024-06-16 21:36:38 +02:00
parent 98ea655d3f
commit 8732f30563
No known key found for this signature in database
GPG key ID: D044E84C5BE01605
3 changed files with 74 additions and 15 deletions

View file

@ -5,9 +5,21 @@ namespace Iceshrimp.Backend.Core.Extensions;
public static class ConsoleLoggerExtensions public static class ConsoleLoggerExtensions
{ {
public static ILoggingBuilder AddCustomConsoleFormatter(this ILoggingBuilder builder) => public static ILoggingBuilder AddCustomConsoleFormatter(this ILoggingBuilder builder)
{
if (Environment.GetEnvironmentVariable("INVOCATION_ID") is null)
{
builder.AddConsole(options => options.FormatterName = "systemd-custom")
.AddConsoleFormatter<CustomSystemdConsoleFormatter, ConsoleFormatterOptions>();
}
else
{
builder.AddConsole(options => options.FormatterName = "custom") builder.AddConsole(options => options.FormatterName = "custom")
.AddConsoleFormatter<CustomFormatter, ConsoleFormatterOptions>(); .AddConsoleFormatter<CustomFormatter, ConsoleFormatterOptions>();
}
return builder;
}
} }
/* /*
@ -249,4 +261,62 @@ file sealed class CustomFormatter() : ConsoleFormatter("custom")
} }
} }
file sealed class CustomSystemdConsoleFormatter() : ConsoleFormatter("systemd-custom")
{
public override void Write<TState>(
in LogEntry<TState> logEntry,
IExternalScopeProvider? scopeProvider,
TextWriter textWriter
)
{
var message = logEntry.Formatter(logEntry.State, logEntry.Exception);
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
if (logEntry.Exception == null && message == null) return;
var logLevel = logEntry.LogLevel;
var category = logEntry.Category;
var id = logEntry.EventId.Id;
var exception = logEntry.Exception;
var syslogSeverityString = GetSyslogSeverityString(logLevel);
textWriter.Write(syslogSeverityString);
textWriter.Write(category);
textWriter.Write('[');
textWriter.Write(id);
textWriter.Write(']');
if (!string.IsNullOrEmpty(message))
{
textWriter.Write(' ');
WriteReplacingNewLine(textWriter, message);
}
if (exception != null)
{
textWriter.Write(' ');
WriteReplacingNewLine(textWriter, exception.ToString());
}
textWriter.Write(Environment.NewLine);
static void WriteReplacingNewLine(TextWriter writer, string message)
{
var str = message.Replace(Environment.NewLine, " ");
writer.Write(str);
}
}
private static string GetSyslogSeverityString(LogLevel logLevel)
{
return logLevel switch
{
LogLevel.Trace => "<7>trce: ",
LogLevel.Debug => "<7>dbug: ",
LogLevel.Information => "<6>info: ",
LogLevel.Warning => "<4>warn: ",
LogLevel.Error => "<3>fail: ",
LogLevel.Critical => "<2>crit: ",
_ => throw new ArgumentOutOfRangeException(nameof(logLevel))
};
}
}
#endregion #endregion

View file

@ -177,17 +177,6 @@ public static class ServiceExtensions
services.TryAdd(new ServiceDescriptor(typeof(T), key, typeof(T), contextLifetime)); services.TryAdd(new ServiceDescriptor(typeof(T), key, typeof(T), contextLifetime));
} }
public static void AddLoggingWithOptions(this IServiceCollection services)
{
services.AddLogging(logging =>
{
if (Environment.GetEnvironmentVariable("INVOCATION_ID") is not null)
logging.AddSystemdConsole();
else
logging.AddCustomConsoleFormatter();
});
}
public static void AddSwaggerGenWithOptions(this IServiceCollection services) public static void AddSwaggerGenWithOptions(this IServiceCollection services)
{ {
services.AddEndpointsApiExplorer(); services.AddEndpointsApiExplorer();

View file

@ -18,7 +18,7 @@ builder.Services.AddControllers()
.AddApiBehaviorOptions(); .AddApiBehaviorOptions();
builder.Services.AddSwaggerGenWithOptions(); builder.Services.AddSwaggerGenWithOptions();
builder.Services.AddLoggingWithOptions(); builder.Services.AddLogging(logging => logging.AddCustomConsoleFormatter());
builder.Services.AddDatabaseContext(builder.Configuration); builder.Services.AddDatabaseContext(builder.Configuration);
builder.Services.AddSlidingWindowRateLimiter(); builder.Services.AddSlidingWindowRateLimiter();
builder.Services.AddCorsPolicies(); builder.Services.AddCorsPolicies();