Logs Output

KissLog saves the logs by using ILogListener listeners.

Listeners are registered at application startup using the KissLogConfiguration.Listeners container.

protected void Application_Start()
{
    // KissLog.net cloud listener
    KissLogConfiguration.Listeners.Add(new KissLogApiListener(new KissLog.Apis.v1.Auth.Application(
        ConfigurationManager.AppSettings["KissLog.OrganizationId"],
        ConfigurationManager.AppSettings["KissLog.ApplicationId"])
    ));

    // NLog listener -> send all the KissLog logs to NLog targets
    KissLogConfiguration.Listeners.Add(new NLogTargetListener());
}

How it works

KissLog listeners are triggered automatically on three separate events:

  1. At the beggining of the HTTP request, using OnBeginRequest(HttpRequest httpRequest)

  2. Each time a log message is created, using OnMessage(LogMessage message)

  3. At the end of the HTTP request, using OnFlush(FlushLogArgs args)

For Web applications (.NET Core, AspNet MVC, AspNet WebApi)

Begin GET /swagger/         <---- OnBeginRequest(HttpRequest httpRequest)



ILogger logger = Logger.Factory.Get();

logger.Debug("step 1");    <---- OnMessage(LogMessage message)

logger.Debug("step 2");    <---- OnMessage(..)

...
logger.Debug("step n");    <---- OnMessage(..)



END 200 OK GET /swagger/    <---- OnFlush(FlushLogArgs args)

For Windows / Console applications

private void Foo()
{
    ILogger logger = new Logger(url: "Foo");    <---- OnBeginRequest(HttpRequest httpRequest)

    logger.Debug("step 1");                     <---- OnMessage(LogMessage message)

    logger.Debug("step 2");                     <---- OnMessage(..)

    ...
    logger.Debug("step n");                     <---- OnMessage(..)

    Logger.NotifyListeners(logger);             <---- OnFlush(FlushLogArgs args)
}

Built-in log listeners

KissLog comes with several built-in log listeners:

KissLogApiListener

This listener saves the logs to KissLog.net / on-premises server.

protected void Application_Start()
{
    ILogListener listener = new KissLogApiListener(new KissLog.Apis.v1.Auth.Application(
        ConfigurationManager.AppSettings["KissLog.OrganizationId"],
        ConfigurationManager.AppSettings["KissLog.ApplicationId"])
    );

    KissLogConfiguration.Listeners.Add(listener);
}

NLogTargetListener

protected void Application_Start()
{
    ILogListener listener = new NLogTargetListener();

    KissLogConfiguration.Listeners.Add(listener);
}

This listener saves the KissLog logs to all the NLog targets defined in NLog.config.

This is useful when you want to use both KissLog and NLog in the same application.

LocalTextFileListener

This listener saves the logs to local text files.

protected void Application_Start()
{
    ILogListener listener = new LocalTextFileListener(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs"))
    {
        FlushTrigger = FlushTrigger.OnFlush // OnFlush | OnMessage
    };

    KissLogConfiguration.Listeners.Add(listener);
}

Creating custom listeners

Custom listeners can be created by implementing the ILogListener interface.

public interface ILogListener
{
    int MinimumResponseHttpStatusCode { get; }
    LogLevel MinimumLogMessageLevel { get; }
    LogListenerParser Parser { get; }

    // is triggered at the beggining of the HTTP request
    void OnBeginRequest(HttpRequest httpRequest, ILogger logger);

    // is triggered each time a log message is created
    void OnMessage(LogMessage message, ILogger logger);

    // is triggered at the end of the HTTP request
    void OnFlush(FlushLogArgs args, ILogger logger);
}

The persistance logic can be implemented by any of the three events: OnBeginRequest, OnMessage and OnFlush.

For example, a TextLogListener can write the logs as soon as they get created, by using the OnMessage(LogMessage message) event.

And, to reduce the database overhead, an SqlLogListener can write the logs at the end of the HTTP request, by using the OnFlush(FlushLogArgs args) event.

Custom listener example

Below we have a custom listener which writes the logs to the Debug console.

public class DebugOutputListener : ILogListener
{
    public int MinimumResponseHttpStatusCode { get; set; } = 0;
    public LogLevel MinimumLogMessageLevel { get; set; } = LogLevel.Trace;
    public LogListenerParser Parser { get; set; } = new LogListenerParser();

    public void OnBeginRequest(HttpRequest httpRequest, ILogger logger)
    {
        Debug.WriteLine($"{httpRequest.HttpMethod.ToUpper()} {httpRequest.Url.PathAndQuery}");
    }

    public void OnMessage(LogMessage message, ILogger logger)
    {
        Debug.WriteLine($"{message.LogLevel} {message.Message}");
    }

    public void OnFlush(FlushLogArgs args, ILogger logger)
    {
        HttpRequest request = args.WebProperties.Request;
        HttpResponse response = args.WebProperties.Response;

        int httpStatusCode = (int)response.HttpStatusCode;
        string duration = (response.EndDateTime - request.StartDateTime).TotalMilliseconds;

        Debug.WriteLine($"{httpStatusCode} Duration: {duration}ms");
    }
}

Registering the custom listener:

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

Please check the custom MongoDbListener for a more complex example.


Related references

  • ILogListener - component used by KissLog to save the logs
  • ILogger - the component used to write log messages