Pull to refresh

Photon это не только log4net

Programming.NETGame development
Tutorial

... но и любой другой логгер.

Традиционно Photon Server SDK поставляется с log4net. Но это не значит что все им должны пользоваться. Пользоваться можно практически любым логгером. Всё что нужно это создать свою сборку-адаптер, которая будет содержать класс прокси и фабрику для него.

Для примера возьмём модный нынче Serilog. Я с ним не знаком, так что возможно что-то будет сделано не лучшим методом или неправильно.

И так приступим.

Первое, что нам нужно это создать сборку для вашего адаптера.

В SDK 4.0 интерфейсы ExitGames.Logging.ILogger и ExitGames.Logging.ILoggerFactory находятся в ExitGamesLibs.dll. В SDK 5.0 их вынесли в ExitGames.Logging.dll. ExitGames.Logging находится в nuget пакете с тем же именем. Эти библиотеки должны быть добавлены в зависимости.

Дальше мы создаём класс-прокси для логгера. Я не будут приводить весь его код, чтобы не раздувать пример.

    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);
        }
......................................................        

Следующее, что нам нужно это класс фабрики.

    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);
        }
    }

Последний штрих это установка нашей фабрики

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

Сделать это необходимо перед тем как будут инициализироваться логгеры в Photon.SocketServer.dll. Для этого лучше всего подходит статический конструктор вашего photon-приложения

Что ещё нужно знать про логгинг

Используйте if (log.IsDebugEnabled)

Хотя я соглашусь с тем, что это очевидно, но я сам так не делал, когда только столкнулся с фотоном. Обычно отладочных сообщений в коде много и, если их не накрывать таким if-ом, они могут сильно просадить скорость выполнения. Для Info это уже решать самим. Warning обычно всегда включён поэтому можно этот трюк не использовать.

Защищённое логгирование

Много раз мы наступали на грабли, что какой-нибудь варнинг начинает валиться в лог сотнями сообщений в секунду. Эта ситуация неприемлема по многим причинам и производительность не самая последняя из них. Поэтому изобрели LogCountGuard. Ему задают интервал и количество сообщений, которое он может вывести за этот интервал. Остальные не выводятся, а только копится счётчик пропущенных. Когда интервал времени заканчивается сообщение снова выводится с указанием числа пропущенных до него. Вот тут есть тонкость в реализации. Если интервал закончился, а новые сообщения не поступали, то пропущенные выводится не будут

Для того, чтобы этим инструментом было удобно пользоваться, были добавлены методы расширения. Теперь это всё выглядит следующим образом. Допустим нам надо, чтобы какое-то сообщение не появлялось чаще, чем 10 раз в минут. Необходимо сделать следующее,

  // объявление
  private static readonly LogCountGuard msgLogGuard = new LogCountGuard(new TimeSpan(0, 0, 6), 1);
  

  // использование
  log.Warn(msgLogGuard, "message");

Заключение

В заключении хочется пожелать всем успеха в использовании Photon Server SDK и пусть отсутствие вашего любимого логгера вас не пугает.

Tags:photonserilogC#
Hubs: Programming .NET Game development
Rating 0
Views813
Senior .Net Engineer (C#)
to 230,000 ₽ItivitiСанкт-Петербург
C# .net Developer
from 90,000 to 180,000 ₽АЛМАЗМоскваRemote job
Программист .NET/C#/ASP. NET MVC
from 100,000 ₽МВС ТелекомМосква
C# .Net Developer
from 1,200 to 3,500 $Profit CenterRemote job
C# .Net developer
from 100,000 to 140,000 ₽МодульбанкRemote job

Top of the last 24 hours