How to create a Custom text formatter for Cloudwatch?
Asked Answered
A

2

6

I don't understand how to create a custom text formatter for Amazon Cloudwatch as mentioned:

var formatter = new MyCustomTextFormatter();

I am trying to write Serilog logs to Amazon CloudWatch instead of the local hard disk. To do that I am following this repo:

https://github.com/Cimpress-MCP/serilog-sinks-awscloudwatch

private readonly ITextFormatter textFormatter;

public ILoggerFactory ConfigureLogger()
{
    LoggerFactory factory = new LoggerFactory();

    var logGroupName = "myLoggrouName";
    var region = Amazon.RegionEndpoint.EUWest1;
    var client = new AmazonCloudWatchLogsClient(region);
   //var formatter = new MyCustomTextFormatter();

    var options = new CloudWatchSinkOptions()
    {
        LogGroupName = logGroupName,
        //TextFormatter = formatter,
     
        MinimumLogEventLevel = LogEventLevel.Information,
        BatchSizeLimit = 100,
        QueueSizeLimit = 10000,
        Period = TimeSpan.FromSeconds(10),
        CreateLogGroup = true,
        LogStreamNameProvider = new DefaultLogStreamProvider(),
        RetryAttempts = 5
    };

      Log.Logger = new LoggerConfiguration()
            .WriteTo.AmazonCloudWatch(options, client)
            .CreateLogger();

    return factory;
}

To be able to write the Serilogs to Cloudwatch.

Abeabeam answered 8/1, 2019 at 9:37 Comment(0)
S
9

I passed for the same situation today and what I figure out is that custom formatter - which no one is set by default - its to set how the log will be write and consequently it will appear in the AWS Logs.

You can start creating a simple formatter using the interface that Serilog provides and adapt to the best fit in your situation.

public class AWSTextFormatter : ITextFormatter
{
    public void Format(LogEvent logEvent, TextWriter output)
    {
        output.Write("Timestamp - {0} | Level - {1} | Message {2} {3}", logEvent.Timestamp, logEvent.Level, logEvent.MessageTemplate, output.NewLine);
        if (logEvent.Exception != null)
        {
            output.Write("Exception - {0}", logEvent.Exception);
        }
    }
}

Using it

var customFormatter = new AWSTextFormatter();

 var options = new CloudWatchSinkOptions
{
  // the name of the CloudWatch Log group for logging
  LogGroupName = logGroupName,

  // the main formatter of the log event
  TextFormatter = customFormatter,

  // other defaults defaults
  MinimumLogEventLevel = LogEventLevel.Information,
  BatchSizeLimit = 100,
  QueueSizeLimit = 10000,
  Period = TimeSpan.FromSeconds(10),
  CreateLogGroup = true,
  LogStreamNameProvider = new DefaultLogStreamProvider(),
  RetryAttempts = 5
};

In the method you can acces the LogEvent and get all information you need. This one is similar to what they use in the lib, writing the event, exception and some detail.

A suggestion is to test the custom formatter locally writing the log in some file

Log.Logger = new LoggerConfiguration()
     .MinimumLevel.Debug()
     .WriteTo.RollingFile(customFormatter, Path.Combine(env.ContentRootPath, "Logs", "Log-{Date}.txt"))
     .WriteTo.AmazonCloudWatch(options, client)
     .CreateLogger();

What the log shows:

Timestamp - 1/9/2019 11:52:11 AM -02:00 | Level - Fatal | Message PROBLEM STARTING 
 APPLICATION 
 Exception - Couchbase.Configuration.Server.Serialization.BootstrapException: Could not 
 bootstrap - check inner exceptions for details.
Septal answered 9/1, 2019 at 14:15 Comment(0)
I
6

You can also use Serilog's default Json formatter.

using Serilog.Formatting.Json;

and then :

TextFormatter = new JsonFormatter(Environment.NewLine);
Isochronize answered 18/4, 2021 at 13:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.