LogWriter File Management

+1 vote
asked Jan 9, 2014 by Tim (390 points)
edited Jan 15, 2014

Is there a programmatic way through the Rebex LogWriter to manage the LogWriter files like rolling logs? Or is this a manual process?

Applies to: Rebex FTP/SSL, Rebex SFTP

3 Answers

+1 vote
answered Jan 10, 2014 by Tomas Knopp (58,890 points)
edited Jan 15, 2014
 
Best answer

There is not a built-in support for managing log files. However, you can easily write a custom implementation of ILogWriter interface or extend the provided LogWriterBase class, and write a custom RollingLogWriter which you can to assign to the LogWriter property of Rebex client objects. Let us know if you need help with this.

commented Jan 10, 2014 by Tim (390 points)
edited Jan 10, 2014

That sounds like a solution. Can you point me to a code example?

commented Jan 15, 2014 by Tomas Knopp (58,890 points)
edited Jan 15, 2014

See this answer for a sample implementation using log4net.

+1 vote
answered Jan 14, 2014 by Tomas Knopp (58,890 points)
edited Oct 10, 2018 by Lukas Matyska

We have implemented a sample Log4NetLogWriter class which uses Apache log4net and provides an adapter to `ILogWriter` that makes it possible to utilize this within Rebex libraries. Apache log4net offers (among other features) a highly customizable log rolling capabilities via the RollingFileAppender class.

Here is the sample which uses the Log4NetLogWriter class. It can be used just the same as Rebex FileLogWriter with one exception. You have to configure the log4net, for example via an app.config.


var client = new Rebex.Net.Imap();

// read the log4net configuration from app.config
log4net.Config.XmlConfigurator.Configure(); // specify the verbose level you want to use
client.LogWriter = new Log4NetLogWriter("Rebex", LogLevel.Debug);

A simple rolling log writer config is available here. Just download the App.config file and put it into the Visual Studio project. The config is for 50KB rolling logs. Maximum number of log files is 100.

0 votes
answered Jan 21 by Lukas Pokorny (111,390 points)

Another alternative is to write a custom implementation of our ILogWriter interface that passes all calls to Serilog and converts the log info as needed:

public class LogWriterAdapter : LogWriterBase
{
    private readonly ILogger _logger;
    private const string MessageTemplate = "{type} {id} {area} {message}";
    private const string MessageTemplateWithData = "{type} {id} {area} {message} {data}";

    public LogWriterAdapter(ILogger logger, LogLevel level)
    {
        Level = level;
        _logger = logger;
    }

    private void Write(LogLevel level, Type objectType, int objectId, string area, string message, ArraySegment<byte>? data)
    {
        string template = (data == null) ? MessageTemplate : MessageTemplateWithData;

        if (level <= LogLevel.Verbose)
        {
            _logger.Verbose(template, objectType, objectId, area, message, data);
        }
        else if (level <= LogLevel.Debug)
        {
            _logger.Debug(template, objectType, objectId, area, message, data);
        }
        else if (level <= LogLevel.Info)
        {
            _logger.Information(template, objectType, objectId, area, message, data);
        }
        else if (level <= LogLevel.Error)
        {
            _logger.Error(template, objectType, objectId, area, message, data);
        }
    }

    public override void Write(LogLevel level, Type objectType, int objectId, string area, string message)
    {
        Write(level, objectType, objectId, area, message, null);
    }

    public override void Write(LogLevel level, Type objectType, int objectId, string area, string message, byte[] buffer, int offset, int length)
    {
        Write(level, objectType, objectId, area, message, new ArraySegment<byte>(buffer, offset, length));
    }
}

Please note ILogWriter has no concept equivalent to Serilog’s structured event data, but it can at least provide some of the logged information in a slightly structured way.

To utilize the LogWriterAdapter class, you would do something like this:

// obtain an appropriate logger
ILogger logger = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .WriteTo.Console()
    .CreateLogger();

// create an instance of Rebex object
var client = new Sftp();

// use LogWriterAdapter (with an equivalent level specified)
client.LogWriter = new LogWriterAdapter(logger, LogLevel.Debug);

// do the rest 
client.Connect(...)
...