Wiki source code of Wonder Logging

Version 11.1 by Johann Werner on 2014/01/14 11:13

Show last authors
1 This page describes how you should do logging in Wonder as well as in your apps and frameworks based on Wonder. Wonder is a really huge collection of different frameworks so there are currently different ways of logging used in it. Those will be converted to the suggested form when time permits. Below the current and future logging setup are described. For those only interested in the how-do-I-log here the quintessence:
2
3 === Logging Framework ===
4
5 SLF4J
6 [[http:~~/~~/www.slf4j.org/>>url:http://www.slf4j.org/||style="text-decoration: none;" shape="rect"]]
7
8 === Needed Frameworks ===
9
10 slf4j-api-1.7.5.jar
11 slf4j-log4j12-1.7.5.jar
12
13 Both are already included in ERJars so no action required in a Wonder project!
14
15 === Output ===
16
17 The output of SLF4J is redirected to log4j, currently the main log provider in Wonder. That means there is no visible change for you. You keep your log4j configuration, have the same log output pattern etc.
18
19 === Coding ===
20
21 First you need a logger object:
22
23 {{code language="java"}}
24 Logger log = LoggerFactory.getLogger(MyClass.class);
25 {{/code}}
26
27 SLF4J brings you the power of parameterized messages. If you want to log some values you write:
28
29 {{code language="java"}}
30 log.debug("The value of '{}' is '{}'", key, value);
31 {{/code}}
32
33 (% class="Apple-style-span" style="white-space: pre-wrap;" %)This prevents code concatenation until the logging is really necessary. If the log statement is output all curly braces //{}// are interpreted as placeholders and the given parameters are used in order to construct the message. This means you can safely drop checks like
34
35 {{code language="java"}}
36 if (log.isDebugEnabled()) { … }
37 {{/code}}
38
39 (% class="Apple-style-span" style="white-space: pre-wrap;" %)making your code less verbose and shorter. Though you should use such a check if you need to pass a computationally expensive parameter:
40
41 {{code language="java"}}
42 if (log.isDebugEnabled()) {
43 log.debug("The value was: {}", computeExpensiveValue());
44 }
45 {{/code}}
46
47 (% class="Apple-style-span" style="white-space: pre-wrap;" %)The available log levels are matching those of log4j with the exception of the intentionally missing //fatal//:
48
49 * ERROR
50 * WARN
51 * INFO
52 * DEBUG
53 * TRACE
54
55 When logging exceptions SLF4J interprets the last parameter as stacktrace if it is an exception object:
56
57 {{code language="java"}}
58 try {
59
60 } catch (Exception e) {
61 log.error("Could not do whatever I wanted to do!", e);
62 }
63 {{/code}}
64
65 (% class="Apple-style-span" style="white-space: pre-wrap;" %)
66
67 Of course you still can use parameters as long as the exception is the last param:
68
69 {{code language="java"}}
70 try {
71
72 } catch (Exception e) {
73 log.error("Error during processing of id {}", id, e);
74 }
75 {{/code}}
76
77 === More SLF4J info ===
78
79 (% class="Apple-style-span" style="white-space: pre-wrap;" %)For more info regarding SLF4J look at the introductory [[user manual>>url:http://www.slf4j.org/manual.html||shape="rect"]] or head to their [[documentation page>>url:http://www.slf4j.org/docs.html||shape="rect"]].
80
81 (% class="Apple-style-span" style="white-space: pre-wrap;" %)
82
83
84 ----
85
86 == Wonder Logging Libraries (Current) ==
87
88 Wonder comes with different logging libraries due to its long history and huge number of sources and frameworks. Those are:
89
90 === NSLog ===
91
92 NSLog is the original logging facility of WebObjects and thus used mainly in the core WO frameworks. With Wonder the logging is configured to redirect its output to log4j (see [[ERXNSLogLog4jBridge>>url:http://jenkins.wocommunity.org/job/WonderIntegration/lastSuccessfulBuild/javadoc/er/extensions/logging/ERXNSLogLog4jBridge.html||shape="rect"]] and [[ERXLogger#configureLogging>>url:http://jenkins.wocommunity.org/job/WonderIntegration/lastSuccessfulBuild/javadoc/er/extensions/logging/ERXLogger.html#configureLogging(java.util.Properties)||shape="rect"]]).
93
94 [[http:~~/~~/wocommunity.org/documents/javadoc/WebObjects/5.4.2/com/webobjects/foundation/NSLog.html>>url:http://wocommunity.org/documents/javadoc/WebObjects/5.4.2/com/webobjects/foundation/NSLog.html||shape="rect"]]
95
96 === commons logging ===
97
98 The Apache commons logging isn't used by Wonder itself but some of its bundled libraries are relying on it to produce log messages like the Apache HttpClient. You can find the corresponding library in ERJars.
99
100 [[http:~~/~~/commons.apache.org/proper/commons-logging/>>url:http://commons.apache.org/proper/commons-logging/||shape="rect"]]
101
102 === log4j ===
103
104 Log4j is the main logging facility of Wonder. For that – as stated above – the logging of WebObjects from NSLog is redirected to log4j so you have only a single logging configuration to maintain. The log4j library is included in ERJars.
105
106 [[http:~~/~~/logging.apache.org/log4j/1.2/>>url:http://logging.apache.org/log4j/1.2/||shape="rect"]]
107
108 === SLF4J ===
109
110 SLF4J is barely used in Wonder currently. It is not a real logging framework like log4j as in fact it acts only as a facade to any logging framework. To produce real logging output you can throw in one of several plugins that redirects the output to a specific logging framework. In Wonder the log4j plugin is used for that, i.e. logging done with slf4j is redirected to log4j as is NSLog. Look at ERJars for both files.
111
112 [[http:~~/~~/www.slf4j.org/>>url:http://www.slf4j.org/||shape="rect"]]
113
114 ----
115
116 == Wonder Logging Libraries (Near Future) ==
117
118 For future development the usage of SLF4J is highly encouraged instead of log4j. As of now all logging done through SLF4J will be automatically redirected to log4j so no configuration change or rewrite is needed by users making the transition seamless.
119
120 === Why SLF4J ===
121
122 The SLF4J framework has many advantages over log4j:
123
124 * //Freedom of choice// – the user can choose which logging framework to use instead of being fixed by Wonder's decision.
125 * //Performance// – there are many situations where logging is done faster and with smaller memory footprint
126 * //Code cleanliness// – the API of SLF4J makes it often possible to reduce the code needed for logging
127
128 Let's look at the last point and compare. You have a debug statement in log4j:
129
130 {{code language="java"}}
131 log.debug("The value of '" + key + "' is '" + value + "'");
132 {{/code}}
133
134 During the method call the compiler will create a StringBuilder to construct the param of the debug method and call the log4j method. That method then will check if the current logger is on the correct level and either output the log statemend or just return.
135 Now if you wanted to prevent the String concatenation to avoid the parameter construction cost if it is not really needed you would have to write:
136
137 {{code language="java"}}
138 if (log.isDebugEnabled()) {
139 log.debug("The value of '" + key + "' is '" + value + "'");
140 }
141 {{/code}}
142
143 With SLF4J there is a cleaner way, parameterized messages:
144
145 {{code language="java"}}
146 log.debug("The value of '{}' is '{}'", key, value);
147 {{/code}}
148
149 This defers the parameter construction until it is really needed. Of course if you include a computationally costly parameter you still should check your logging level beforehand:
150
151 {{code language="java"}}
152 if (log.isDebugEnabled()) {
153 log.debug("The value was: {}", computeExpensiveValue());
154 }
155 {{/code}}
156
157 ----
158
159 == Wonder Logging Libraries (Far Future) ==
160
161 The plan is to migrate all logging to use the SLF4J classes and afterwards to remove any SLF4J plugin from Wonder. That is Wonder won't be logging anything out of the box. If you use Wonder you will have to add the SLF4J plugin that //you// want to your project. By this you can control yourself if you want to log via log4j, commons logging, LOGBack or any other available framework.
162 Wonder could provide some optional logging framework that includes basic configuration and libraries for beginners to setup a simple log setup if they should not be wanting to take this step yet.