1 /**
2 Copyright: 2018 Mark Fisher
3 
4 License:
5 Permission is hereby granted, free of charge, to any person obtaining a copy of
6 this software and associated documentation files (the "Software"), to deal in
7 the Software without restriction, including without limitation the rights to
8 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9 of the Software, and to permit persons to whom the Software is furnished to do
10 so, subject to the following conditions:
11 
12 The above copyright notice and this permission notice shall be included in all
13 copies or substantial portions of the Software.
14 
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 SOFTWARE.
22 **/
23 module dxx.util.log;
24 
25 private import std.experimental.logger;
26 private import std.conv;
27 
28 private import dxx.util;
29 
30 /++
31 A notifying logger.
32 ++/
33 
34 final class MsgLog : SyncNotificationSource,NotificationListener {
35     struct LogNotification {
36         LogLevel logLevel;
37         int line;
38         string file;
39         string funcName;
40         string prettyFuncName;
41         string moduleName;
42         string msg;
43     }
44     __gshared shared(MsgLog) _MSGLOG;
45 
46     shared static this() {
47         debug(Log) {
48             sharedLog.trace("MsgLog static this");
49         }
50         if(_MSGLOG is null) {
51             _MSGLOG = new MsgLog;
52             _MSGLOG.addNotificationListener(_MSGLOG);
53         }
54     }
55 
56     override synchronized void handleNotification(void* _p) {
57         debug(Log) {
58             sharedLog.trace("MsgLog handleNotification");
59         }
60         LogNotification* p = cast(LogNotification*)_p;
61         assert(p);
62 
63         //switch(p.logLevel) {
64         //    case LogLevel.trace:
65         //        logger.trace!(p.line,p.file,p.funcName,p.prettyFuncName,p.moduleName)(p.msg);
66         //        break;
67         //    case LogLevel.warning:
68         //        logger.warning!(p.line,p.file,p.funcName,p.prettyFuncName,p.moduleName)(p.msg);
69         //        break;
70         //    case LogLevel.error:
71         //        logger.error!(p.line,p.file,p.funcName,p.prettyFuncName,p.moduleName)(p.msg);
72         //        break;
73         //    case LogLevel.info:
74         //        logger.info!(p.line,p.file,p.funcName,p.prettyFuncName,p.moduleName)(p.msg);
75         //        break;
76         //    case LogLevel.fatal:
77         //        logger.fatal!(p.line,p.file,p.funcName,p.prettyFuncName,p.moduleName)(p.msg);
78         //        break;
79         //}
80     }
81 
82 
83     static auto logger() {
84         if(InjectionContainer.getInstance is null) {
85             return stdThreadLocalLog;
86         }
87         return resolveInjector!Logger;
88     }
89 
90     static void addLogNotificationListener(T)(T t) {
91         _MSGLOG.addNotificationListener(t);
92     }
93     static void removeLogNotificationListener(T)(T t) {
94         _MSGLOG.removeNotificationListener(t);
95     }
96 
97     nothrow
98     static void sendLogNotification(LogNotification n) {
99         _MSGLOG.send!(LogNotification)(&n);
100     }
101 
102     nothrow
103     static void trace(int line = __LINE__, string file = __FILE__,
104             string funcName = __FUNCTION__,
105             string prettyFuncName = __PRETTY_FUNCTION__,
106             string moduleName = __MODULE__, A...)(
107                 lazy A args) {
108         try {
109             version(DXX_Module) {
110                 debug(Module) {
111                     logger.trace("[module]");
112                 }
113             }
114             version(DXX_Developer) {
115                 debug(Developer) {
116                     logger.trace("[dev]");
117                 }
118             }
119             string n;
120             static foreach (a; args) {
121               n ~= a.to!string;
122             }
123             sendLogNotification(LogNotification(LogLevel.trace,line,file,funcName,prettyFuncName,moduleName,n));
124             logger.trace!(line,file,funcName,prettyFuncName,moduleName,A)(args);
125         } catch (Exception e) {
126             //debug { // nothrow
127             //    sharedLog.error(e);
128             //}
129         }
130 
131     }
132     nothrow
133     static void warning(int line = __LINE__, string file = __FILE__,
134             string funcName = __FUNCTION__,
135             string prettyFuncName = __PRETTY_FUNCTION__,
136             string moduleName = __MODULE__, A...)(
137                 lazy A args) {
138         try {
139             version(DXX_Module) {
140                 debug(Module) {
141                     logger.trace("[module]");
142                 }
143             }
144             version(DXX_Developer) {
145                 debug(Developer) {
146                     logger.trace("[dev]");
147                 }
148             }
149             string _args;
150             foreach(a;args) {
151               _args ~= a.to!string;
152             }
153             //sendLogNotification(LogNotification(LogLevel.warning,line,file,funcName,prettyFuncName,moduleName,args.to!string));
154             sendLogNotification(LogNotification(LogLevel.warning,line,file,funcName,prettyFuncName,moduleName,_args));
155             logger.warning!(line,file,funcName,prettyFuncName,moduleName,A)(args);
156         } catch (Exception) {
157         }
158     }
159     nothrow
160     static void error(int line = __LINE__, string file = __FILE__,
161             string funcName = __FUNCTION__,
162             string prettyFuncName = __PRETTY_FUNCTION__,
163             string moduleName = __MODULE__, A...)(
164                 lazy A args) {
165         try {
166             version(DXX_Module) {
167                 debug(Module) {
168                     logger.trace("[module]");
169                 }
170             }
171             version(DXX_Developer) {
172                 debug(Developer) {
173                     logger.trace("[dev]");
174                 }
175             }
176             string _args;
177             foreach(a;args) {
178               _args ~= a.to!string;
179             }
180             sendLogNotification(LogNotification(LogLevel.error,line,file,funcName,prettyFuncName,moduleName,_args));
181             logger.error!(line,file,funcName,prettyFuncName,moduleName,A)(args);
182         } catch (Exception) {
183         }
184     }
185     nothrow
186     static void info(int line = __LINE__, string file = __FILE__,
187             string funcName = __FUNCTION__,
188             string prettyFuncName = __PRETTY_FUNCTION__,
189             string moduleName = __MODULE__, A...)(
190                 lazy A args) {
191         try {
192             version(DXX_Module) {
193                 debug(Module) {
194                     logger.trace("[module]");
195                 }
196             }
197             version(DXX_Developer) {
198                 debug(Developer) {
199                     logger.trace("[dev]");
200                 }
201             }
202             string n;
203             static foreach (a; args) {
204               n ~= a.to!string;
205             }
206             sendLogNotification(LogNotification(LogLevel.info,line,file,funcName,prettyFuncName,moduleName,n));
207             logger.info!(line,file,funcName,prettyFuncName,moduleName,A)(args);
208         } catch (Exception) {
209         }
210     }
211     static void fatal(int line = __LINE__, string file = __FILE__,
212             string funcName = __FUNCTION__,
213             string prettyFuncName = __PRETTY_FUNCTION__,
214             string moduleName = __MODULE__, A...)(
215                 lazy A args) {
216         try {
217             version(DXX_Module) {
218                 debug(Module) {
219                     logger.trace("[module]");
220                 }
221             }
222             version(DXX_Developer) {
223                 debug(Developer) {
224                     logger.trace("[dev]");
225                 }
226             }
227             string _args;
228             foreach(a;args) {
229               _args ~= a.to!string;
230             }
231             sendLogNotification(LogNotification(LogLevel.fatal,line,file,funcName,prettyFuncName,moduleName,_args));
232             logger.fatal!(line,file,funcName,prettyFuncName,moduleName,A)(args);
233         } catch (Exception) {
234         }
235     }
236     static void critical(int line = __LINE__, string file = __FILE__,
237             string funcName = __FUNCTION__,
238             string prettyFuncName = __PRETTY_FUNCTION__,
239             string moduleName = __MODULE__, A...)(
240                 lazy A args) {
241         try {
242             version(DXX_Module) {
243                 debug(Module) {
244                     logger.trace("[module]");
245                 }
246             }
247             version(DXX_Developer) {
248                 debug(Developer) {
249                     logger.trace("[dev]");
250                 }
251             }
252             string _args;
253             foreach(a;args) {
254               _args ~= a.to!string;
255             }
256             sendLogNotification(LogNotification(LogLevel.critical,line,file,funcName,prettyFuncName,moduleName,_args));
257             logger.critical!(line,file,funcName,prettyFuncName,moduleName,A)(args);
258         } catch (Exception) {
259         }
260     }
261 
262 };