1 /**
2 *   Sometimes logging is needed only if something goes wrong. This module
3 *   describes a class-wrapper to handle delayed logging. 
4 *
5 *   Example:
6 *   ----------
7 *   auto delayed = new shared BufferedLogger(logger); // wrapping a logger
8 *	scope(exit) delayed.finalize(); // write down information in wrapped logger
9 *   scope(failure) delayed.minOutputLevel = LoggingLevel.Notice; // if failed, spam in console
10 *   delayed.logNotice("Hello!");
11 *
12 *   // do something that can fail
13 *
14 *   ----------
15 *
16 *   Copyright: © 2013-2014 Anton Gushcha
17 *   License: Subject to the terms of the MIT license, as written in the included LICENSE file.
18 *   Authors: NCrashed <ncrashed@gmail.com>
19 */
20 module dlogg.buffered;
21 
22 import std.array;
23 import std.stdio;
24 import dlogg.strict;
25 
26 /**
27 *   Alias for $(B StyledBufferedLogger) for default logging style.
28 */
29 alias BufferedLogger = StyledBufferedLogger!(LoggingLevel
30                 , LoggingLevel.Debug,   "Debug: %1$s",   "[%2$s]: Debug: %1$s"
31                 , LoggingLevel.Notice,  "Notice: %1$s",  "[%2$s]: Notice: %1$s"
32                 , LoggingLevel.Warning, "Warning: %1$s", "[%2$s]: Warning: %1$s"
33                 , LoggingLevel.Fatal,   "Fatal: %1$s",   "[%2$s]: Fatal: %1$s"
34                 , LoggingLevel.Muted,   "",              ""
35                 );
36 
37 /**
38 *   Class-wrapper around strict logger. All strings are written down
39 *   only after finalizing the wrapper. Usually you want to use alias
40 *   for standart style $(B BufferedLogger).
41 */
42 synchronized class StyledBufferedLogger(StyleEnum, US...) : StyledStrictLogger!(StyleEnum, US)
43 {
44     this(shared ILogger delayLogger)
45     {
46         this.delayLogger = delayLogger;
47         minOutputLevel = LoggingLevel.Muted;
48     }
49     
50     override void rawInput(string message) @trusted
51     {
52         buffer ~= message;
53     }
54     
55     override void finalize() @trusted
56     {
57         if(finalized) return;
58         scope(exit) finalized = true;
59         
60         foreach(msg; buffer)
61         {
62             try
63             {
64 	            if(minOutputLevel != LoggingLevel.Muted)
65 	                writeln(msg);
66 	                
67 	            delayLogger.rawInput(msg);
68             } catch(Throwable th)
69             {
70             	
71             }
72         }
73     }
74     
75     private
76     {
77         shared ILogger delayLogger;
78         string[] buffer;
79         bool finalized;
80     }
81 }