Search Results for

    Show / Hide Table of Contents

    Custom logging extensions

    A custom logger is a standard C# class thats exposes a static factory method and an implementation.

    As an example, consider an imaginary logger that sends logs to some kind of external service. It needs the following elements:

    • A builder method
    • A logging controller
    • An implementation of the ILogger interface

    Builder method

    The builder method is called as part of the runtime build process and creates a new instance of your logging controller.
    This controller is responsible for creating new ILogger instances and managing the interactions with any other logging framework you may be using.

    // This definition exposes the installed method for installing the logging 
    // framework when creating a runtime
    public static class MyCustomLoggingInstaller
    {
        public static IRuntimeFactory UseMyCustomLogging(this IRuntimeFactory runtimeFactory)
        {
            runtimeFactory.SetupLogging(new MyCustomLoggingImpl());
            return runtimeFactory;
        }
    }
    

    Logging controller

    The logging controller could look something like the following.
    This version creates a connection to an imaginary remote logging service.

    internal class MyCustomLoggingImpl: ILoggingImplementation
    {
        private MyLoggerLogger rootLogger;
    
        public OpenFin.Net.Adapter.Logging.ILogger GetLogger(Type context = null)
        {
            if (context != null)
            {
                return new MyLoggerLogger(myServiceConnection, context);
            }
            return rootLogger;
        }
    
        public void Initialize(LogConfig loggerConfig, string targetFilePath)
        {
            // TODO: Setup some remote logger service connection
            myServiceConnection = ...create connection;
    
            rootLogger = new MyLoggerLogger(myServiceConnection);
        }
    }
    

    The Initialize() method is responsible for setting up any logging service you may be using, creating files, and so on.

    The GetLogger() method is called whenever a new logger for a context is required.

    The following example creates a new logger, passing in a context of MainWindow.

    var loggerMgr = runtime.GetService<ILogManager>();
    var logger = loggerMgr.GetLogger(typeof(MainWindow));
    

    ILogger implementation

    A logger implementation handles each of the log levels and writes messages to the required destination.

    An implementation of ILogger could look something like the following:

    public class MyLoggerLogger : ILogger
    {
        private LogConfig logConfig;
        public MyLoggerLogger(ISomeConnection connection, Type context)
        {
            Connection = connection;
            Context = context;
        }
        public ISomeConnection  Connection { get; }
        public Type   Context{ get; }
    
        /// Invoked after creation and whenever the logger configuration changes
        public void OnLogConfigUpdate(LogConfig logConfig)
        {
            this.logConfig = logConfig;
        }
    
        // Output a message to the logging service    
        public void Debug(string message)
        {
            Connection.SendDebug(message);
        }
    
        // Output a message and any passed exception to the logging service
        public void Debug(string message, Exception exception)
        {
            Connection.SendDebug(exception, message);
        }
    
        // Output a message resulting from a `Func` evaluation to the logging service.
        // Note: The `Func` is evaluated only if the logging level matches, in this case, debug.  
        // This technique allows for more output but minimal impact on performance 
        // if the log level is not enabled.
        public void Debug(Func<string> message)
        {
            if (LogLevel.Debug >= logConfig.MinLevel)
            {
                Debug(message());
            }
        }
        public void Error(string message)
        {
            Connection.SendError(message);
        }
        public void Error(string message, Exception exception)
        {
            Connection.SendError(exception, message);
        }
        public void Error(Func<string> message)
        {
            if (LogLevel.Error >= logConfig.MinLevel)
            {
                Error(message());
            }
        }
        public void Fatal(string message)
        {
            Connection.SendFatal(message);
        }
        public void Fatal(string message, Exception exception)
        {
            Connection.SendFatal(exception, message);
        }
        public void Fatal(Func<string> message)
        {
            if (LogLevel.Fatal >= logConfig.MinLevel)
            {
                Fatal(message());
            }
        }
        public void Information(string message)
        {
            Connection.SendInformation(message);
        }
        public void Information(string message, Exception exception)
        {
            Connection.Information(exception, message);
        }
        public void Information(Func<string> message)
        {
            if (LogLevel.Information >= logConfig.MinLevel)
            {
                Information(message());
            }
        }
        public void Verbose(string message)
        {
            Connection.SendSendVerbose(message);
        }
        public void Verbose(string message, Exception exception)
        {
            Connection.SendVerbose(exception, message);
        }
        public void Verbose(Func<string> message)
        {
            if (LogLevel.Verbose >= logConfig.MinLevel)
            {
                Verbose(message());
            }
        }
        public void Warning(string message)
        {
            Connection.SendWarning(message);
        }
        public void Warning(string message, Exception exception)
        {
            Connection.SendWarning(exception, message);
        }
        public void Warning(Func<string> message)
        {
            if (LogLevel.Warning >= logConfig.MinLevel)
            {
                Warning(message());
            }
        }
    }
    

    Use the custom logger

    Once you have written the logger and deployed it as an assembly, you can enable it within your applications using the runtime builder.

    For example:

    runtime = new RuntimeFactory()
                .UseMyCustomLogging()
                .GetRuntimeInstance(new RuntimeOptions
                {
                    Version = "stable",
                    UUID = "UUID_STRING",
                    LicenseKey = "LICENSE_KEY"
                });
    
    var loggerMgr = runtime.GetService<ILogManager>();
    var logger = loggerMgr.GetLogger(typeof(MainWindow));          
    logger.Debug("This message goes via my custom logger");
    
    In This Article
    Back to top Copyright OpenFin