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