1 module des.log.base; 2 3 import std.conv : to; 4 import std.datetime : Clock; 5 import std.string : toUpper, format; 6 7 import des.log.output; 8 import des.log.rule; 9 10 /// 11 class LogException : Exception 12 { this( string msg ) pure @safe nothrow { super(msg); } } 13 14 /// 15 enum LogLevel 16 { 17 OFF, /// no output 18 FATAL, /// not recoverible error 19 ERROR, /// recoverible error (exceptions) 20 WARN, /// warning (only if something wrong but not critical) 21 INFO, /// info message (one-call functions messages) 22 DEBUG, /// debug message (detalied one-call functions messages) 23 TRACE /// trace message (idle, foreach, etc) 24 }; 25 26 /// 27 struct LogMessage 28 { 29 string emitter; /// name of log message emmiter 30 ulong ts; /// timestamp 31 32 /// log message level (without LogLevel.OFF) 33 enum Level : LogLevel 34 { 35 FATAL = LogLevel.FATAL, /// 36 ERROR, /// 37 WARN, /// 38 INFO, /// 39 DEBUG, /// 40 TRACE /// 41 }; 42 43 Level level; /// log level 44 string message; /// 45 46 /// 47 @disable this(); 48 49 /// 50 this( string emitter, ulong ts, Level level, string message ) pure nothrow @safe 51 { 52 this.emitter = emitter; 53 this.ts = ts; 54 this.level = level; 55 this.message = message; 56 } 57 } 58 59 /++ 60 nothrow format function, if first is string it try call string.format, 61 if it's failed return all args converted to string 62 +/ 63 string ntFormat(Args...)( Args args ) nothrow 64 { 65 try 66 { 67 static if( is( Args[0] == string ) ) 68 { try return format(args); catch{} } 69 70 string res; 71 foreach( arg; args ) 72 res ~= to!string(arg); 73 return res; 74 } 75 catch( Exception e ) 76 return "[MESSAGE CTOR EXCEPTION]: " ~ e.msg; 77 } 78 79 /// 80 LogLevel toLogLevel( string s ) { return to!LogLevel( s.toUpper ); } 81 82 /++ 83 Returns: 84 format( "[%016.9f][%5s][%s]: %s", lm.ts / 1e9f, lm.level, lm.emitter, lm.message ); 85 +/ 86 string defaultFormatLogMessage( in LogMessage lm ) 87 { 88 return format( "[%016.9f][%5s][%s]: %s", 89 lm.ts / 1e9f, lm.level, lm.emitter, lm.message ); 90 } 91 92 package: 93 94 static shared OutputHandler g_output; 95 static shared Rule g_rule; 96 97 ulong __ts() nothrow @property 98 { 99 try return Clock.currAppTick().length; 100 catch(Exception e) return 0; 101 } 102 103 string fixReservedName( string name ) nothrow 104 { 105 if( name == "debug" ) return "Debug"; 106 return name; 107 }