1 /*******************************************************************************
2 
3     Implementation of logging appender which writes to both stdout and stderr
4     based on logging level.
5 
6     Copyright:
7         Copyright (c) 2009-2016 dunnhumby Germany GmbH.
8         All rights reserved.
9 
10     License:
11         Boost Software License Version 1.0. See LICENSE_BOOST.txt for details.
12         Alternatively, this file may be distributed under the terms of the Tango
13         3-Clause BSD License (see LICENSE_BSD.txt for details).
14 
15 *******************************************************************************/
16 
17 module ocean.util.log.AppendStderrStdout;
18 
19 
20 import ocean.meta.types.Qualifiers;
21 import ocean.util.log.Appender;
22 import ocean.util.log.Event;
23 import ocean.util.log.ILogger;
24 
25 /*******************************************************************************
26 
27     Appender class.
28 
29     Important properties:
30         - always flushes after logging
31         - warnings/errors/fatals go to stderr
32         - info/traces/debug goes to stdout
33 
34     Exact log level to be treated as first "stderr" level can be configured
35     via constructor.
36 
37 *******************************************************************************/
38 
39 public class AppendStderrStdout : Appender
40 {
41     import ocean.io.device.Device;
42     import ocean.io.Console;
43 
44     /***********************************************************************
45 
46         Cached mask value used by logger internals
47 
48     ***********************************************************************/
49 
50     private Mask mask_;
51 
52     /***********************************************************************
53 
54         Defines which logging Level will be used as first "error" level.
55 
56     ***********************************************************************/
57 
58     private ILogger.Level first_stderr_level;
59 
60     /***********************************************************************
61 
62         Constructor
63 
64         Params:
65             first_stderr_level = LogEvent with this level and higher will
66                 be written to stderr. Defaults to Level.Warn
67             how = optional custom layout object
68 
69     ************************************************************************/
70 
71     public this (ILogger.Level first_stderr_level = ILogger.Level.Warn,
72                  Appender.Layout how = null)
73     {
74         this.mask_ = this.register(name);
75         this.first_stderr_level = first_stderr_level;
76         this.layout(how);
77     }
78 
79     /***********************************************************************
80 
81         Returns:
82             the fingerprint for this class
83 
84     ************************************************************************/
85 
86     final override public Mask mask ()
87     {
88         return this.mask_;
89     }
90 
91     /***********************************************************************
92 
93         Returns:
94             the name of this class
95 
96     ************************************************************************/
97 
98     override public istring name ()
99     {
100         return this.classinfo.name;
101     }
102 
103     /***********************************************************************
104 
105         Writes log event to target stream
106 
107         Params:
108             event = log message + metadata
109 
110     ************************************************************************/
111 
112     final override public void append (LogEvent event)
113     {
114         OutputStream stream;
115         if (event.level >= this.first_stderr_level)
116             stream = Cerr.stream();
117         else
118             stream = Cout.stream();
119 
120         layout.format(
121             event,
122             (cstring content) {
123                 stream.write(content);
124             }
125         );
126         stream.write(Console.Eol);
127         stream.flush;
128     }
129 }