1 /**
2 	Central logging facility for vibe.
3 
4 	Copyright: © 2012 RejectedSoftware e.K.
5 	License: Subject to the terms of the MIT license, as written in the included LICENSE.txt file.
6 	Authors: Sönke Ludwig
7 */
8 module dub.internal.vibecompat.core.log;
9 
10 import std.array;
11 import std.datetime;
12 import std.format;
13 import std.stdio;
14 import core.thread;
15 
16 private {
17 	shared LogLevel s_minLevel = LogLevel.info;
18 	shared LogLevel s_logFileLevel;
19 }
20 
21 /// Sets the minimum log level to be printed.
22 void setLogLevel(LogLevel level) nothrow
23 {
24 	s_minLevel = level;
25 }
26 
27 /**
28 	Logs a message.
29 
30 	Params:
31 		level = The log level for the logged message
32 		fmt = See http://dlang.org/phobos/std_format.html#format-string
33 */
34 void logDebug(T...)(string fmt, auto ref T args) nothrow { log(LogLevel.debug_, fmt, args); }
35 /// ditto
36 void logDiagnostic(T...)(string fmt, auto ref T args) nothrow { log(LogLevel.diagnostic, fmt, args); }
37 /// ditto
38 void logInfo(T...)(string fmt, auto ref T args) nothrow { log(LogLevel.info, fmt, args); }
39 /// ditto
40 void logWarn(T...)(string fmt, auto ref T args) nothrow { log(LogLevel.warn, fmt, args); }
41 /// ditto
42 void logError(T...)(string fmt, auto ref T args) nothrow { log(LogLevel.error, fmt, args); }
43 
44 /// ditto
45 void log(T...)(LogLevel level, string fmt, auto ref T args)
46 nothrow {
47 	if( level < s_minLevel ) return;
48 	string pref;
49 	final switch( level ){
50 		case LogLevel.debug_: pref = "trc"; break;
51 		case LogLevel.diagnostic: pref = "dbg"; break;
52 		case LogLevel.info: pref = "INF"; break;
53 		case LogLevel.warn: pref = "WRN"; break;
54 		case LogLevel.error: pref = "ERR"; break;
55 		case LogLevel.fatal: pref = "FATAL"; break;
56 		case LogLevel.none: assert(false);
57 	}
58 
59 	try {
60 		auto txt = appender!string();
61 		txt.reserve(256);
62 		formattedWrite(txt, fmt, args);
63 
64 		auto threadid = cast(ulong)cast(void*)Thread.getThis();
65 		auto fiberid = cast(ulong)cast(void*)Fiber.getThis();
66 		threadid ^= threadid >> 32;
67 		fiberid ^= fiberid >> 32;
68 
69 		if( level >= s_minLevel ){
70 			if (level == LogLevel.info) {
71 				stdout.writeln(txt.data());
72 				stdout.flush();
73 			} else {
74 				stderr.writeln(txt.data());
75 				stderr.flush();
76 			}
77 		}
78 	} catch( Exception e ){
79 		// this is bad but what can we do..
80 		debug assert(false, e.msg);
81 	}
82 }
83 
84 /// Specifies the log level for a particular log message.
85 enum LogLevel {
86 	debug_,
87 	diagnostic,
88 	info,
89 	warn,
90 	error,
91 	fatal,
92 	none
93 }
94