1 /** 2 * Модуль содержит функции для работы с логами в приложении 3 * 4 * Copyright: (c) 2015-2020, Milofon Project. 5 * License: Subject to the terms of the BSD 3-Clause License, as written in the included LICENSE.md file. 6 * Author: <m.galanin@milofon.pro> Maksim Galanin 7 * Date: 2020-04-11 8 */ 9 10 module dango.system.logging.core; 11 12 public 13 { 14 import uniconf.core : UniConf; 15 } 16 17 private 18 { 19 import std.uni : toUpper; 20 import std.functional : toDelegate; 21 import std.format : fmt = format; 22 23 import vibe.core.log : Logger, LogLevel, FileLogger, setLogLevel; 24 25 import dango.inject : DependencyContainer, ComponentFactory; 26 import dango.system.properties : getNameOrEnforce; 27 } 28 29 30 /** 31 * Интерфейс фабрики для создания объекта логгера 32 */ 33 alias LoggerFactory = ComponentFactory!(shared(Logger), UniConf); 34 35 36 /** 37 * Преобразует строку в уровеь логирования 38 */ 39 package LogLevel matchLogLevel(string level) @safe 40 { 41 switch (level.toUpper) with (LogLevel) 42 { 43 case "TRACE": 44 return trace; 45 case "DEBUGV": 46 return debugV; 47 case "DEBUG": 48 return debug_; 49 case "INFO": 50 return info; 51 case "WARN": 52 return warn; 53 case "ERROR": 54 return error; 55 case "FATAL": 56 return fatal; 57 default: 58 return info; 59 } 60 } 61 62 63 /** 64 * Преобразует строку в формат лога 65 */ 66 package FileLogger.Format matchLogFormat(string logFormat) 67 { 68 switch (logFormat.toUpper) with (FileLogger.Format) 69 { 70 case "PLAIN": 71 return plain; 72 case "THREAD": 73 return thread; 74 case "THREADTIME": 75 return threadTime; 76 default: 77 return plain; 78 } 79 } 80 81 82 /** 83 * Инициализация логирования приложения 84 * 85 * В основе функционала логирования используется реализация из vibed. 86 * Значения по умолчанию: уровень логирования = warn, формат лога = plain 87 * 88 * Params: 89 * 90 * container = Контейнер DI 91 * config = Объект свойств содержит настройки логгеров 92 * dg = Функция для обработки логгера 93 */ 94 void configureLogging(DependencyContainer container, UniConf config, 95 void function(shared(Logger)) nothrow dg) @trusted 96 { 97 configureLogging(container, config, toDelegate(dg)); 98 } 99 100 101 /** 102 * Инициализация логирования приложения 103 * 104 * В основе функционала логирования используется реализация из vibed. 105 * Значения по умолчанию: уровень логирования = warn, формат лога = plain 106 * 107 * Params: 108 * 109 * container = Контейнер DI 110 * config = Объект свойств содержит настройки логгеров 111 * dg = Функция-делегат для обработки логгера 112 */ 113 void configureLogging(DependencyContainer container, UniConf config, 114 void delegate(shared(Logger)) nothrow dg) @safe 115 { 116 if ("logger" !in config) 117 return; 118 119 // отключаем логгер консоли по умолчанию 120 setLogLevel(LogLevel.none); 121 122 UniConf logConfig = config.get!UniConf("logger"); 123 if (logConfig.canMapping) 124 logConfig = UniConf([logConfig]); 125 126 foreach (UniConf loggerConf; logConfig.getSequence()) 127 { 128 auto appender = loggerConf.opt!UniConf("appender"); 129 if (appender.empty) 130 throw new Exception(fmt!"В конфигурации логера не указан тип ('%s')"(loggerConf)); 131 132 string appenderName = appender.front.getNameOrEnforce( 133 "Не указано наименование логгера").toUpper; 134 135 auto factory = container.resolve!LoggerFactory(appenderName); 136 if (factory is null) 137 throw new Exception("Не зарегистрирован логгер с именем " ~ appenderName); 138 139 shared(Logger) logger = factory.createComponent(loggerConf); 140 if (logger && dg) 141 () @trusted { dg(logger); }(); 142 } 143 } 144