/usr/share/doc/liblogback-java/manual/encoders.html is in liblogback-java-doc 1:1.1.3-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>Chapter 5: Encoders</title>
<link rel="stylesheet" type="text/css" href="../css/common.css" />
<link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen" />
<link rel="stylesheet" type="text/css" href="../css/_print.css" media="print" />
<link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen" />
</head>
<body onload="prettyPrint(); decorate();">
<script type="text/javascript">prefix='../';</script>
<script type="text/javascript" src="../js/prettify.js"></script>
<script type="text/javascript" src="../templates/header.js" ></script>
<script type="text/javascript" src="../js/jquery-min.js"></script>
<script type="text/javascript" src="../js/decorator.js"></script>
<div id="left">
<noscript>Please turn on Javascript to view this menu</noscript>
<script src="../templates/left.js" type="text/javascript"></script>
</div>
<div id="right">
<script src="menu.js" type="text/javascript"></script>
</div>
<div id="content">
<h1>Chapter 5: Encoders</h1>
<div class="quote">
<p><b>ACTION THIS DAY</b> Make sure they have all they want on
extreme priority and report to me that this has been done.
</p>
<p>—CHURCHILL on October 1941 to General Hastings Ismay in
response to a request for more resources signed by Alan Turing
and his cryptanalyst colleagues at Bletchley Park</p>
</div>
<script src="../templates/creative.js" type="text/javascript"></script>
<script src="../templates/setup.js" type="text/javascript"></script>
<h2 class="doAnchor">What is an encoder</h2>
<p>Encoders are responsible for transforming an event into a byte
array as well as writing out that byte array into an
<code>OutputStream</code>. Encoders were introduced in logback
version 0.9.19. In previous versions, most appenders relied on a
layout to transform an event into a string and write it out using
a <code>java.io.Writer</code>. In previous versions of logback,
users would nest a <code>PatternLayout</code> within
<code>FileAppender</code>. Since logback 0.9.19,
<code>FileAppender</code> and sub-classes <a
href="../codes.html#layoutInsteadOfEncoder">expect an encoder and no
longer take a layout</a>.
</p>
<p>Why the breaking change?</p>
<p>Layouts, as discussed in detail in the next chapter, are only
able to transform an event into a String. Moreover, given that a
layout has no control over when events get written out, layouts
cannot aggregate events into batches. Contrast this with encoders
which not only have total control over the format of the bytes
written out, but also control when (and if) those bytes get written
out.
</p>
<p>At the present time, <code>PatternLayoutEncoder</code> is the
only really useful encoder. It merely wraps a
<code>PatternLayout</code> which does most of the work. Thus, it
may seem that encoders do not bring much to the table except
needless complexity. However, we hope that with the advent of new
and powerful encoders this impression will change.</p>
<h2 class="doAnchor" name="interface">Encoder interface</h2>
<p>Encoders are responsible for transforming an incoming event
into a byte array <b>and</b> writing out the resulting byte array
onto the appropriate <code>OutputStream</code>. Thus, encoders
have total control of what and when bytes gets written to the
<code>OutputStream</code> maintained by the owning appender. Here
is the <a
href="../xref/ch/qos/logback/core/encoder/Encoder.html">Encoder
interface:</a>
</p>
<pre class="prettyprint source">package ch.qos.logback.core.encoder;
public interface Encoder<E> extends ContextAware, LifeCycle {
/**
* This method is called when the owning appender starts or whenever output
* needs to be directed to a new OutputStream, for instance as a result of a
* rollover.
*/
void init(OutputStream os) throws IOException;
/**
* Encode and write an event to the appropriate {@link OutputStream}.
* Implementations are free to defer writing out of the encoded event and
* instead write in batches.
*/
void doEncode(E event) throws IOException;
/**
* This method is called prior to the closing of the underling
* {@link OutputStream}. Implementations MUST not close the underlying
* {@link OutputStream} which is the responsibility of the owning appender.
*/
void close() throws IOException;
}</pre>
<p>As you can see, the <code>Encoder</code> interface consists of
few methods, but surprisingly many useful things can be
accomplished with these methods.
</p>
<h2 class="doAnchor">LayoutWrappingEncoder</h2>
<p>Until logback version 0.9.19, many appenders relied on the
Layout instances to control the format of log output. As there
exists substantial amount of code based on the layout interface,
we needed a way for encoders to inter-operate with layouts. <a
href="../xref/ch/qos/logback/core/encoder/LayoutWrappingEncoder.html">LayoutWrappingEncoder</a>
bridges the gap between encoders and layouts. It implements the
encoder interface and wraps a layout to which it delegates the
work of transforming an event into string.
</p>
<p>Below is an excerpt from the <code>LayoutWrappingEncoder</code>
class illustrating how delegation to the wrapped layout instance
is done.</p>
<pre class="prettyprint source">package ch.qos.logback.core.encoder;
public class LayoutWrappingEncoder<E> extends EncoderBase<E> {
protected Layout<E> layout;
private Charset charset;
private boolean immediateFlush = true;
public void doEncode(E event) throws IOException {
String txt = layout.doLayout(event);
outputStream.write(convertToBytes(txt));
if (immediateFlush)
outputStream.flush();
}
private byte[] convertToBytes(String s) {
if (charset == null) {
return s.getBytes();
} else {
return s.getBytes(charset);
}
}
}</pre>
<p>The <code>doEncode</code>() method starts by having the wrapped
layout convert the incoming event into string. The resulting text
string is converted to bytes according to the charset encoding
chosen by the user. Those bytes are then written to the
<code>OutputStream</code> given by the owning appender. By
default, the <code>OutputStream</code> is immediately flushed,
unless the <span class="prop">immediateFlush</span> property is
explicitly set to 'false'. Setting the <span
class="prop">immediateFlush</span> property to false can
significantly improve logging throughput. See
<code>PatternLayoutEncoder</code> below for sample configuration..
</p>
<h2 class="doAnchor">PatternLayoutEncoder</h2>
<p>Given that <code>PatternLayout</code> is the most commonly used
layout, logback caters for this common use-case with
<code>PatternLayoutEncoder</code>, an extension of
<code>LayoutWrappingEncoder</code> restricted to wrapping
instances of <code>PatternLayout</code>.
</p>
<p>As of logback version 0.9.19, whenever a
<code>FileAppender</code> or one of its sub-classes was configured
with a <code>PatternLayout</code>, a
<code>PatternLayoutEncoder</code> must be used instead. This is
explained in the <a
href="../codes.html#layoutInsteadOfEncoder">relevant entry in the
logback error codes</a>.
</p>
<h4 class="doAnchor" name="immediateFlush"><span class="prop">immediateFlush</span> property</h4>
<p>As a sub-class of <a
href="../xref/ch/qos/logback/core/encoder/LayoutWrappingEncoder.html"><code>LayoutWrappingEncoder</code></a>,
<code>PatternLayoutEncoder</code> admits the <span
class="prop">immediateFlush</span> property. The default value
for <span class="prop">immediateFlush</span> is 'true'. Immediate
flushing of the output stream ensures that logging events are
immediately written to disk and will not be lost in case your
application exits without properly closing appenders. On the
other hand, setting this property to 'false' is likely to
quintuple (your mileage may vary) logging throughput. As
mentioned previously, if <span class="prop">immediateFlush</span>
is set to 'false' and if appenders are not closed properly when
your application exits, then logging events not yet written to
disk may be lost.
</p>
<p>Below is a sample configuration for a
<code>FileAppender</code> containing a
<code>PatternLayoutEncoder</code> with its <span
class="prop">immediateFlush</span> property set to 'false'.</p>
<pre class="prettyprint"><appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>foo.log</file>
<encoder>
<pattern>%d %-5level [%thread] %logger{0}: %msg%n</pattern>
<!-- this quadruples logging throughput -->
<b><immediateFlush>false</immediateFlush></b>
</encoder>
</appender></pre>
<h4 class="doAnchor" name="outputPatternAsHeader">Output pattern
string as header</h4>
<p>In order to facilitate parsing of log files, logback can insert
the pattern used for the log output at the top of log files. This
feature is <b>disabled</b> by default. It can be enabled by
setting the <span class="prop">outputPatternAsHeader</span>
property to 'true' for relevant
<code>PatternLayoutEncoder</code>. Here is an example:</p>
<pre class="prettyprint"><appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>foo.log</file>
<encoder>
<pattern>%d %-5level [%thread] %logger{0}: %msg%n</pattern>
<b><outputPatternAsHeader>true</outputPatternAsHeader></b>
</encoder>
</appender></pre>
<p>This will result output akin to the following in the log file:</p>
<pre>#logback.classic pattern: %d [%thread] %-5level %logger{36} - %msg%n
2012-04-26 14:54:38,461 [main] DEBUG com.foo.App - Hello world
2012-04-26 14:54:38,461 [main] DEBUG com.foo.App - Hi again
...</pre>
<p>The line starting with "#logback.classic pattern" is newly
inserted pattern line.</p>
<script src="../templates/footer.js" type="text/javascript"></script>
</div>
</body>
</html>
|