This file is indexed.

/usr/share/doc/liblogback-java/manual/migrationFromLog4j.html is in liblogback-java-doc 1:1.2.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
<!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 13: Migration from log4j</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 13: Migration from log4j</h1> 

    <a href="migrationFromLog4j_ja.html">&#x548C;&#x8A33; (Japanese translation)</a>

    <div class="quote">
      <p><em>The more things change, the more they remain the
      same. </em></p>
      
      <p>&mdash;ALPHONSE KARR, <em>Les Gu&ecirc;pes</em></p>
    </div>

    <p>This chapter deals with the topic of migrating custom log4j
    components such as appenders or layouts to logback-classic.
    </p>

    <p>Software which merely invokes log4j client API, that is the
    <code>Logger</code> or <code>Category</code> classes in
    <code>org.apache.log4j</code> package, can be automatically
    migrated to use SLF4J via the <a
    href="http://www.slf4j.org/migrator.html">SLF4J migrator
    tool</a>. To migrate <em>log4j.property</em> files into its
    logback equivalent, you can use the <a
    href="http://logback.qos.ch/translator/">log4j.properties
    translator</a>.
    </p>

    <p>From a broader perspective, log4j and logback-classic are
    closely related. The core components, such as loggers, appenders
    and layouts exist in both frameworks and serve identical
    purposes. Similarly, the most important internal data-structure,
    namely <code>LoggingEvent</code>, exists in both frameworks with
    rather similar but non-identical implementations. Most notably, in
    logback-classic <code>LoggingEvent</code> implements the
    <code>ILoggingEvent</code> interface. Most of the changes required
    in migrating log4j components to logback-classic are related to
    differences in implementation of the <code>LoggingEvent</code>
    class. Rest assured, these differences are rather limited. If in
    spite of your best efforts you are unable to migrate any given
    log4j component to logback-classic, do post a question on the <a
    href="../mailinglist.html">logback-dev mailing list</a>. A logback
    developer should be able to provide guidance.
    </p>

    
    <h3 class="doAnchor" name="log4jLayout">Migrating a log4j layout</h3>

    <p>Let us begin by migrating a hypothetical and trivially simple
    log4j layout named <a
    href="../xref/chapters/migrationFromLog4j/TrivialLog4jLayout.html">TrivialLog4jLayout</a>
    which returns the message contained in a logging events as the
    formatted message. Here is the code.
    </p>
    

    <pre class="prettyprint source">package chapters.migrationFromLog4j;

import org.apache.log4j.Layout;
import org.apache.log4j.spi.LoggingEvent;

public class TrivialLog4jLayout extends Layout {

  public void activateOptions() {
    // there are no options to activate
  }

  public String format(LoggingEvent loggingEvent) {
    return loggingEvent.getRenderedMessage();
  }

  public boolean ignoresThrowable() {
    return true;
  }
}</pre>

    <p>The logback-classic equivalent named <a
    href="../xref/chapters/migrationFromLog4j/TrivialLogbackLayout.html">TrivialLogbackLayout</a>
    would be </p>
    
    <pre class="prettyprint source">package chapters.migrationFromLog4j;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.LayoutBase;

public class TrivialLogbackLayout extends <b>LayoutBase&lt;ILoggingEvent></b> {

  public String <b>doLayout</b>(ILoggingEvent loggingEvent) {
    return loggingEvent.getMessage();
  }
}    </pre>
 
   <p>As you can see, in a logback-classic layout, the formatting
   method is named <code>doLayout</code> instead of
   <code>format</code>() in log4j. The <code>ignoresThrowable</code>()
   method is not needed and has no equivalent in logback-classic. Note
   that a logback-classic layout must extend the
   <code>LayoutBase&lt;ILoggingEvent></code> class.
   </p>

   <p>The <code>activateOptions</code>() method merits further
   discussion. In log4j, a layout will have its
   <code>activateOptions</code>() method invoked by log4j
   configurators, that is <code>PropertyConfigurator</code> or
   <code>DOMConfigurator</code> just after all the options of the
   layout have been set. Thus, the layout will have an opportunity to
   check that its options are coherent and if so, proceed to fully
   initialize itself.</p>


   <p>In logback-classic, layouts must implement the <a
   href="../xref/ch/qos/logback/core/spi/LifeCycle.html">LifeCycle</a>
   interface which includes a method called <code>start</code>(). The
   <code>start</code>() method is the equivalent of log4j's
   <code>activateOptions</code>() method.
   </p>

   <h3 class="doAnchor" name="log4jAppender">Migrating a log4j
   appender</h3>
   
   <p>Migrating an appender is quite similar to migrating a
   layout. Here is a trivially simple appender called <a
   href="../xref/chapters/migrationFromLog4j/TrivialLog4jAppender.html">TrivialLog4jAppender</a>
   which writes on the console the string returned by its layout.</p>
   
    <pre class="prettyprint source">package chapters.migrationFromLog4j;

import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.spi.LoggingEvent;


public class TrivialLog4jAppender extends AppenderSkeleton {

  protected void append(LoggingEvent loggingevent) {
    String s = this.layout.format(loggingevent);
    System.out.println(s);
  }

  public void close() {
    // nothing to do
  }

  public boolean requiresLayout() {
    return true;
  }
}</pre>

   <p>The logback-classic equivalent named <a
   href="../xref/chapters/migrationFromLog4j/TrivialLogbackAppender.html">TrivialLogbackAppender</a>
   would be written as</p>


   <pre class="prettyprint source">package chapters.migrationFromLog4j;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.AppenderBase;

public class TrivialLogbackAppender extends AppenderBase&lt;ILoggingEvent> {

  @Override
  public void start() {
    if (this.layout == null) {
      addError("No layout set for the appender named [" + name + "].");
      return;
    }
    super.start();
  }

  @Override
  protected void append(ILoggingEvent loggingevent) {
    // note that AppenderBase.doAppend will invoke this method only if
    // this appender was successfully started.
    
    String s = this.layout.doLayout(loggingevent);
    System.out.println(s);
  }
}</pre>


   <p>Comparing the two classes, you should notice that the contents
   of the <code>append</code>() method remains unchanged. The
   <code>requiresLayout</code> method is not used in logback and can
   be removed. In logback, the <code>stop</code>() method is the
   equivalent of log4j's <code>close</code>() method. However,
   <code>AppenderBase</code> in logback-classic, contains a nop
   implementation for <code>stop</code> which is sufficient for the
   purposes of this trivial appender.
   </p>



  <script src="../templates/footer.js" type="text/javascript"></script>
</div>
</body>
</html>