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 }