serilog-contrib / Serilog.Sinks.Postgresql.Alternative

Serilog.Sinks.Postgresql.Alternative is a library to save logging information from https://github.com/serilog/serilog to https://www.postgresql.org/.
MIT License
67 stars 13 forks source link

LogEventSerializedColumnWriter: Modify "Timestamp" JSON value from log_event column to be UTC format #67

Open J-Porras opened 9 months ago

J-Porras commented 9 months ago

Hello everyone Is there a way, preferably trough code, to configure the "Timestamp" property to be UTC? Currently my the JSON looks like this:

{
  "Level": "Information",
  "Timestamp": "2024-03-01T12:07:27.2510933-06:00",
  "Properties": {
    "ClientIp": "::1",
    "RequestId": "97a1fe41-99d3-4c03-8bb2-2a907867537b",
    "ActionName": "API.Controllers.v1 (API)",
    "Environment": "Testing",
    "ProcessName": "",
    "RequestPath": "/",
    "Custom_Properties": {
      "Custom_Message": "Information Response External API"
    },
    "ApplicationName": "API.NAME",
    "EnvironmentUserName": "123"
  },
  "MessageTemplate": "{RequestId}"
}

I would like the "Timestamp" in this format or the closest 2024-03-01 18:07:27.251

I have already managed to change my Created_date column to use timestamp and add custom properties to the Properties key, but I will prefer to modify the existing "Timestamp"

Here is the Serilog configuration if needed

public static class SerilogExtensions
{
    const string TableName = "Log_API";
    const string SchemaName = "Serilog";
    const string outputTemplate = "[{Timestamp:u} {Level:u3}] {Message:lj} {Properties:j}{NewLine}{record}{NewLine}{Exception}";

    /// <summary>
    /// Defines the serilog configuration
    /// </summary>
    /// <param name="builder">WebApplicationBuilder  for adding services to the builder</param>
    public static void AddSerilogApi(WebApplicationBuilder builder)
    {
        IConfiguration? configuration = builder.Configuration;

        string ConnectionString = configuration![Enum.GetName(typeof(CxCloudDbContext.DataContext.DbContextType), 1)!]!;
        var SettingAppInsights = builder.Configuration.GetSection(nameof(SettingApplicationInsights)).Get<SettingApplicationInsights>();

        IDictionary<string, ColumnWriterBase> ColumnOptions = new Dictionary<string, ColumnWriterBase>
        {
            { "RequestId", new RenderedMessageColumnWriter(NpgsqlDbType.Varchar) },
            { "Level", new LevelColumnWriter(true, NpgsqlDbType.Varchar) },
            { "Created_date", new TimestampColumnWriter(NpgsqlDbType.Timestamp) },
            { "Exception", new ExceptionColumnWriter(NpgsqlDbType.Text) },
            { "Log_event", new LogEventSerializedColumnWriter(NpgsqlDbType.Jsonb) },
            { "Properties", new PropertiesColumnWriter(NpgsqlDbType.Jsonb) },
            { "Machine_name", new SinglePropertyColumnWriter("MachineName", PropertyWriteMethod.ToString, NpgsqlDbType.Text, "l") }
        };

        Log.Logger = new LoggerConfiguration()
            .ReadFrom.Configuration(configuration)
            .MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Error)
            .Enrich.FromGlobalLogContext()
            .Enrich.FromLogContext()
            .Enrich.WithThreadId()
            .Enrich.WithClientIp()
            .Enrich.WithProcessName()
            .Enrich.WithMachineName()
            .Enrich.WithEnvironmentUserName()
            .Enrich.WithExceptionDetails()
            .Destructure.JsonNetTypes()
            .WriteTo.Async(wt => wt.Console(outputTemplate: outputTemplate))
            .WriteTo.Async(appInsgh => appInsgh.ApplicationInsights(SettingAppInsights.ConnectionString, new TraceTelemetryConverter()))
            .WriteTo.Async(pg => pg.PostgreSQL(ConnectionString,
                                               TableName,
                                               ColumnOptions,
                                               needAutoCreateTable: false,
                                               needAutoCreateSchema: false,
                                               schemaName: SchemaName,
                                               useCopy: true,
                                               period: new TimeSpan(0, 0, 10),
                                               restrictedToMinimumLevel: LogEventLevel.Information))
            .CreateLogger();

        builder.Host.UseSerilog();
    }
}