1 /**
2 *    Logging system designed to operate in concurrent application.
3 *
4 *    The system should be initialized with $(B initLoggingSystem) function.
5 *    There is no need to call shutdown function as it is happen in module
6 *    destructor.
7 *
8 *    Example:
9 *    ---------
10 *    void testThread()
11 *    {
12 *        foreach(j; 1 .. 50)
13 *        {
14 *            logInfo(to!string(j));
15 *            logError(to!string(j));
16 *        }
17 *    }    
18 *
19 *    foreach(i; 1 .. 50)
20 *    {
21 *        spawn(&testThread);
22 *    }
23 *    ---------
24 *
25 *   Copyright: © 2013-2014 Anton Gushcha
26 *   License: Subject to the terms of the MIT license, as written in the included LICENSE file.
27 *   Authors: NCrashed <ncrashed@gmail.com>
28 *
29 */
30 module dlogg.log;
31 @safe:
32 
33 public import std.conv;
34 
35 /**
36 *   Log levels defines style of the messages.
37 *   Printing in console can be controlled by
38 *   ILogger.minOutputLevel property.
39 */
40 enum LoggingLevel
41 {
42     Notice,
43     Warning,
44     Debug,
45     Fatal,
46     Muted // Used only to mute all writing to console
47 }
48 
49 /**
50 *   Interface for lazy logging. Assumes to be nothrow.
51 *   Underlying realization should be concurrent safe.
52 */
53 shared interface ILogger
54 {
55     /**
56     *   Setting new log file name. If the $(B value)
57     *   differs from old one, logger should close
58     *   old one and open new file.
59     */
60     void name(string value) @property;
61     
62     nothrow 
63     {
64         /**
65         *   Log file name.
66         */
67         string name() @property const;
68         
69         /**
70         *   Prints message into log. Displaying in the console
71         *   controlled by minOutputLevel property.
72         */
73         void log(lazy string message, LoggingLevel level);
74 
75         /**
76         *   Returns: minimum log level,  will be printed in the console.
77         */
78         LoggingLevel minOutputLevel() const @property;
79 
80         /**
81         *   Setups minimum log level, 
82         */
83         void minOutputLevel(LoggingLevel level) @property;
84         
85         /**
86         *   Used to manual shutdown protocols.
87         */
88         void finalize();
89     }
90 
91     /**
92     *   Unsafe write down the message without any meta information.
93     */
94     void rawInput(string message);
95     
96     /**
97     *   Format message with default logging style (etc. time and level string).
98     */
99     string formatString(lazy string message, LoggingLevel level);
100     
101     /**
102     *   Checks if the log file is exists at specified $(B location) and
103     *   if can't find it, recreates the file and continues write into it.
104     *
105     *   Useful for $(B logrotate) utility. GNU/Linux system checks file identity by
106     *   inode, that doesn't change while renaming. Thus after renaming the file at 
107     *   $(B location) log continues write into the renamed file. The call to the
108     *   $(B reload) method force splitting log into two parts.
109     *
110     *   Note: The method is not nothrow!
111     */
112     void reload();
113 
114     // wrappers for easy logging
115     final nothrow @trusted
116     {
117         /**
118         *   Wrapper for handy debug messages.
119         *   Warning: main purpose for debug messages, thus it is not lazy.
120         */
121         void logDebug(E...)(E args) shared @trusted
122         {
123             scope(failure) {}
124             debug
125             {
126                 string str = text(args);
127                 log(str, LoggingLevel.Debug);
128             }
129         }
130         
131         void logInfo(lazy string message)
132         {
133             log(message, LoggingLevel.Notice);
134         }
135 
136         void logWarning(lazy string message)
137         {
138             log(message, LoggingLevel.Warning);
139         }
140 
141         void logError(lazy string message)
142         {
143             log(message, LoggingLevel.Fatal);
144         }
145     }
146 }