简体   繁体   中英

log4net - log into different files in a multitenant application

I am working on a multi-tenant C# application. I am using log4net for logging purposes. Until now, I logged everything into a single log file. I want to log everything that relates to a specific tenant into a separate file.

For Example-
tenant 1 - C://log/tenant1.log
tenant 2 - C://log/tenant2.log
tenant 3 - C://log/tenant3.log

One way of achieving this is by adding different rollingfileappenders manually to the web.config.

By following method you can set filename dynamically.

**log4net.GlobalContext.Properties["LogFileName"]** 

But this doesn't help since it changes the global context. Everything going to logged into the last config filename.

You can try to inherit from FileAppender class. I don't know how do you recognize the tenant from the context, so I created a naive implementation just to showcase the general idea.

My appender:

public class MyFileAppender : FileAppender
{
    protected override void Append(LoggingEvent loggingEvent)
    {
        var myMessage = loggingEvent.MessageObject as MultitenantMessage;
        if (myMessage == null) return;
        OpenFile(myMessage.File, true);
        base.Append(loggingEvent);
    }
}

It works with custom login message:

public class MultitenantMessage
{
    public string Message { get; set; }
    public string File { get; set; }

    public override string ToString()
    {
        return Message;
    }
}

Usage would look as follows:

    logger.Debug(new MultitenantMessage {Message ="Tenant 1 here!", File=@"C:\logs\tenant1.txt" });
    logger.Debug(new MultitenantMessage {Message ="Tenant 2 also works!", File=@"C:\logs\tenant2.txt" });

This code creates two separate files and writes messages where required;

This, of course, is just a proof of concept. You would have to create some kind of dictionary of tenants and their logfiles as well as pass the tenant context to the appender (I did this by passing the file path). In the final implementation, MultitenantMessage class would not store the path to file, but maybe tenantID and your appender should contain dictionary TenantID -> file. Also file opening and saving can be done better as well as grouping logging events for performance reasons.

In the app.config reference, your appender just like you would register normal file appender

<appender name="RollingLogFileAppender" type="log4nettesting.MyFileAppender">

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM