diff --git a/dependencies.props b/dependencies.props index 7180720..7b5f51f 100644 --- a/dependencies.props +++ b/dependencies.props @@ -2,7 +2,8 @@ 6.0.0 6.1.0 - 5.5.0 + 2.3.0 + 5.2.2 6.2.3 12.0.1 12.0.0 diff --git a/src/Correo/Correo.csproj b/src/Correo/Correo.csproj index c7068b6..c33b1a1 100644 --- a/src/Correo/Correo.csproj +++ b/src/Correo/Correo.csproj @@ -12,7 +12,8 @@ - + + diff --git a/src/Correo/Extensions/DataTypeExtensions.cs b/src/Correo/Extensions/DataTypeExtensions.cs index d6d9b39..c470335 100644 --- a/src/Correo/Extensions/DataTypeExtensions.cs +++ b/src/Correo/Extensions/DataTypeExtensions.cs @@ -6,5 +6,10 @@ namespace Correo.Extensions { public static bool EqualsIgnoreCase(this string value1, string value2) => 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); } } diff --git a/src/Correo/Extensions/LoggingExtensions.cs b/src/Correo/Extensions/LoggingExtensions.cs new file mode 100644 index 0000000..f321566 --- /dev/null +++ b/src/Correo/Extensions/LoggingExtensions.cs @@ -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("Workspace"); + var fileEnabled = configuration.GetValue("Logs:File:Enabled"); + var filePath = configuration.GetValue("Logs:File:Path"); + var seqEnabled = configuration.GetValue("Logs:Seq:Enabled"); + var seqUrl = configuration.GetValue("Logs:Seq:Url"); + var seqApiKey = configuration.GetValue("Logs:Seq:ApiKey"); + var postgresEnabled = configuration.GetValue("Logs:Postgres:Enabled"); + var postgresConnection = configuration.GetValue("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 + { + {"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; + } + } +} diff --git a/src/Correo/Extensions/SqliteExtensions.cs b/src/Correo/Extensions/SqliteExtensions.cs deleted file mode 100644 index af4b8a7..0000000 --- a/src/Correo/Extensions/SqliteExtensions.cs +++ /dev/null @@ -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("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; - } - } -} diff --git a/src/Correo/Program.cs b/src/Correo/Program.cs index 7be9777..dde789d 100644 --- a/src/Correo/Program.cs +++ b/src/Correo/Program.cs @@ -4,7 +4,6 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Serilog; -using Serilog.Core; using System; namespace Correo @@ -18,12 +17,11 @@ namespace Correo builder.Host.UseSerilog((_, loggerConfiguration) => { - var databasePath = builder.Configuration.GetDatabasePath(); loggerConfiguration .ReadFrom.Configuration(builder.Configuration) .Enrich.FromLogContext() .WriteTo.Console() - .WriteTo.SQLite(databasePath, "__Logs"); + .WriteToConfiguredDestinations(builder.Configuration); }); var app = builder.Build(); diff --git a/src/Correo/appsettings.json b/src/Correo/appsettings.json index 78cf10b..edddae8 100644 --- a/src/Correo/appsettings.json +++ b/src/Correo/appsettings.json @@ -1,9 +1,6 @@ { "Urls": "http://*:5005", "Workspace": "workspace", - "ConnectionStrings": { - "DatabaseConnection": "Data Source={Workspace}/correo.db" - }, "Serilog": { "MinimumLevel": { "Default": "Warning", @@ -12,6 +9,21 @@ } } }, + "Logs": { + "File": { + "Enabled": true, + "Path": "logs/log.txt" + }, + "Postgres": { + "Enabled": false, + "Connection": "Host=;Port=5432;User ID=;Password=;Database=;" + }, + "Seq": { + "Enabled": false, + "Url": "", + "ApiKey": "" + } + }, "AllowedHosts": "*", "Messaging": { "Enabled": false,