mirror of
https://github.com/PluralKit/PluralKit.git
synced 2026-02-03 20:46:48 +00:00
feat(dotnet): json stdout logging
This commit is contained in:
parent
c56fd36023
commit
0fa0070d41
12 changed files with 348 additions and 140 deletions
4
.gitmodules
vendored
4
.gitmodules
vendored
|
|
@ -0,0 +1,4 @@
|
|||
[submodule "Serilog"]
|
||||
path = Serilog
|
||||
url = https://github.com/pluralkit/serilog
|
||||
branch = f5eb991cb4c4a0c1e2407de7504c543536786598
|
||||
|
|
@ -32,6 +32,6 @@
|
|||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning" Version="5.1.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer" Version="5.1.0" />
|
||||
<PackageReference Include="Sentry" Version="4.13.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ public class Startup
|
|||
builder.RegisterInstance(InitUtils.BuildConfiguration(Environment.GetCommandLineArgs()).Build())
|
||||
.As<IConfiguration>();
|
||||
builder.RegisterModule(new ConfigModule<ApiConfig>("API"));
|
||||
builder.RegisterModule(new LoggingModule("api",
|
||||
builder.RegisterModule(new LoggingModule("dotnet-api",
|
||||
cfg: new LoggerConfiguration().Filter.ByExcluding(
|
||||
exc => exc.Exception is PKError || exc.Exception.IsUserError()
|
||||
)));
|
||||
|
|
|
|||
|
|
@ -36,17 +36,20 @@
|
|||
},
|
||||
"Serilog.AspNetCore": {
|
||||
"type": "Direct",
|
||||
"requested": "[9.0.0, )",
|
||||
"resolved": "9.0.0",
|
||||
"contentHash": "JslDajPlBsn3Pww1554flJFTqROvK9zz9jONNQgn0D8Lx2Trw8L0A8/n6zEQK1DAZWXrJwiVLw8cnTR3YFuYsg==",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "FAjtKPZ4IzqFQBqZKPv6evcXK/F0ls7RoXI/62Pnx2igkDZ6nZ/jn/C/FxVATqQbEQvtqP+KViWYIe4NZIHa2w==",
|
||||
"dependencies": {
|
||||
"Serilog": "4.2.0",
|
||||
"Serilog.Extensions.Hosting": "9.0.0",
|
||||
"Serilog.Formatting.Compact": "3.0.0",
|
||||
"Serilog.Settings.Configuration": "9.0.0",
|
||||
"Serilog.Sinks.Console": "6.0.0",
|
||||
"Serilog.Sinks.Debug": "3.0.0",
|
||||
"Serilog.Sinks.File": "6.0.0"
|
||||
"Microsoft.Extensions.DependencyInjection": "8.0.0",
|
||||
"Microsoft.Extensions.Logging": "8.0.0",
|
||||
"Serilog": "3.1.1",
|
||||
"Serilog.Extensions.Hosting": "8.0.0",
|
||||
"Serilog.Extensions.Logging": "8.0.0",
|
||||
"Serilog.Formatting.Compact": "2.0.0",
|
||||
"Serilog.Settings.Configuration": "8.0.0",
|
||||
"Serilog.Sinks.Console": "5.0.0",
|
||||
"Serilog.Sinks.Debug": "2.0.0",
|
||||
"Serilog.Sinks.File": "5.0.0"
|
||||
}
|
||||
},
|
||||
"App.Metrics": {
|
||||
|
|
@ -296,21 +299,21 @@
|
|||
},
|
||||
"Microsoft.Extensions.DependencyModel": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.0",
|
||||
"contentHash": "saxr2XzwgDU77LaQfYFXmddEDRUKHF4DaGMZkNB3qjdVSZlax3//dGJagJkKrGMIPNZs2jVFXITyCCR6UHJNdA==",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "NSmDw3K0ozNDgShSIpsZcbFIzBX4w28nDag+TfaQujkXGazBm+lid5onlWoCBy4VsLxqnnKjEBbGSJVWJMf43g==",
|
||||
"dependencies": {
|
||||
"System.Text.Encodings.Web": "9.0.0",
|
||||
"System.Text.Json": "9.0.0"
|
||||
"System.Text.Encodings.Web": "8.0.0",
|
||||
"System.Text.Json": "8.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Diagnostics.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.0",
|
||||
"contentHash": "1K8P7XzuzX8W8pmXcZjcrqS6x5eSSdvhQohmcpgiQNY/HlDAlnrhR9dvlURfFz428A+RTCJpUyB+aKTA6AgVcQ==",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "JHYCQG7HmugNYUhOl368g+NMxYE/N/AiclCYRNlgCY9eVyiBkOHMwK4x60RYMxv9EL3+rmj1mqHvdCiPpC+D4Q==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.0",
|
||||
"Microsoft.Extensions.Options": "9.0.0",
|
||||
"System.Diagnostics.DiagnosticSource": "9.0.0"
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0",
|
||||
"Microsoft.Extensions.Options": "8.0.0",
|
||||
"System.Diagnostics.DiagnosticSource": "8.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": {
|
||||
|
|
@ -338,14 +341,14 @@
|
|||
},
|
||||
"Microsoft.Extensions.Hosting.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.0",
|
||||
"contentHash": "yUKJgu81ExjvqbNWqZKshBbLntZMbMVz/P7Way2SBx7bMqA08Mfdc9O7hWDKAiSp+zPUGT6LKcSCQIPeDK+CCw==",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "AG7HWwVRdCHlaA++1oKDxLsXIBxmDpMPb3VoyOoAghEWnkUvEAdYQUwnV4jJbAaa/nMYNiEh5ByoLauZBEiovg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "9.0.0",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.0",
|
||||
"Microsoft.Extensions.Diagnostics.Abstractions": "9.0.0",
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": "9.0.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.0"
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0",
|
||||
"Microsoft.Extensions.Diagnostics.Abstractions": "8.0.0",
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": "8.0.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "8.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
|
|
@ -461,30 +464,25 @@
|
|||
"System.IO.Pipelines": "5.0.1"
|
||||
}
|
||||
},
|
||||
"Serilog": {
|
||||
"type": "Transitive",
|
||||
"resolved": "4.2.0",
|
||||
"contentHash": "gmoWVOvKgbME8TYR+gwMf7osROiWAURterc6Rt2dQyX7wtjZYpqFiA/pY6ztjGQKKV62GGCyOcmtP1UKMHgSmA=="
|
||||
},
|
||||
"Serilog.Extensions.Hosting": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.0",
|
||||
"contentHash": "u2TRxuxbjvTAldQn7uaAwePkWxTHIqlgjelekBtilAGL5sYyF3+65NWctN4UrwwGLsDC7c3Vz3HnOlu+PcoxXg==",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "db0OcbWeSCvYQkHWu6n0v40N4kKaTAXNjlM3BKvcbwvNzYphQFcBR+36eQ/7hMMwOkJvAyLC2a9/jNdUL5NjtQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.0",
|
||||
"Microsoft.Extensions.Hosting.Abstractions": "9.0.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.0",
|
||||
"Serilog": "4.2.0",
|
||||
"Serilog.Extensions.Logging": "9.0.0"
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0",
|
||||
"Microsoft.Extensions.Hosting.Abstractions": "8.0.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "8.0.0",
|
||||
"Serilog": "3.1.1",
|
||||
"Serilog.Extensions.Logging": "8.0.0"
|
||||
}
|
||||
},
|
||||
"Serilog.Extensions.Logging": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.0",
|
||||
"contentHash": "NwSSYqPJeKNzl5AuXVHpGbr6PkZJFlNa14CdIebVjK3k/76kYj/mz5kiTRNVSsSaxM8kAIa1kpy/qyT9E4npRQ==",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "YEAMWu1UnWgf1c1KP85l1SgXGfiVo0Rz6x08pCiPOIBt2Qe18tcZLvdBUuV5o1QHvrs8FAry9wTIhgBRtjIlEg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging": "9.0.0",
|
||||
"Serilog": "4.2.0"
|
||||
"Microsoft.Extensions.Logging": "8.0.0",
|
||||
"Serilog": "3.1.1"
|
||||
}
|
||||
},
|
||||
"Serilog.Formatting.Compact": {
|
||||
|
|
@ -514,12 +512,12 @@
|
|||
},
|
||||
"Serilog.Settings.Configuration": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.0",
|
||||
"contentHash": "4/Et4Cqwa+F88l5SeFeNZ4c4Z6dEAIKbu3MaQb2Zz9F/g27T5a3wvfMcmCOaAiACjfUb4A6wrlTVfyYUZk3RRQ==",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "nR0iL5HwKj5v6ULo3/zpP8NMcq9E2pxYA6XKTSWCbugVs4YqPyvaqaKOY+OMpPivKp7zMEpax2UKHnDodbRB0Q==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Binder": "9.0.0",
|
||||
"Microsoft.Extensions.DependencyModel": "9.0.0",
|
||||
"Serilog": "4.2.0"
|
||||
"Microsoft.Extensions.Configuration.Binder": "8.0.0",
|
||||
"Microsoft.Extensions.DependencyModel": "8.0.0",
|
||||
"Serilog": "3.1.1"
|
||||
}
|
||||
},
|
||||
"Serilog.Sinks.Async": {
|
||||
|
|
@ -540,10 +538,10 @@
|
|||
},
|
||||
"Serilog.Sinks.Debug": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "4BzXcdrgRX7wde9PmHuYd9U6YqycCC28hhpKonK7hx0wb19eiuRj16fPcPSVp0o/Y1ipJuNLYQ00R3q2Zs8FDA==",
|
||||
"resolved": "2.0.0",
|
||||
"contentHash": "Y6g3OBJ4JzTyyw16fDqtFcQ41qQAydnEvEqmXjhwhgjsnG/FaJ8GUqF5ldsC/bVkK8KYmqrPhDO+tm4dF6xx4A==",
|
||||
"dependencies": {
|
||||
"Serilog": "4.0.0"
|
||||
"Serilog": "2.10.0"
|
||||
}
|
||||
},
|
||||
"Serilog.Sinks.Elasticsearch": {
|
||||
|
|
@ -837,8 +835,8 @@
|
|||
"NodaTime.Serialization.JsonNet": "[3.1.0, )",
|
||||
"Npgsql": "[9.0.2, )",
|
||||
"Npgsql.NodaTime": "[9.0.2, )",
|
||||
"Serilog": "[4.2.0, )",
|
||||
"Serilog.Extensions.Logging": "[9.0.0, )",
|
||||
"Serilog": "[4.1.0, )",
|
||||
"Serilog.Extensions.Logging": "[8.0.0, )",
|
||||
"Serilog.Formatting.Compact": "[3.0.0, )",
|
||||
"Serilog.NodaTime": "[3.0.0, )",
|
||||
"Serilog.Sinks.Async": "[2.1.0, )",
|
||||
|
|
@ -852,6 +850,9 @@
|
|||
"System.Interactive.Async": "[6.0.1, )",
|
||||
"ipnetwork2": "[3.0.667, )"
|
||||
}
|
||||
},
|
||||
"serilog": {
|
||||
"type": "Project"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ public class Init
|
|||
var builder = new ContainerBuilder();
|
||||
builder.RegisterInstance(config);
|
||||
builder.RegisterModule(new ConfigModule<BotConfig>("Bot"));
|
||||
builder.RegisterModule(new LoggingModule("bot"));
|
||||
builder.RegisterModule(new LoggingModule("dotnet-bot"));
|
||||
builder.RegisterModule(new MetricsModule());
|
||||
builder.RegisterModule<DataStoreModule>();
|
||||
builder.RegisterModule<BotModule>();
|
||||
|
|
|
|||
|
|
@ -423,11 +423,11 @@
|
|||
},
|
||||
"Serilog.Extensions.Logging": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.0",
|
||||
"contentHash": "NwSSYqPJeKNzl5AuXVHpGbr6PkZJFlNa14CdIebVjK3k/76kYj/mz5kiTRNVSsSaxM8kAIa1kpy/qyT9E4npRQ==",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "YEAMWu1UnWgf1c1KP85l1SgXGfiVo0Rz6x08pCiPOIBt2Qe18tcZLvdBUuV5o1QHvrs8FAry9wTIhgBRtjIlEg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging": "9.0.0",
|
||||
"Serilog": "4.2.0"
|
||||
"Microsoft.Extensions.Logging": "8.0.0",
|
||||
"Serilog": "3.1.1"
|
||||
}
|
||||
},
|
||||
"Serilog.Formatting.Compact": {
|
||||
|
|
@ -796,8 +796,8 @@
|
|||
"NodaTime.Serialization.JsonNet": "[3.1.0, )",
|
||||
"Npgsql": "[9.0.2, )",
|
||||
"Npgsql.NodaTime": "[9.0.2, )",
|
||||
"Serilog": "[4.2.0, )",
|
||||
"Serilog.Extensions.Logging": "[9.0.0, )",
|
||||
"Serilog": "[4.1.0, )",
|
||||
"Serilog.Extensions.Logging": "[8.0.0, )",
|
||||
"Serilog.Formatting.Compact": "[3.0.0, )",
|
||||
"Serilog.NodaTime": "[3.0.0, )",
|
||||
"Serilog.Sinks.Async": "[2.1.0, )",
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ using NodaTime;
|
|||
|
||||
using Serilog;
|
||||
using Serilog.Events;
|
||||
using Serilog.Formatting.Compact;
|
||||
using Serilog.Sinks.Seq;
|
||||
using Serilog.Formatting.Json;
|
||||
using Serilog.Sinks.SystemConsole.Themes;
|
||||
|
||||
using ILogger = Serilog.ILogger;
|
||||
|
|
@ -50,14 +49,9 @@ public class LoggingModule: Module
|
|||
|
||||
private ILogger InitLogger(CoreConfig config)
|
||||
{
|
||||
var consoleTemplate = "[{Timestamp:HH:mm:ss.fff}] {Level:u3} {Message:lj}{NewLine}{Exception}";
|
||||
var outputTemplate = "[{Timestamp:yyyy-MM-dd HH:mm:ss.ffffff}] {Level:u3} {Message:lj}{NewLine}{Exception}";
|
||||
|
||||
var logCfg = _cfg
|
||||
.Enrich.FromLogContext()
|
||||
.Enrich.WithProperty("GitCommitHash", BuildInfoService.FullVersion)
|
||||
.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb)
|
||||
.Enrich.WithProperty("Component", _component)
|
||||
.MinimumLevel.Is(config.ConsoleLogLevel)
|
||||
|
||||
// Don't want App.Metrics/D#+ spam
|
||||
|
|
@ -75,9 +69,8 @@ public class LoggingModule: Module
|
|||
.Destructure.With<PatchObjectDestructuring>()
|
||||
.WriteTo.Async(a =>
|
||||
a.Console(
|
||||
theme: AnsiConsoleTheme.Code,
|
||||
outputTemplate: consoleTemplate,
|
||||
restrictedToMinimumLevel: config.ConsoleLogLevel));
|
||||
new CustomJsonFormatter(_component),
|
||||
config.ConsoleLogLevel));
|
||||
|
||||
if (config.ElasticUrl != null)
|
||||
{
|
||||
|
|
@ -89,15 +82,6 @@ public class LoggingModule: Module
|
|||
);
|
||||
}
|
||||
|
||||
if (config.SeqLogUrl != null)
|
||||
{
|
||||
logCfg.WriteTo.Seq(
|
||||
config.SeqLogUrl,
|
||||
restrictedToMinimumLevel: LogEventLevel.Verbose
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
_fn.Invoke(logCfg);
|
||||
return Log.Logger = logCfg.CreateLogger();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,10 @@
|
|||
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Serilog\src\Serilog\Serilog.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="App.Metrics" Version="4.3.0" />
|
||||
<PackageReference Include="App.Metrics.Reporting.InfluxDB" Version="4.3.0" />
|
||||
|
|
@ -37,8 +41,7 @@
|
|||
<PackageReference Include="NodaTime.Serialization.JsonNet" Version="3.1.0" />
|
||||
<PackageReference Include="Npgsql" Version="9.0.2" />
|
||||
<PackageReference Include="Npgsql.NodaTime" Version="9.0.2" />
|
||||
<PackageReference Include="Serilog" Version="4.2.0" />
|
||||
<PackageReference Include="Serilog.Extensions.Logging" Version="9.0.0" />
|
||||
<PackageReference Include="Serilog.Extensions.Logging" Version="8.0.0" />
|
||||
<PackageReference Include="Serilog.Formatting.Compact" Version="3.0.0" />
|
||||
<PackageReference Include="Serilog.NodaTime" Version="3.0.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Async" Version="2.1.0" />
|
||||
|
|
|
|||
215
PluralKit.Core/Utils/SerilogJsonFormatter.cs
Normal file
215
PluralKit.Core/Utils/SerilogJsonFormatter.cs
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
|
||||
using Serilog.Events;
|
||||
using Serilog.Formatting;
|
||||
using Serilog.Formatting.Json;
|
||||
using Serilog.Parsing;
|
||||
using Serilog.Rendering;
|
||||
|
||||
// Customized Serilog JSON output for PluralKit
|
||||
|
||||
// Copyright 2013-2015 Serilog Contributors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
namespace PluralKit.Core;
|
||||
|
||||
static class Guard
|
||||
{
|
||||
public static T AgainstNull<T>(
|
||||
T? argument,
|
||||
[CallerArgumentExpression("argument")] string? paramName = null)
|
||||
where T : class
|
||||
{
|
||||
if (argument is null)
|
||||
{
|
||||
throw new ArgumentNullException(paramName);
|
||||
}
|
||||
|
||||
return argument;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formats log events in a simple JSON structure. Instances of this class
|
||||
/// are safe for concurrent access by multiple threads.
|
||||
/// </summary>
|
||||
/// <remarks>New code should prefer formatters from <c>Serilog.Formatting.Compact</c>, or <c>ExpressionTemplate</c> from
|
||||
/// <c>Serilog.Expressions</c>.</remarks>
|
||||
public sealed class CustomJsonFormatter: ITextFormatter
|
||||
{
|
||||
readonly JsonValueFormatter _jsonValueFormatter = new();
|
||||
readonly string _component;
|
||||
|
||||
/// <summary>
|
||||
/// Construct a <see cref="JsonFormatter"/>.
|
||||
/// </summary>
|
||||
/// <param name="closingDelimiter">A string that will be written after each log event is formatted.
|
||||
/// If null, <see cref="Environment.NewLine"/> will be used.</param>
|
||||
/// <param name="renderMessage">If <see langword="true"/>, the message will be rendered and written to the output as a
|
||||
/// property named RenderedMessage.</param>
|
||||
/// <param name="formatProvider">Supplies culture-specific formatting information, or null.</param>
|
||||
public CustomJsonFormatter(string component)
|
||||
{
|
||||
_component = component;
|
||||
}
|
||||
|
||||
private string CustomLevelString(LogEventLevel level)
|
||||
{
|
||||
switch (level)
|
||||
{
|
||||
case LogEventLevel.Verbose:
|
||||
return "TRACE";
|
||||
case LogEventLevel.Debug:
|
||||
return "DEBUG";
|
||||
case LogEventLevel.Information:
|
||||
return "INFO";
|
||||
case LogEventLevel.Warning:
|
||||
return "WARN";
|
||||
case LogEventLevel.Error:
|
||||
return "ERROR";
|
||||
case LogEventLevel.Fatal:
|
||||
return "FATAL";
|
||||
};
|
||||
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Format the log event into the output.
|
||||
/// </summary>
|
||||
/// <param name="logEvent">The event to format.</param>
|
||||
/// <param name="output">The output.</param>
|
||||
/// <exception cref="ArgumentNullException">When <paramref name="logEvent"/> is <code>null</code></exception>
|
||||
/// <exception cref="ArgumentNullException">When <paramref name="output"/> is <code>null</code></exception>
|
||||
public void Format(LogEvent logEvent, TextWriter output)
|
||||
{
|
||||
Guard.AgainstNull(logEvent);
|
||||
Guard.AgainstNull(output);
|
||||
|
||||
output.Write("{\"component\":\"");
|
||||
output.Write(_component);
|
||||
output.Write("\",\"timestamp\":\"");
|
||||
output.Write(logEvent.Timestamp.ToString("O").Replace("+00:00", "Z"));
|
||||
output.Write("\",\"level\":\"");
|
||||
output.Write(CustomLevelString(logEvent.Level));
|
||||
|
||||
output.Write("\",\"message\":");
|
||||
var message = logEvent.MessageTemplate.Render(logEvent.Properties);
|
||||
JsonValueFormatter.WriteQuotedJsonString(message, output);
|
||||
|
||||
if (logEvent.TraceId != null)
|
||||
{
|
||||
output.Write(",\"TraceId\":");
|
||||
JsonValueFormatter.WriteQuotedJsonString(logEvent.TraceId.ToString()!, output);
|
||||
}
|
||||
|
||||
if (logEvent.SpanId != null)
|
||||
{
|
||||
output.Write(",\"SpanId\":");
|
||||
JsonValueFormatter.WriteQuotedJsonString(logEvent.SpanId.ToString()!, output);
|
||||
}
|
||||
|
||||
if (logEvent.Exception != null)
|
||||
{
|
||||
output.Write(",\"Exception\":");
|
||||
JsonValueFormatter.WriteQuotedJsonString(logEvent.Exception.ToString(), output);
|
||||
}
|
||||
|
||||
if (logEvent.Properties.Count != 0)
|
||||
{
|
||||
output.Write(",\"Properties\":{");
|
||||
|
||||
char? propertyDelimiter = null;
|
||||
foreach (var property in logEvent.Properties)
|
||||
{
|
||||
if (propertyDelimiter != null)
|
||||
output.Write(propertyDelimiter.Value);
|
||||
else
|
||||
propertyDelimiter = ',';
|
||||
|
||||
JsonValueFormatter.WriteQuotedJsonString(property.Key, output);
|
||||
output.Write(':');
|
||||
_jsonValueFormatter.Format(property.Value, output);
|
||||
}
|
||||
|
||||
output.Write('}');
|
||||
}
|
||||
|
||||
var tokensWithFormat = logEvent.MessageTemplate.Tokens
|
||||
.OfType<PropertyToken>()
|
||||
.Where(pt => pt.Format != null)
|
||||
.GroupBy(pt => pt.PropertyName)
|
||||
.ToArray();
|
||||
|
||||
if (tokensWithFormat.Length != 0)
|
||||
{
|
||||
output.Write(",\"Renderings\":{");
|
||||
WriteRenderingsValues(tokensWithFormat, logEvent.Properties, output);
|
||||
output.Write('}');
|
||||
}
|
||||
|
||||
output.Write('}');
|
||||
output.Write("\n");
|
||||
}
|
||||
|
||||
void WriteRenderingsValues(IEnumerable<IGrouping<string, PropertyToken>> tokensWithFormat, IReadOnlyDictionary<string, LogEventPropertyValue> properties, TextWriter output)
|
||||
{
|
||||
static void WriteNameValuePair(string name, string value, ref char? precedingDelimiter, TextWriter output)
|
||||
{
|
||||
if (precedingDelimiter != null)
|
||||
output.Write(precedingDelimiter.Value);
|
||||
|
||||
JsonValueFormatter.WriteQuotedJsonString(name, output);
|
||||
output.Write(':');
|
||||
JsonValueFormatter.WriteQuotedJsonString(value, output);
|
||||
precedingDelimiter = ',';
|
||||
}
|
||||
|
||||
char? propertyDelimiter = null;
|
||||
foreach (var propertyFormats in tokensWithFormat)
|
||||
{
|
||||
if (propertyDelimiter != null)
|
||||
output.Write(propertyDelimiter.Value);
|
||||
else
|
||||
propertyDelimiter = ',';
|
||||
|
||||
output.Write('"');
|
||||
output.Write(propertyFormats.Key);
|
||||
output.Write("\":[");
|
||||
|
||||
char? formatDelimiter = null;
|
||||
foreach (var format in propertyFormats)
|
||||
{
|
||||
if (formatDelimiter != null)
|
||||
output.Write(formatDelimiter.Value);
|
||||
|
||||
formatDelimiter = ',';
|
||||
|
||||
output.Write('{');
|
||||
char? elementDelimiter = null;
|
||||
|
||||
// Caller ensures that `tokensWithFormat` contains only property tokens that have non-null `Format`s.
|
||||
WriteNameValuePair("Format", format.Format!, ref elementDelimiter, output);
|
||||
|
||||
using var sw = ReusableStringWriter.GetOrCreate();
|
||||
MessageTemplateRenderer.RenderPropertyToken(format, properties, sw, null, isLiteral: true, isJson: false);
|
||||
WriteNameValuePair("Rendering", sw.ToString(), ref elementDelimiter, output);
|
||||
|
||||
output.Write('}');
|
||||
}
|
||||
|
||||
output.Write(']');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -198,20 +198,14 @@
|
|||
"Npgsql": "9.0.2"
|
||||
}
|
||||
},
|
||||
"Serilog": {
|
||||
"type": "Direct",
|
||||
"requested": "[4.2.0, )",
|
||||
"resolved": "4.2.0",
|
||||
"contentHash": "gmoWVOvKgbME8TYR+gwMf7osROiWAURterc6Rt2dQyX7wtjZYpqFiA/pY6ztjGQKKV62GGCyOcmtP1UKMHgSmA=="
|
||||
},
|
||||
"Serilog.Extensions.Logging": {
|
||||
"type": "Direct",
|
||||
"requested": "[9.0.0, )",
|
||||
"resolved": "9.0.0",
|
||||
"contentHash": "NwSSYqPJeKNzl5AuXVHpGbr6PkZJFlNa14CdIebVjK3k/76kYj/mz5kiTRNVSsSaxM8kAIa1kpy/qyT9E4npRQ==",
|
||||
"requested": "[8.0.0, )",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "YEAMWu1UnWgf1c1KP85l1SgXGfiVo0Rz6x08pCiPOIBt2Qe18tcZLvdBUuV5o1QHvrs8FAry9wTIhgBRtjIlEg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging": "9.0.0",
|
||||
"Serilog": "4.2.0"
|
||||
"Microsoft.Extensions.Logging": "8.0.0",
|
||||
"Serilog": "3.1.1"
|
||||
}
|
||||
},
|
||||
"Serilog.Formatting.Compact": {
|
||||
|
|
@ -722,6 +716,9 @@
|
|||
"Microsoft.NETCore.Targets": "1.1.0",
|
||||
"System.Runtime": "4.3.0"
|
||||
}
|
||||
},
|
||||
"serilog": {
|
||||
"type": "Project"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -320,21 +320,21 @@
|
|||
},
|
||||
"Microsoft.Extensions.DependencyModel": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.0",
|
||||
"contentHash": "saxr2XzwgDU77LaQfYFXmddEDRUKHF4DaGMZkNB3qjdVSZlax3//dGJagJkKrGMIPNZs2jVFXITyCCR6UHJNdA==",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "NSmDw3K0ozNDgShSIpsZcbFIzBX4w28nDag+TfaQujkXGazBm+lid5onlWoCBy4VsLxqnnKjEBbGSJVWJMf43g==",
|
||||
"dependencies": {
|
||||
"System.Text.Encodings.Web": "9.0.0",
|
||||
"System.Text.Json": "9.0.0"
|
||||
"System.Text.Encodings.Web": "8.0.0",
|
||||
"System.Text.Json": "8.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Diagnostics.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.0",
|
||||
"contentHash": "1K8P7XzuzX8W8pmXcZjcrqS6x5eSSdvhQohmcpgiQNY/HlDAlnrhR9dvlURfFz428A+RTCJpUyB+aKTA6AgVcQ==",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "JHYCQG7HmugNYUhOl368g+NMxYE/N/AiclCYRNlgCY9eVyiBkOHMwK4x60RYMxv9EL3+rmj1mqHvdCiPpC+D4Q==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.0",
|
||||
"Microsoft.Extensions.Options": "9.0.0",
|
||||
"System.Diagnostics.DiagnosticSource": "9.0.0"
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0",
|
||||
"Microsoft.Extensions.Options": "8.0.0",
|
||||
"System.Diagnostics.DiagnosticSource": "8.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": {
|
||||
|
|
@ -362,14 +362,14 @@
|
|||
},
|
||||
"Microsoft.Extensions.Hosting.Abstractions": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.0",
|
||||
"contentHash": "yUKJgu81ExjvqbNWqZKshBbLntZMbMVz/P7Way2SBx7bMqA08Mfdc9O7hWDKAiSp+zPUGT6LKcSCQIPeDK+CCw==",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "AG7HWwVRdCHlaA++1oKDxLsXIBxmDpMPb3VoyOoAghEWnkUvEAdYQUwnV4jJbAaa/nMYNiEh5ByoLauZBEiovg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "9.0.0",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.0",
|
||||
"Microsoft.Extensions.Diagnostics.Abstractions": "9.0.0",
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": "9.0.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.0"
|
||||
"Microsoft.Extensions.Configuration.Abstractions": "8.0.0",
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0",
|
||||
"Microsoft.Extensions.Diagnostics.Abstractions": "8.0.0",
|
||||
"Microsoft.Extensions.FileProviders.Abstractions": "8.0.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "8.0.0"
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.Logging": {
|
||||
|
|
@ -537,37 +537,40 @@
|
|||
},
|
||||
"Serilog.AspNetCore": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.0",
|
||||
"contentHash": "JslDajPlBsn3Pww1554flJFTqROvK9zz9jONNQgn0D8Lx2Trw8L0A8/n6zEQK1DAZWXrJwiVLw8cnTR3YFuYsg==",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "FAjtKPZ4IzqFQBqZKPv6evcXK/F0ls7RoXI/62Pnx2igkDZ6nZ/jn/C/FxVATqQbEQvtqP+KViWYIe4NZIHa2w==",
|
||||
"dependencies": {
|
||||
"Serilog": "4.2.0",
|
||||
"Serilog.Extensions.Hosting": "9.0.0",
|
||||
"Serilog.Formatting.Compact": "3.0.0",
|
||||
"Serilog.Settings.Configuration": "9.0.0",
|
||||
"Serilog.Sinks.Console": "6.0.0",
|
||||
"Serilog.Sinks.Debug": "3.0.0",
|
||||
"Serilog.Sinks.File": "6.0.0"
|
||||
"Microsoft.Extensions.DependencyInjection": "8.0.0",
|
||||
"Microsoft.Extensions.Logging": "8.0.0",
|
||||
"Serilog": "3.1.1",
|
||||
"Serilog.Extensions.Hosting": "8.0.0",
|
||||
"Serilog.Extensions.Logging": "8.0.0",
|
||||
"Serilog.Formatting.Compact": "2.0.0",
|
||||
"Serilog.Settings.Configuration": "8.0.0",
|
||||
"Serilog.Sinks.Console": "5.0.0",
|
||||
"Serilog.Sinks.Debug": "2.0.0",
|
||||
"Serilog.Sinks.File": "5.0.0"
|
||||
}
|
||||
},
|
||||
"Serilog.Extensions.Hosting": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.0",
|
||||
"contentHash": "u2TRxuxbjvTAldQn7uaAwePkWxTHIqlgjelekBtilAGL5sYyF3+65NWctN4UrwwGLsDC7c3Vz3HnOlu+PcoxXg==",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "db0OcbWeSCvYQkHWu6n0v40N4kKaTAXNjlM3BKvcbwvNzYphQFcBR+36eQ/7hMMwOkJvAyLC2a9/jNdUL5NjtQ==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.0",
|
||||
"Microsoft.Extensions.Hosting.Abstractions": "9.0.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "9.0.0",
|
||||
"Serilog": "4.2.0",
|
||||
"Serilog.Extensions.Logging": "9.0.0"
|
||||
"Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0",
|
||||
"Microsoft.Extensions.Hosting.Abstractions": "8.0.0",
|
||||
"Microsoft.Extensions.Logging.Abstractions": "8.0.0",
|
||||
"Serilog": "3.1.1",
|
||||
"Serilog.Extensions.Logging": "8.0.0"
|
||||
}
|
||||
},
|
||||
"Serilog.Extensions.Logging": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.0",
|
||||
"contentHash": "NwSSYqPJeKNzl5AuXVHpGbr6PkZJFlNa14CdIebVjK3k/76kYj/mz5kiTRNVSsSaxM8kAIa1kpy/qyT9E4npRQ==",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "YEAMWu1UnWgf1c1KP85l1SgXGfiVo0Rz6x08pCiPOIBt2Qe18tcZLvdBUuV5o1QHvrs8FAry9wTIhgBRtjIlEg==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Logging": "9.0.0",
|
||||
"Serilog": "4.2.0"
|
||||
"Microsoft.Extensions.Logging": "8.0.0",
|
||||
"Serilog": "3.1.1"
|
||||
}
|
||||
},
|
||||
"Serilog.Formatting.Compact": {
|
||||
|
|
@ -597,12 +600,12 @@
|
|||
},
|
||||
"Serilog.Settings.Configuration": {
|
||||
"type": "Transitive",
|
||||
"resolved": "9.0.0",
|
||||
"contentHash": "4/Et4Cqwa+F88l5SeFeNZ4c4Z6dEAIKbu3MaQb2Zz9F/g27T5a3wvfMcmCOaAiACjfUb4A6wrlTVfyYUZk3RRQ==",
|
||||
"resolved": "8.0.0",
|
||||
"contentHash": "nR0iL5HwKj5v6ULo3/zpP8NMcq9E2pxYA6XKTSWCbugVs4YqPyvaqaKOY+OMpPivKp7zMEpax2UKHnDodbRB0Q==",
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.Configuration.Binder": "9.0.0",
|
||||
"Microsoft.Extensions.DependencyModel": "9.0.0",
|
||||
"Serilog": "4.2.0"
|
||||
"Microsoft.Extensions.Configuration.Binder": "8.0.0",
|
||||
"Microsoft.Extensions.DependencyModel": "8.0.0",
|
||||
"Serilog": "3.1.1"
|
||||
}
|
||||
},
|
||||
"Serilog.Sinks.Async": {
|
||||
|
|
@ -623,10 +626,10 @@
|
|||
},
|
||||
"Serilog.Sinks.Debug": {
|
||||
"type": "Transitive",
|
||||
"resolved": "3.0.0",
|
||||
"contentHash": "4BzXcdrgRX7wde9PmHuYd9U6YqycCC28hhpKonK7hx0wb19eiuRj16fPcPSVp0o/Y1ipJuNLYQ00R3q2Zs8FDA==",
|
||||
"resolved": "2.0.0",
|
||||
"contentHash": "Y6g3OBJ4JzTyyw16fDqtFcQ41qQAydnEvEqmXjhwhgjsnG/FaJ8GUqF5ldsC/bVkK8KYmqrPhDO+tm4dF6xx4A==",
|
||||
"dependencies": {
|
||||
"Serilog": "4.0.0"
|
||||
"Serilog": "2.10.0"
|
||||
}
|
||||
},
|
||||
"Serilog.Sinks.Elasticsearch": {
|
||||
|
|
@ -993,7 +996,7 @@
|
|||
"Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer": "[5.1.0, )",
|
||||
"PluralKit.Core": "[1.0.0, )",
|
||||
"Sentry": "[4.13.0, )",
|
||||
"Serilog.AspNetCore": "[9.0.0, )"
|
||||
"Serilog.AspNetCore": "[8.0.0, )"
|
||||
}
|
||||
},
|
||||
"pluralkit.bot": {
|
||||
|
|
@ -1029,8 +1032,8 @@
|
|||
"NodaTime.Serialization.JsonNet": "[3.1.0, )",
|
||||
"Npgsql": "[9.0.2, )",
|
||||
"Npgsql.NodaTime": "[9.0.2, )",
|
||||
"Serilog": "[4.2.0, )",
|
||||
"Serilog.Extensions.Logging": "[9.0.0, )",
|
||||
"Serilog": "[4.1.0, )",
|
||||
"Serilog.Extensions.Logging": "[8.0.0, )",
|
||||
"Serilog.Formatting.Compact": "[3.0.0, )",
|
||||
"Serilog.NodaTime": "[3.0.0, )",
|
||||
"Serilog.Sinks.Async": "[2.1.0, )",
|
||||
|
|
|
|||
1
Serilog
Submodule
1
Serilog
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit f5eb991cb4c4a0c1e2407de7504c543536786598
|
||||
Loading…
Add table
Add a link
Reference in a new issue