Custom MongoDb output

In the following example, we will create a custom ILogListener which saves the log messages to MongoDb database.

Contents

Create entities

To start, we will define two entities which will store the logs data, respectively RequestLog and Message.

namespace MyApplication.Models
{
    public class RequestLog
    {
        public string Id { get; private set; }
        public DateTime DateTime { get; set; }
        public string UserAgent { get; set; }
        public string HttpMethod { get; set; }
        public string AbsoluteUri { get; set; }
        public double DurationInMilliseconds { get; set; }

        public IEnumerable<Message> Messages { get; set; }

        public RequestLog()
        {
            Id = Guid.NewGuid().ToString();
            Messages = new List<Message>();
        }
    }
}
namespace MyApplication.Models
{
    public class Message
    {
        public string Category { get; set; }
        public DateTime DateTime { get; set; }
        public string LogLevel { get; set; }
        public string LogMessage { get; set; }
    }
}

Create MongoDbContext

Next, we create the MongoDbContext, which will help us query the MongoDb database.

using MongoDB.Driver;
using MyApplication.Models;

namespace MyApplication.MongoDb
{
    public class MongoDbContext
    {
        private readonly IMongoDatabase _db;
        public MongoDbContext()
        {
            var mongoClient = new MongoClient("mongodb://localhost:27017");
            _db = mongoClient.GetDatabase("CustomLogsDatabase");
        }

        // we define a "RequestLog" collection
        public IMongoCollection<RequestLog> RequestLogs => _db.GetCollection<RequestLog>("RequestLog");
    }
}

Create MongoDbListener

Finally, we create the MongoDbListener, which will save the log messages to MongoDb.

using MyApplication.Models;
using MyApplication.MongoDb;
using KissLog;
using KissLog.Web;
 
namespace MyApplication
{
    public class MongoDbListener : ILogListener
    {
        public int MinimumResponseHttpStatusCode { get; set; } = 0;
        public LogLevel MinimumLogMessageLevel { get; set; } = LogLevel.Trace;
        public LogListenerParser Parser { get; set; } = new LogListenerParser();

        public void OnFlush(FlushLogArgs args)
        {
            var logMessages = args.MessagesGroups.SelectMany(p => p.Messages).OrderBy(p => p.DateTime).ToList();

            // create the entities
            RequestLog requestLog = ToModel(args.WebRequestProperties);
            requestLog.Messages = logMessages.Select(p => ToModel(p)).ToList();

            // save the entities to MongoDb
            MongoDbContext dbContext = new MongoDbContext();
            dbContext.RequestLogs.InsertOne(requestLog);
        }

        private Message ToModel(LogMessage logMessage)
        {
            return new Message
            {
                Category = logMessage.CategoryName,
                DateTime = logMessage.DateTime,
                LogLevel = logMessage.LogLevel.ToString(),
                LogMessage = logMessage.Message
            };
        }

        private RequestLog ToModel(WebRequestProperties webRequest)
        {
            double durationInMs = (webRequest.EndDateTime - webRequest.StartDateTime).TotalMilliseconds;

            return new RequestLog
            {
                UserAgent = webRequest.UserAgent,
                HttpMethod = webRequest.HttpMethod,
                AbsoluteUri = webRequest.Url.AbsoluteUri,
                DurationInMilliseconds = durationInMs
            };
        }
    }
}

Register the listener

Last step is to register the new MongoDbListener.

protected void Application_Start()
{
    KissLogConfiguration.Listeners.Add(new MongoDbListener());
}

Checking the MongoDb, we can see the persisted log messages.

MongoDb logs