Logging improvements

master
Tudor Stanciu 2023-01-24 19:40:32 +02:00
parent babf2ca282
commit a9b3b5bef7
7 changed files with 83 additions and 36 deletions

View File

@ -2,7 +2,8 @@
<PropertyGroup Label="Package Versions"> <PropertyGroup Label="Package Versions">
<MicrosoftExtensionsPackageVersion>6.0.0</MicrosoftExtensionsPackageVersion> <MicrosoftExtensionsPackageVersion>6.0.0</MicrosoftExtensionsPackageVersion>
<SerilogPackageVersion>6.1.0</SerilogPackageVersion> <SerilogPackageVersion>6.1.0</SerilogPackageVersion>
<SerilogSinksSQLitePackageVersion>5.5.0</SerilogSinksSQLitePackageVersion> <SerilogSinksPostgreSQLPackageVersion>2.3.0</SerilogSinksPostgreSQLPackageVersion>
<SerilogSinksSeqPackageVersion>5.2.2</SerilogSinksSeqPackageVersion>
<SwashbucklePackageVersion>6.2.3</SwashbucklePackageVersion> <SwashbucklePackageVersion>6.2.3</SwashbucklePackageVersion>
<AutoMapperPackageVersion>12.0.1</AutoMapperPackageVersion> <AutoMapperPackageVersion>12.0.1</AutoMapperPackageVersion>
<AutoMapperExtensionsPackageVersion>12.0.0</AutoMapperExtensionsPackageVersion> <AutoMapperExtensionsPackageVersion>12.0.0</AutoMapperExtensionsPackageVersion>

View File

@ -12,7 +12,8 @@
<PackageReference Include="NBB.Messaging.Host" Version="$(NBBPackageVersion)" /> <PackageReference Include="NBB.Messaging.Host" Version="$(NBBPackageVersion)" />
<PackageReference Include="NBB.Messaging.Nats" Version="$(NBBPackageVersion)" /> <PackageReference Include="NBB.Messaging.Nats" Version="$(NBBPackageVersion)" />
<PackageReference Include="Serilog.AspNetCore" Version="$(SerilogPackageVersion)" /> <PackageReference Include="Serilog.AspNetCore" Version="$(SerilogPackageVersion)" />
<PackageReference Include="Serilog.Sinks.SQLite" Version="$(SerilogSinksSQLitePackageVersion)" /> <PackageReference Include="Serilog.Sinks.PostgreSQL" Version="$(SerilogSinksPostgreSQLPackageVersion)" />
<PackageReference Include="Serilog.Sinks.Seq" Version="$(SerilogSinksSeqPackageVersion)" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="$(SwashbucklePackageVersion)" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="$(SwashbucklePackageVersion)" />
</ItemGroup> </ItemGroup>

View File

@ -6,5 +6,10 @@ namespace Correo.Extensions
{ {
public static bool EqualsIgnoreCase(this string value1, string value2) public static bool EqualsIgnoreCase(this string value1, string value2)
=> value1.Equals(value2, StringComparison.InvariantCultureIgnoreCase); => value1.Equals(value2, StringComparison.InvariantCultureIgnoreCase);
public static string Nullify(this string value)
=> string.IsNullOrWhiteSpace(value) ? null : value;
public static bool NotEmpty(this string value) => !string.IsNullOrWhiteSpace(value);
} }
} }

View File

@ -0,0 +1,58 @@
using Microsoft.Extensions.Configuration;
using NpgsqlTypes;
using Serilog;
using Serilog.Sinks.PostgreSQL;
using System;
using System.Collections.Generic;
using System.IO;
namespace Correo.Extensions
{
public static class LoggingExtensions
{
internal static LoggerConfiguration WriteToConfiguredDestinations(this LoggerConfiguration sinkConfiguration, IConfiguration configuration)
{
var workspace = configuration.GetValue<string>("Workspace");
var fileEnabled = configuration.GetValue<bool>("Logs:File:Enabled");
var filePath = configuration.GetValue<string>("Logs:File:Path");
var seqEnabled = configuration.GetValue<bool>("Logs:Seq:Enabled");
var seqUrl = configuration.GetValue<string>("Logs:Seq:Url");
var seqApiKey = configuration.GetValue<string>("Logs:Seq:ApiKey");
var postgresEnabled = configuration.GetValue<bool>("Logs:Postgres:Enabled");
var postgresConnection = configuration.GetValue<string>("Logs:Postgres:Connection");
if (fileEnabled && string.IsNullOrWhiteSpace(filePath))
throw new Exception("If file logging is enabled, the log file path must be configured.");
if (seqEnabled && string.IsNullOrWhiteSpace(seqUrl))
throw new Exception("If Seq logging is enabled, the Seq URL must be configured.");
if (postgresEnabled && string.IsNullOrWhiteSpace(postgresConnection))
throw new Exception("If Postgres logging is enabled, the Postgres connection must be configured.");
if (filePath.NotEmpty() && workspace.NotEmpty())
filePath = Path.Combine(workspace, filePath);
if (fileEnabled)
sinkConfiguration.WriteTo.File(filePath, rollingInterval: RollingInterval.Day);
if (seqEnabled)
sinkConfiguration.WriteTo.Seq(seqUrl, apiKey: seqApiKey.Nullify());
if (postgresEnabled)
{
var columnWriters = new Dictionary<string, ColumnWriterBase>
{
{"message", new RenderedMessageColumnWriter(NpgsqlDbType.Text) },
{"level", new LevelColumnWriter(true, NpgsqlDbType.Varchar) },
{"raise_date", new TimestampColumnWriter(NpgsqlDbType.Timestamp) },
{"exception", new ExceptionColumnWriter(NpgsqlDbType.Text) },
{"event", new LogEventSerializedColumnWriter(NpgsqlDbType.Jsonb) },
{"properties", new PropertiesColumnWriter(NpgsqlDbType.Jsonb) }
};
sinkConfiguration.WriteTo.PostgreSQL(postgresConnection, "correo_logs", columnWriters, needAutoCreateTable: true);
}
return sinkConfiguration;
}
}
}

View File

@ -1,28 +0,0 @@
using Microsoft.Extensions.Configuration;
using System.IO;
using System;
using System.Data.Common;
namespace Correo.Extensions
{
public static class SqliteExtensions
{
internal static string GetDatabasePath(this IConfiguration configuration)
{
var workspace = configuration.GetValue<string>("Workspace");
var connectionString = configuration.GetConnectionString("DatabaseConnection");
if (string.IsNullOrEmpty(workspace))
throw new Exception($"Workspace path is empty! Check 'Workspace' parameter.");
var builder = new DbConnectionStringBuilder
{
ConnectionString = connectionString
};
var dataSource = builder["Data Source"].ToString();
var databasePath = dataSource.Replace("{Workspace}", workspace);
return databasePath;
}
}
}

View File

@ -4,7 +4,6 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Serilog; using Serilog;
using Serilog.Core;
using System; using System;
namespace Correo namespace Correo
@ -18,12 +17,11 @@ namespace Correo
builder.Host.UseSerilog((_, loggerConfiguration) => builder.Host.UseSerilog((_, loggerConfiguration) =>
{ {
var databasePath = builder.Configuration.GetDatabasePath();
loggerConfiguration loggerConfiguration
.ReadFrom.Configuration(builder.Configuration) .ReadFrom.Configuration(builder.Configuration)
.Enrich.FromLogContext() .Enrich.FromLogContext()
.WriteTo.Console() .WriteTo.Console()
.WriteTo.SQLite(databasePath, "__Logs"); .WriteToConfiguredDestinations(builder.Configuration);
}); });
var app = builder.Build(); var app = builder.Build();

View File

@ -1,9 +1,6 @@
{ {
"Urls": "http://*:5005", "Urls": "http://*:5005",
"Workspace": "workspace", "Workspace": "workspace",
"ConnectionStrings": {
"DatabaseConnection": "Data Source={Workspace}/correo.db"
},
"Serilog": { "Serilog": {
"MinimumLevel": { "MinimumLevel": {
"Default": "Warning", "Default": "Warning",
@ -12,6 +9,21 @@
} }
} }
}, },
"Logs": {
"File": {
"Enabled": true,
"Path": "logs/log.txt"
},
"Postgres": {
"Enabled": false,
"Connection": "Host=<host>;Port=5432;User ID=<user>;Password=<password>;Database=<database>;"
},
"Seq": {
"Enabled": false,
"Url": "",
"ApiKey": ""
}
},
"AllowedHosts": "*", "AllowedHosts": "*",
"Messaging": { "Messaging": {
"Enabled": false, "Enabled": false,