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 ) 23 { 24 this.parent = parent; 25 if( parent ) 26 this.level = parent.level; 27 } 28 29 /// 30 @property bool useMinimal() const 31 { 32 if( parent !is null ) 33 return parent.useMinimal(); 34 else return use_minimal; 35 } 36 37 /// setting allowed level for emitter (create new inner Rule), if emitter is "" sets self level 38 void setLevel( LogLevel lvl, string emitter="" ) 39 { 40 auto addr = splitAddress( emitter ); 41 if( addr[0].length == 0 ) { level = lvl; return; } 42 auto iname = addr[0]; 43 if( iname !in inner ) inner[iname] = new shared Rule(this); 44 inner[iname].setLevel( lvl, addr[1] ); 45 } 46 47 /// if emitter is "" returns self level 48 LogLevel allowedLevel( string emitter="" ) 49 { 50 auto addr = splitAddress( emitter ); 51 if( addr[0].length == 0 ) return level; 52 auto iname = addr[0]; 53 if( iname !in inner ) return level; 54 if( useMinimal ) 55 return min( level, inner[iname].allowedLevel( addr[1] ) ); 56 else 57 return inner[iname].allowedLevel( addr[1] ); 58 } 59 60 string print( string offset="" ) const 61 { 62 string ret = format( "%s", level ); 63 foreach( key, val; inner ) 64 ret ~= format( "\n%s%s : %s", offset, key, val.print( offset ~ mlt(" ",key.length) ) ); 65 return ret; 66 } 67 68 protected: 69 70 /// 71 static string[2] splitAddress( string emitter ) 72 { 73 auto addr = emitter.split("."); 74 if( addr.length == 0 ) return ["",""]; 75 if( addr.length == 1 ) return [addr[0],""]; 76 77 return [ addr[0], addr[1..$].join(".") ]; 78 } 79 } 80 81 private T[] mlt(T)( T[] val, size_t cnt ) nothrow 82 { 83 T[] buf; 84 foreach( i; 0 .. cnt ) buf ~= val; 85 return buf; 86 } 87 88 unittest { assert( " ", mlt( " ", 4 ) ); } 89 90 /// 91 unittest 92 { 93 auto r = new shared Rule; 94 95 r.setLevel( LogLevel.INFO ); 96 r.setLevel( LogLevel.TRACE, "des.gl" ); 97 r.setLevel( LogLevel.WARN, "des" ); 98 99 assert( r.allowedLevel() == LogLevel.INFO ); 100 assert( r.allowedLevel("des") == LogLevel.WARN ); 101 assert( r.allowedLevel("des.gl") == LogLevel.WARN ); 102 103 r.use_minimal = false; 104 105 assert( r.allowedLevel() == LogLevel.INFO ); 106 assert( r.allowedLevel("des") == LogLevel.WARN ); 107 assert( r.allowedLevel("des.gl") == LogLevel.TRACE ); 108 }