+1 vote
by (390 points)
edited

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
by (58.9k points)
edited
 
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.

by (390 points)
edited

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

by (58.9k points)
edited

See this answer for a sample implementation using log4net.

+1 vote
by (58.9k points)
edited by

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
by (144k 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(...)
...