1 module des.util.logsys.rule; 2 3 import std.algorithm : min; 4 import std.string : split, join; 5 6 import des.util.logsys.base; 7 8 /// store rules for logging 9 package synchronized class Rule 10 { 11 package: 12 shared Rule parent; /// 13 14 LogLevel level = LogLevel.ERROR; /// 15 shared Rule[string] inner; /// 16 17 bool use_minimal = true; /// 18 19 public: 20 21 /// 22 this( shared Rule parent = null ) { this.parent = parent; } 23 24 /// 25 @property bool useMinimal() const 26 { 27 if( parent !is null ) 28 return parent.useMinimal(); 29 else return use_minimal; 30 } 31 32 /// setting allowed level for emitter (create new inner Rule), if emitter is "" sets self level 33 void setLevel( LogLevel lvl, string emitter="" ) 34 { 35 auto addr = splitAddress( emitter ); 36 if( addr[0].length == 0 ) { level = lvl; return; } 37 auto iname = addr[0]; 38 if( iname !in inner ) inner[iname] = new shared Rule(this); 39 inner[iname].setLevel( lvl, addr[1] ); 40 } 41 42 /// if emitter is "" returns self level 43 LogLevel allowedLevel( string emitter="" ) 44 { 45 auto addr = splitAddress( emitter ); 46 if( addr[0].length == 0 ) return level; 47 auto iname = addr[0]; 48 if( iname !in inner ) return level; 49 if( useMinimal ) 50 return min( level, inner[iname].allowedLevel( addr[1] ) ); 51 else 52 return inner[iname].allowedLevel( addr[1] ); 53 } 54 55 string print( string offset="" ) const 56 { 57 string ret = format( "%s", level ); 58 foreach( key, val; inner ) 59 ret ~= format( "\n%s%s : %s", offset, key, val.print( offset ~ mlt(" ",key.length) ) ); 60 return ret; 61 } 62 63 protected: 64 65 /// 66 static string[2] splitAddress( string emitter ) 67 { 68 auto addr = emitter.split("."); 69 if( addr.length == 0 ) return ["",""]; 70 if( addr.length == 1 ) return [addr[0],""]; 71 72 return [ addr[0], addr[1..$].join(".") ]; 73 } 74 } 75 76 private T[] mlt(T)( T[] val, size_t cnt ) nothrow 77 { 78 T[] buf; 79 foreach( i; 0 .. cnt ) buf ~= val; 80 return buf; 81 } 82 83 unittest { assert( " ", mlt( " ", 4 ) ); } 84 85 /// 86 unittest 87 { 88 auto r = new shared Rule; 89 90 r.setLevel( LogLevel.INFO ); 91 r.setLevel( LogLevel.TRACE, "des.gl" ); 92 r.setLevel( LogLevel.WARN, "des" ); 93 94 assert( r.allowedLevel() == LogLevel.INFO ); 95 assert( r.allowedLevel("des") == LogLevel.WARN ); 96 assert( r.allowedLevel("des.gl") == LogLevel.WARN ); 97 98 r.use_minimal = false; 99 100 assert( r.allowedLevel() == LogLevel.INFO ); 101 assert( r.allowedLevel("des") == LogLevel.WARN ); 102 assert( r.allowedLevel("des.gl") == LogLevel.TRACE ); 103 }