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