1 module kissrpc.Logs;
2 
3 import kissrpc.Unit;
4 
5 import std.string;
6 import std.format;
7 import std.stdio;
8 import std.array : appender;
9 import std.file;
10 import std.experimental.logger;
11 
12 
13 immutable string PRINT_COLOR_NONE  = "\033[m";
14 immutable string PRINT_COLOR_RED   =  "\033[0;32;31m";
15 immutable string PRINT_COLOR_GREEN  = "\033[0;32;32m";
16 immutable string PRINT_COLOR_YELLOW = "\033[0;33m";
17 
18 __gshared FileLogger logFile = null;
19 
20 enum LOG_LEVEL
21 {
22 	LL_INFO,
23 	LL_WARNING,
24 	LL_DEBUG,
25 	LL_ERROR,
26 	LL_CRITICAL,
27 	LL_FATAL,
28 }
29 
30 
31 //#define PRINT_COLOR_YELLOW 	   "\033[1;33m"
32 //#define PRINT_COLOR_BLUE         "\033[0;32;34m"
33 //#define PRINT_COLOR_WHITE        "\033[1;37m"
34 //#define PRINT_COLOR_CYAN         "\033[0;36m"
35 //#define PRINT_COLOR_PURPLE       "\033[0;35m"
36 //#define PRINT_COLOR_BROWN        "\033[0;33m"
37 //#define PRINT_COLOR_DARY_GRAY    "\033[1;30m"
38 //#define PRINT_COLOR_LIGHT_RED    "\033[1;31m"
39 //#define PRINT_COLOR_LIGHT_GREEN  "\033[1;32m"
40 //#define PRINT_COLOR_LIGHT_BLUE   "\033[1;34m"
41 //#define PRINT_COLOR_LIGHT_CYAN   "\033[1;36m"
42 //#define PRINT_COLOR_LIGHT_PURPLE "\033[1;35m"
43 //#define PRINT_COLOR_LIGHT_GRAY   "\033[0;37m"
44 
45 
46 version(Windows)
47 {
48 	import core.sys.windows.wincon;
49 	import core.sys.windows.winbase;
50 	import core.sys.windows.windef;
51 	
52 	__gshared HANDLE g_hout = null;
53 	
54 	void win_writeln(string msg , ushort color)
55 	{
56 		if(g_hout is null)
57 			g_hout = GetStdHandle(STD_OUTPUT_HANDLE);
58 		SetConsoleTextAttribute(g_hout , color);
59 		writeln(msg);
60 		SetConsoleTextAttribute(g_hout ,  FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED);
61 	}
62 	
63 }
64 
65 private string convTostr(string msg , string file , size_t line)
66 {
67 	import std.conv;
68 	return msg ~ " - " ~ file ~ ":" ~ to!string(line);	
69 }
70 
71 bool setOutputLogPath(string filePath)
72 {
73 	logFile = new FileLogger(filePath);
74 
75 	if(!logFile.file.isOpen)
76 	{
77 		logFile = null;
78 		logError("log file is not open!!, file path:%s", logFile);
79 
80 		return false;
81 	}
82 
83 	return true;
84 }
85 
86 
87 void outputLog(LOG_LEVEL type, string logText)
88 {
89 		switch(type)
90 		{
91 			case LOG_LEVEL.LL_ERROR, LOG_LEVEL.LL_FATAL, LOG_LEVEL.LL_CRITICAL: 
92 				logFile.fatal(logText);
93 				break;
94 				
95 			case LOG_LEVEL.LL_INFO: logFile.info(logText); break;
96 				
97 			case LOG_LEVEL.LL_WARNING: logFile.warning(logText); break;
98 				
99 			case LOG_LEVEL.LL_DEBUG: logFile.trace(logText); break;
100 
101 			default:break;
102 		}
103 }
104 
105 void logKiss(string msg , LOG_LEVEL type ,  string file = __FILE__ , size_t line = __LINE__)
106 {
107 	string timePrior = RPC_SYSTEM_TIMESTAMP_STR;
108 	
109 	version(Posix)
110 	{
111 		string prior;
112 		string suffix = PRINT_COLOR_NONE;
113 
114 		if(type == LOG_LEVEL.LL_ERROR || type == LOG_LEVEL.LL_FATAL ||  type == LOG_LEVEL.LL_CRITICAL)
115 		{
116 			prior = PRINT_COLOR_RED;
117 		}
118 		else if(type == LOG_LEVEL.LL_INFO)
119 		{
120 			prior = PRINT_COLOR_GREEN;
121 			
122 		}else if(type == LOG_LEVEL.LL_WARNING)
123 		{
124 			prior = PRINT_COLOR_YELLOW;
125 		}
126 
127 		if(logFile !is null)
128 		{
129 			outputLog(type, msg);
130 		}else
131 		{
132 			string outInfo = format("%s [%s] %s:%s %s", prior, type, timePrior, msg, suffix);
133 			writeln(outInfo);
134 		}
135 
136 	}
137 	else
138 	{
139 		
140 
141 		if(type == LOG_LEVEL.LL_ERROR || type == LOG_LEVEL.LL_FATAL ||  type == LOG_LEVEL.LL_CRITICAL)
142 		{
143 			if(logFile !is null)
144 			{
145 				outputLog(msg, type);
146 			}else
147 			{
148 				string outInfo = format("[%s] %s:%s ", type, timePrior, msg);
149 
150 				win_writeln(outInfo , FOREGROUND_RED);
151 			}
152 
153 		}
154 		else if(type == LOG_LEVEL.LL_WARNING || type == LOG_LEVEL.LL_INFO)
155 		{
156 			if(logFile !is null)
157 			{
158 				outputLog(msg, type);
159 			}else
160 			{
161 				string outInfo = format("[%s] %s:%s ", type, timePrior, msg);
162 				win_writeln(outInfo , FOREGROUND_GREEN);
163 			}
164 
165 		}
166 		else
167 		{
168 			if(logFile !is null)
169 			{
170 				outputLog(msg, type);
171 			}else
172 			{
173 				string outInfo = format("[%s] %s:%s ", type, timePrior, msg);
174 				win_writeln(outInfo , FOREGROUND_GREEN);
175 			}
176 		}
177 	}
178 	
179 }
180 
181 
182 version(onyxLog)
183 {
184 	import onyx.log;
185 	import onyx.bundle;
186 	import core.sys.windows.winbase;
187 	
188 	__gshared Log g_log;
189 	
190 	void log_debug(string msg , string file = __FILE__ , size_t line = __LINE__)
191 	{
192 		if(g_log !is null )
193 			g_log.debug_(convTostr(msg , file , line));
194 		logKiss(msg , LOG_LEVEL.LL_DEBUG , file , line);
195 	}
196 	
197 	void logInfo(string msg , string file = __FILE__ , size_t line = __LINE__)
198 	{
199 		if(g_log !is null)
200 			g_log.info(convTostr(msg , file , line));
201 		logKiss(msg , LOG_LEVEL.LL_INFO, file , line);
202 	}
203 	
204 	void logWarning(string msg , string file = __FILE__ , size_t line = __LINE__)
205 	{
206 		if(g_log !is null)
207 			g_log.warning(convTostr(msg , file , line));
208 		logKiss(msg , LOG_LEVEL.LL_WARNING , file , line);
209 	}
210 	
211 	void logError(string msg , string file = __FILE__ , size_t line = __LINE__)
212 	{
213 		if(g_log !is null)
214 			g_log.error(convTostr(msg , file , line));
215 		logKiss(msg , LOG_LEVEL.LL_ERROR , file , line);
216 	}
217 	
218 	void logCritical(string msg ,string file = __FILE__ , size_t line = __LINE__)
219 	{
220 		if(g_log !is null)
221 			g_log.critical(convTostr(msg , file , line));
222 		logKiss(msg , LOG_LEVEL.LL_CRITICAL , file , line);
223 	}
224 	
225 	void logFatal(string msg ,string file = __FILE__ , size_t line = __LINE__)
226 	{
227 		if(g_log !is null)
228 			g_log.fatal(convTostr(msg , file , line));
229 		logKiss(msg , LOG_LEVEL.LL_FATAL , file , line);
230 	}
231 	
232 }
233 else
234 {
235 	void kissLogDebug(string msg , string file = __FILE__ , size_t line = __LINE__)
236 	{
237 		logKiss(msg , LOG_LEVEL.LL_DEBUG , file , line);
238 	}
239 	void kissLogInfo(string msg , string file = __FILE__ , size_t line = __LINE__)
240 	{
241 		logKiss(msg , LOG_LEVEL.LL_INFO , file , line);
242 	}
243 	void kissLogWarning(string msg , string file = __FILE__ , size_t line = __LINE__)
244 	{
245 		logKiss(msg , LOG_LEVEL.LL_WARNING , file , line);
246 	}
247 	void kissLogError(string msg , string file = __FILE__ , size_t line = __LINE__)
248 	{
249 		logKiss(msg , LOG_LEVEL.LL_ERROR ,  file , line);
250 	}
251 	void kissLogCritical(string msg ,string file = __FILE__ , size_t line = __LINE__)
252 	{
253 		logKiss(msg , LOG_LEVEL.LL_CRITICAL , file , line);
254 	}
255 	void kissLogFatal(string msg ,string file = __FILE__ , size_t line = __LINE__)
256 	{
257 		logKiss(msg , LOG_LEVEL.LL_FATAL ,  file , line);
258 	}
259 	
260 }
261 
262 void logFormat(T ...)(T args, const LOG_LEVEL level)
263 {
264 	auto strings = appender!string();
265 	formattedWrite(strings, args);
266 	auto info = strings.data;
267 	
268 	switch(level)
269 	{
270 		case LOG_LEVEL.LL_INFO: kissLogInfo(info); break;
271 		case LOG_LEVEL.LL_WARNING: kissLogWarning(info); break;
272 		case LOG_LEVEL.LL_DEBUG: kissLogDebug(info); break;
273 		case LOG_LEVEL.LL_ERROR: kissLogError(info); break;
274 		case LOG_LEVEL.LL_CRITICAL: kissLogCritical(info); break;
275 		case LOG_LEVEL.LL_FATAL: kissLogFatal(info); break;
276 			
277 		default: 
278 			kissLogInfo(info);
279 	}
280 }
281 
282 void logFormatDebug(T ...)(T args)
283 {
284 	logFormat(args, LOG_LEVEL.LL_DEBUG);
285 }
286 
287 void logFormatInfo(T ...)(T args)
288 {
289 	logFormat(args, LOG_LEVEL.LL_INFO);
290 }
291 
292 void logFormatWarning(T ...)(T args)
293 {
294 	logFormat(args, LOG_LEVEL.LL_WARNING);
295 }
296 
297 void logFormatError(T ...)(T args)
298 {
299 	logFormat(args, LOG_LEVEL.LL_ERROR);
300 }
301 
302 void logFormatCritical(T ...)(T args)
303 {
304 	logFormat(args, LOG_LEVEL.LL_CRITICAL);
305 }
306 	
307 void logFormatFatal(T ...)(T args)
308 {
309 	logFormat(args, LOG_LEVEL.LL_FATAL);
310 }
311 
312 version(RpcDebug)
313 {
314 	alias deWritefln = logFormatDebug;
315 	alias deWriteln = logFormatDebug;
316 }else
317 {
318 	void nullLog(T ...)(T args)
319 	{
320 
321 	}
322 //	alias deWritefln = logFormatDebug;
323 //	alias deWriteln = logFormatDebug;
324 	alias deWritefln = nullLog;
325 	alias deWriteln = nullLog;
326 }
327 
328 version(UltraHigh)
329 {
330 	void nullLog(T ...)(T args)
331 	{
332 		
333 	}
334 
335 	alias logInfo = nullLog;
336 	alias logWarning = nullLog;
337 	alias logError = nullLog;
338 	alias logCritical = nullLog;
339 	alias logFatal = nullLog;
340 }else
341 {
342 	alias logInfo = logFormatInfo;
343 	alias logWarning = logFormatWarning;
344 	alias logError = logFormatError;
345 	alias logCritical = logFormatCritical;
346 	alias logFatal = logFormatFatal;
347 }
348 
349 
350 
351 unittest
352 {
353 	import kissrpc.Logs;
354 //
355 //	setOutputLogPath("./info.log");
356 //
357 //
358 	writeln("-------------------------------------------------------");
359 	logFormatDebug("debug");
360 	logInfo("info");
361 	logError("errro");
362 	
363 }