Гайд Заводим красивое логирование для нашего приложения

Статус
В этой теме нельзя размещать новые ответы.
  • 7
  • 8
Контакты для связи отсутствуют.
Предыстория:
Всем привет! Довольно часто при разработке какого либо приложения, бывает необходимость логировать какие либо действия в коде программы.
Конечно, можно банально и просто использовать: Console.WriteLine(); Но просто выводить голый текст - для мелких программ с пару сотен кода - окей, а вот для программы по больше - не очень то удобно. Да и по хорошему надо логировать уровни лога: Информация, Варнинг, Ошибка, Фатальная ошибка и прочее. И писать всё через Console.WriteLine(); или писать обёртку для этого - не совсем хорошая идея, которая к тому-же и сьест ваше время.


Предлагаю в этом туториале познакомиться с библиотекой логирования - NLog
Давайте первым делом создадим C# консольный проект и подключим его через NuGet:
kr4n3JB.png

KMp6TLI.png

Окей, библиотека уже скачалась и сама подключилась к нашему проекту.
Однако при компиляции никакой разницы вы не почувствуете. Надо в начале настроить само логирование, а уже потом его инициализировать.

NLog умеет логировать ваши сообщения в:
Простой файл
В консоль
В Базу данных
Отправляя лог на почту

Мы будем рассказывать про первые 2 способа, которые как раз таки являются самыми популярными типами логирования.
Про логирование в БД вы можете почитать тут:
*Тык*
Не забыв подключить ещё и провайдера (драйвер) базы данных:
*Тык*

Ну а для любителей почты, вот ваш гайд:
*Жмяк*

Для настройки NLog , прежде всего есть 2 типа его конфигурации:
1) Через конфигурационный файл (NLog.Config)
2) Через код прямо в программе

Так как в интернете полно гайдов, как подключать NLog через первый вариант - я покажу подключение через код прям в программе. Лично для меня второй вариант куда удобнее. Сконфигурировал в main-e, запихнул код в регион и скрыл.

Давайте начнём с простой конфигурации, и потом уже будет её апгрейдить.
Вот код, который позволит вам начать работу с NLog:

C#:
            #region NLog Initializator

            var config = new NLog.Config.LoggingConfiguration();
            LogManager.Configuration = new LoggingConfiguration();
            var consoleTarget = new ColoredConsoleTarget("Console Target")
            {
                Layout = @"${longdate}|${level:uppercase=true}|${logger}|${message}"
            };
            // Rules for mapping loggers to targets
            config.AddRule(LogLevel.Trace, LogLevel.Fatal, consoleTarget);
            // Apply config
            NLog.LogManager.Configuration = config;

            #endregion NLog Initializator

Далее создаём сам логгер.
Для этого достаточно инициализировать её внутри класса:

public static Logger Logger = LogManager.GetCurrentClassLogger();

Ну а после всего, можно выводить сообщение:
Logger.Info("Hello world!");

Вот полный код, ready to paste (Вставлять внутрь класса):
Код:
public static Logger Logger = LogManager.GetCurrentClassLogger();

        private static void Main(string[] args)
        {
            #region NLog Initializator

            var config = new NLog.Config.LoggingConfiguration();
            LogManager.Configuration = new LoggingConfiguration();
            var consoleTarget = new ColoredConsoleTarget("Console Target")
            {
                Layout = @"${longdate}|${level:uppercase=true}|${logger}|${message}"
            };
            // Rules for mapping loggers to targets
            config.AddRule(LogLevel.Trace, LogLevel.Fatal, consoleTarget);
            // Apply config
            NLog.LogManager.Configuration = config;

            #endregion NLog Initializator

            Logger.Trace("Hello from Gamania!");
            Logger.Debug("Hello from Gamania!");
            Logger.Info("Hello from Gamania!");
            Logger.Warn("Hello from Gamania!");
            Logger.Error("Hello from Gamania!");
            Logger.Fatal("Hello from Gamania!");
        }

Ну а вот и вывод:
UJ7k4UW.png


У NLog есть несколько уровней сообщений (Они пронумерованы от низшего к высшему):

1. Trace
2. Debug
3. Info
4. Warn
5. Error

6. Fatal

Красиво?) А теперь расскажу как можно донастроить наше логирование
Для этого достаточно поменять:
public static Logger Logger = LogManager.GetCurrentClassLogger();
На
public static NLog.Logger Logger = NLog.LogManager.GetLogger("Сюда писать свой текст");
Для этого достаточно добавить данный код (Думаю поменять цвета вы сможете самостоятельно, всё очень просто)
C#:
            #region NLog Colors

            var Trace = new ConsoleRowHighlightingRule();
            Trace.Condition = ConditionParser.ParseExpression("level == LogLevel.Trace");
            Trace.ForegroundColor = ConsoleOutputColor.Yellow;
            consoleTarget.RowHighlightingRules.Add(Trace);
            var Debug = new ConsoleRowHighlightingRule();
            Debug.Condition = ConditionParser.ParseExpression("level == LogLevel.Debug");
            Debug.ForegroundColor = ConsoleOutputColor.DarkCyan;
            consoleTarget.RowHighlightingRules.Add(Debug);
            var Info = new ConsoleRowHighlightingRule();
            Info.Condition = ConditionParser.ParseExpression("level == LogLevel.Info");
            Info.ForegroundColor = ConsoleOutputColor.Green;
            consoleTarget.RowHighlightingRules.Add(Info);
            var Warn = new ConsoleRowHighlightingRule();
            Warn.Condition = ConditionParser.ParseExpression("level == LogLevel.Warn");
            Warn.ForegroundColor = ConsoleOutputColor.DarkYellow;
            consoleTarget.RowHighlightingRules.Add(Warn);
            var Error = new ConsoleRowHighlightingRule();
            Error.Condition = ConditionParser.ParseExpression("level == LogLevel.Error");
            Error.ForegroundColor = ConsoleOutputColor.DarkRed;
            consoleTarget.RowHighlightingRules.Add(Error);
            var Fatal = new ConsoleRowHighlightingRule();
            Fatal.Condition = ConditionParser.ParseExpression("level == LogLevel.Fatal");
            Fatal.ForegroundColor = ConsoleOutputColor.Black;
            Fatal.BackgroundColor = ConsoleOutputColor.DarkRed;
            consoleTarget.RowHighlightingRules.Add(Fatal);

            #endregion NLog Colors

pE2BEAI.png
В NLog можно фильтровать по сообщения по их уровню. Например скрыть сообщения типа TRACE и DEBUG, оставив сообщения от INFO и выше.
У нас есть правило:
config.AddRule(LogLevel.Trace, LogLevel.Fatal, consoleTarget);
И тут есть LogLevel.Trace - Это минимальный уровень логирования. Его необходимо поставить на LogLevel.Info.
Тогда у нас логи будут только от Info и выше.
Но можно скрывать не только по минимальному логу, но и по максимальному. Второй аргумент тут как раз кстати.
А вот это всё в действии:
cOIkKnO.png

Очень полезно, если вы делаете программу для дебага и релиза. Можно указать через #if DEBUG и #if RELEASE разные уровни логирования.
Все возможные лэйауты вы можете просмотреть тут:
*Тыч*
Сам код шаблона у нас изначально был таким:
Layout = @"${longdate}|${level:uppercase=true}|${logger}|${message}"
Вот мой код:
Layout = @"${counter}|[${date:format=yyyy-MM-dd HH\:mm\:ss}] [${logger}/${uppercase: ${level}}] [THREAD: ${threadid}] >> ${message} ${exception: format=ToString}"
5VpOF4W.png

Особо подсказать нечего. Просто идёте в официальную документацию NLog по Layout-ам, берёте и вставляете что вам нужно. Моего примера вполне достаточно, чтоб понять.
Покажу вам самое простое, базовое логгирование:
1) Добавляем Layout для логгирования в файл:
const string LayoutFile = @"[${date:format=yyyy-MM-dd HH\:mm\:ss}] [${logger}/${uppercase: ${level}}] [THREAD: ${threadid}] >> ${message} ${exception: format=ToString}";
2) Инициализируем файловый логгер:
C#:
var logfile = new FileTarget();
            if (!Directory.Exists("logs"))
                Directory.CreateDirectory("logs");
3) Добавляем правило для вывода сообщений в логфайл:
config.AddRule(LogLevel.Trace, LogLevel.Fatal, logfile);
4) Вставляем этот код:
C#:
logfile.CreateDirs = true;
            logfile.FileName = $"logs{Path.DirectorySeparatorChar}lastlog.log";
            logfile.AutoFlush = true;
            logfile.LineEnding = LineEndingMode.CRLF;
            logfile.Layout = LayoutFile;
            logfile.FileNameKind = FilePathKind.Absolute;
            logfile.ConcurrentWrites = false;
            logfile.KeepFileOpen = true;
9A0JQUP.png

Ну вот в принципе и всё. Всё что хотел - рассказал.
А на последок, прикрепляю ссылку на фулл исходный код проекта:
Example NLog code Guide from Gamania - Pastebin.com
Не стесняйтесь - пишите, будем обсуждать НЛог, кому интересно :)
В будущем буду постить ещё гайды.​
 
Статус
В этой теме нельзя размещать новые ответы.
Активность
Пока что здесь никого нет
Сверху Снизу