1 /**
2  * Модуль содержит функции для работы с логами в приложении
3  *
4  * Copyright: (c) 2015-2017, Milofon Project.
5  * License: Subject to the terms of the BSD license, as written in the included LICENSE.txt file.
6  * Authors: Maksim Galanin
7  */
8 module dango.system.logging.core;
9 
10 private
11 {
12     import std.uni: toUpper;
13     import std.functional: toDelegate;
14     import std.format: format, formattedWrite;
15 
16     import vibe.core.log;
17     import poodinis: DependencyContainer;
18     import proped: Properties;
19 
20     import dango.system.container: resolveByName;
21 }
22 
23 
24 /**
25  * Интерфейс фабрики для создания объекта логгера
26  */
27 interface LoggerFactory
28 {
29     shared(Logger) createLogger(Properties config);
30 }
31 
32 
33 package LogLevel matchLogLevel(string level)
34 {
35     switch (level.toUpper) with (LogLevel)
36     {
37         case "TRACE":
38             return trace;
39         case "DEBUG":
40             return debug_;
41         case "INFO":
42             return info;
43         case "WARN":
44             return warn;
45         case "ERROR":
46             return error;
47         case "FATAL":
48             return fatal;
49         default:
50             return info;
51     }
52 }
53 
54 
55 package FileLogger.Format matchLogFormat(string logFormat)
56 {
57     switch (logFormat.toUpper) with (FileLogger.Format)
58     {
59         case "PLAIN":
60             return plain;
61         case "THREAD":
62             return thread;
63         case "THREADTIME":
64             return threadTime;
65         default:
66             return plain;
67     }
68 }
69 
70 
71 /**
72  * Инициализация логирования приложения
73  *
74  * В основе функционала логирования используется реализация из vibed.
75  * Значения по умолчанию: уровень логирования = warn, формат лога = plain
76  *
77  * Params:
78  *
79  * container = Контейнер DI
80  * config    = Объект свойств содержит настройки логгеров
81  * dg        = Функция для обработки логгера
82  */
83 void configureLogging(shared(DependencyContainer) container, Properties config, void function(shared(Logger)) nothrow dg)
84 {
85     configureLogging(container, config, toDelegate(dg));
86 }
87 
88 
89 /**
90  * Инициализация логирования приложения
91  *
92  * В основе функционала логирования используется реализация из vibed.
93  * Значения по умолчанию: уровень логирования = warn, формат лога = plain
94  *
95  * Params:
96  *
97  * container = Контейнер DI
98  * config    = Объект свойств содержит настройки логгеров
99  * dg        = Функция-делегат для обработки логгера
100  */
101 void configureLogging(shared(DependencyContainer) container, Properties config, void delegate(shared(Logger)) nothrow dg)
102 {
103     if ("logger" !in config)
104         return;
105 
106     // отключаем логгер консоли по умолчанию
107     setLogLevel(LogLevel.none);
108 
109     foreach (Properties loggerConf; config.getArray("logger"))
110     {
111         auto appender = loggerConf.get!string("appender");
112         if (appender.isNull)
113             throw new Exception("В конфигурации логера не указан тип ('%s')".format(loggerConf));
114 
115         LoggerFactory factory = container.resolveByName!(LoggerFactory)(appender.get.toUpper);
116         if (factory is null)
117             throw new Exception("Не зарегистрирован логгер с именем " ~ appender);
118 
119         shared(Logger) logger = factory.createLogger(loggerConf);
120         if (logger && dg)
121             dg(logger);
122     }
123 }
124