This file is indexed.

/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>&mdash;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&lt;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&lt;E> extends EncoderBase&lt;E> {

  protected Layout&lt;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">&lt;appender name="FILE" class="ch.qos.logback.core.FileAppender"> 
  &lt;file>foo.log&lt;/file>
  &lt;encoder>
    &lt;pattern>%d %-5level [%thread] %logger{0}: %msg%n&lt;/pattern>
    &lt;!-- this quadruples logging throughput --&gt;
    <b>&lt;immediateFlush>false&lt;/immediateFlush></b>
  &lt;/encoder> 
&lt;/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">&lt;appender name="FILE" class="ch.qos.logback.core.FileAppender"> 
  &lt;file>foo.log&lt;/file>
  &lt;encoder>
    &lt;pattern>%d %-5level [%thread] %logger{0}: %msg%n&lt;/pattern>
    <b>&lt;outputPatternAsHeader>true&lt;/outputPatternAsHeader></b>
  &lt;/encoder> 
&lt;/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>