Photon is not only about log4net

... but also any other logger.





Traditionally, the Photon Server SDK comes with log4net. But this does not mean that everyone should use it. Almost any logger can be used. All you need to do is create your own adapter assembly, which will contain the proxy class and the factory for it.





Let's take Serilog, which is fashionable today. I am not familiar with him, so it is possible that something will not be done in the best way or wrong.





And so let's get started.





The first thing we need to do is create an assembly for your adapter.





In SDK 4.0, the interfaces ExitGames.Logging.ILogger and ExitGames.Logging.ILoggerFactory are in ExitGamesLibs.dll. In SDK 5.0 they were moved to ExitGames.Logging.dll. ExitGames.Logging is in the nuget package of the same name. These libraries need to be added as dependencies.





Next, we create a proxy class for the logger. I will not give all of its code, so as not to inflate the example.





    class SerilogLogger : ILogger
    {
        private readonly global::Serilog.ILogger logger;

        public bool IsDebugEnabled => this.logger.IsEnabled(LogEventLevel.Debug);

        // not sure whether this is right implementation
        public string Name => this.logger.ToString();

............................................................

        public SerilogLogger(global::Serilog.ILogger logger)
        {
            this.logger = logger;
        }

        public void Debug(object message)
        {
            if (message is string str)
            {
                this.logger.Debug(str);
                return;
            }

            throw new NotSupportedException("only strings are allowed");
        }

        public void Debug(object message, Exception exception)
        {
            if (message is string str)
            {
                this.logger.Debug(exception, str);
                return;
            }
            throw new NotSupportedException("only strings are allowed");
        }

        public void DebugFormat(string format, params object[] args)
        {
            this.logger.Debug(format, args);
        }

        public void DebugFormat(IFormatProvider formatProvider, string format, params object[] args)
        {
            this.logger.Debug(format, args);
        }
......................................................        

      
      



The next thing we need is a factory class.





    public class SerilogLoggerFactory : ILoggerFactory
    {
        /// <summary>
        /// Provides a static singleton instance for the <see cref="SerilogLoggerFactory"/> class.
        /// </summary>
        public static readonly SerilogLoggerFactory Instance = new SerilogLoggerFactory();

        public ILogger CreateLogger(string name)
        {
            var serilogLogger = Log.ForContext(Constants.SourceContextPropertyName, name);
            return new SerilogLogger(serilogLogger);
        }
    }

      
      



The final touch is the installation of our factory





ExitGames.Logging.LogManager.SetLoggerFactory(SerilogLoggerFactory.Instance);

      
      



This must be done before the loggers in Photon.SocketServer.dll are initialized. The static constructor of your photon application is best for this.





What else you need to know about logging

Use if (log.IsDebugEnabled)

, , , . , if-, . Info . Warning .





, - . . LogCountGuard. , . , . . . , ,





To make this tool convenient to use, extension methods have been added. Now it all looks like this. Let's say we need a message not to appear more often than 10 times a minute. You need to do the following,





  // 
  private static readonly LogCountGuard msgLogGuard = new LogCountGuard(new TimeSpan(0, 0, 6), 1);
  

  // 
  log.Warn(msgLogGuard, "message");

      
      



Conclusion

In conclusion, I would like to wish everyone success in using the Photon Server SDK, and do not let the absence of your favorite logger scare you.








All Articles