View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.log4j.spi;
18  
19  import org.apache.log4j.ULogger;
20  import org.apache.log4j.helpers.MessageFormatter;
21  
22  
23  /**
24   * A simple implementation that logs messages of level INFO or higher on
25   * the console (<code>System.out</code>).
26   * <p>
27   * The output includes the relative time in milliseconds, thread name, level,
28   * logger name, and the message followed by the line separator for the host.
29   * In log4j terms it amounts to the "%r  [%t] %level %logger - %m%n" pattern.
30   * <pre>
31   * 176 [main] INFO examples.Sort - Populating an array of 2 elements in reverse.
32   * 225 [main] INFO examples.SortAlgo - Entered the sort method.
33   * 304 [main] INFO SortAlgo.DUMP - Dump of interger array:
34   * 317 [main] INFO SortAlgo.DUMP - Element [0] = 0
35   * 331 [main] INFO SortAlgo.DUMP - Element [1] = 1
36   * 343 [main] INFO examples.Sort - The next log statement should be an error msg.
37   * 346 [main] ERROR SortAlgo.DUMP - Tried to dump an uninitialized array.
38   * at org.log4j.examples.SortAlgo.dump(SortAlgo.java:58)
39   * at org.log4j.examples.Sort.main(Sort.java:64)
40   * 467 [main] INFO  examples.Sort - Exiting main method.
41   * </pre>
42   *
43   * @author Ceki G&uuml;lc&uuml;
44   */
45  public final class SimpleULogger implements ULogger {
46  
47      /**
48       * Logger name.
49       */
50      private final String loggerName;
51  
52  
53      /**
54       * Mark the time when this class gets loaded into memory.
55       */
56      private static long startTime = System.currentTimeMillis();
57  
58      /**
59       * Line separator.
60       */
61      public static final String LINE_SEPARATOR
62          = System.getProperty("line.separator");
63  
64      /**
65       * INFO string literal.
66       */
67      private static final String INFO_STR = "INFO";
68      /**
69       * WARN string literal.
70       */
71      private static final String WARN_STR = "WARN";
72      /**
73       * ERROR string literal.
74       */
75      private static final String ERROR_STR = "ERROR";
76  
77      /**
78       * Constructor is private to force construction through getLogger.
79       *
80       * @param name logger name
81       */
82      private SimpleULogger(final String name) {
83          super();
84          this.loggerName = name;
85      }
86  
87      /**
88       * Creates a new instance.
89       *
90       * @param name logger name
91       * @return logger.
92       */
93      public static SimpleULogger getLogger(final String name) {
94          return new SimpleULogger(name);
95      }
96  
97      /**
98       * {@inheritDoc}
99       */
100     public boolean isDebugEnabled() {
101         return false;
102     }
103 
104     /**
105      * {@inheritDoc}
106      */
107     public void debug(final Object msg) {
108         // NOP
109     }
110 
111     /**
112      * {@inheritDoc}
113      */
114     public void debug(final Object parameterizedMsg, final Object param1) {
115         // NOP
116     }
117 
118     /**
119      * {@inheritDoc}
120      */
121     public void debug(final String parameterizedMsg,
122                       final Object param1,
123                       final Object param2) {
124         // NOP
125     }
126 
127     /**
128      * {@inheritDoc}
129      */
130     public void debug(final Object msg, final Throwable t) {
131         // NOP
132     }
133 
134     /**
135      * This is our internal implementation for logging regular (non-parameterized)
136      * log messages.
137      *
138      * @param level   level
139      * @param message message
140      * @param t       throwable
141      */
142     private void log(final String level,
143                      final String message,
144                      final Throwable t) {
145         StringBuilder buf = new StringBuilder();
146 
147         long millis = System.currentTimeMillis();
148         buf.append(millis - startTime);
149 
150         buf.append(" [");
151         buf.append(Thread.currentThread().getName());
152         buf.append("] ");
153 
154         buf.append(level);
155         buf.append(" ");
156 
157         buf.append(loggerName);
158         buf.append(" - ");
159 
160         buf.append(message);
161 
162         buf.append(LINE_SEPARATOR);
163 
164         System.out.print(buf.toString());
165         if (t != null) {
166             t.printStackTrace(System.out);
167         }
168         System.out.flush();
169     }
170 
171     /**
172      * For parameterized messages, first substitute parameters and then log.
173      *
174      * @param level            level
175      * @param parameterizedMsg message pattern
176      * @param param1           param1
177      * @param param2           param2
178      */
179     private void parameterizedLog(final String level,
180                                   final Object parameterizedMsg,
181                                   final Object param1,
182                                   final Object param2) {
183         if (parameterizedMsg instanceof String) {
184             String msgStr = (String) parameterizedMsg;
185             msgStr = MessageFormatter.format(msgStr, param1, param2);
186             log(level, msgStr, null);
187         } else {
188             // To be failsafe, we handle the case where 'messagePattern' is not
189             // a String. Unless the user makes a mistake, this should not happen.
190             log(level, parameterizedMsg.toString(), null);
191         }
192     }
193 
194     /**
195      * {@inheritDoc}
196      */
197     public boolean isInfoEnabled() {
198         return true;
199     }
200 
201     /**
202      * {@inheritDoc}
203      */
204     public void info(final Object msg) {
205         log(INFO_STR, msg.toString(), null);
206     }
207 
208 
209     /**
210      * {@inheritDoc}
211      */
212     public void info(final Object parameterizedMsg, final Object param1) {
213         parameterizedLog(INFO_STR, parameterizedMsg, param1, null);
214     }
215 
216     /**
217      * {@inheritDoc}
218      */
219     public void info(final String parameterizedMsg,
220                      final Object param1,
221                      final Object param2) {
222         parameterizedLog(INFO_STR, parameterizedMsg, param1, param2);
223     }
224 
225     /**
226      * {@inheritDoc}
227      */
228     public void info(final Object msg, final Throwable t) {
229         log(INFO_STR, msg.toString(), t);
230     }
231 
232     /**
233      * {@inheritDoc}
234      */
235     public boolean isWarnEnabled() {
236         return true;
237     }
238 
239     /**
240      * {@inheritDoc}
241      */
242     public void warn(final Object msg) {
243         log(WARN_STR, msg.toString(), null);
244     }
245 
246     /**
247      * {@inheritDoc}
248      */
249     public void warn(final Object parameterizedMsg, final Object param1) {
250         parameterizedLog(WARN_STR, parameterizedMsg, param1, null);
251     }
252 
253     /**
254      * {@inheritDoc}
255      */
256     public void warn(final String parameterizedMsg,
257                      final Object param1,
258                      final Object param2) {
259         parameterizedLog(WARN_STR, parameterizedMsg, param1, param2);
260     }
261 
262     /**
263      * {@inheritDoc}
264      */
265     public void warn(final Object msg, final Throwable t) {
266         log(WARN_STR, msg.toString(), t);
267     }
268 
269     /**
270      * {@inheritDoc}
271      */
272     public boolean isErrorEnabled() {
273         return true;
274     }
275 
276     /**
277      * {@inheritDoc}
278      */
279     public void error(final Object msg) {
280         log(ERROR_STR, msg.toString(), null);
281     }
282 
283 
284     /**
285      * {@inheritDoc}
286      */
287     public void error(final Object parameterizedMsg, final Object param1) {
288         parameterizedLog(ERROR_STR, parameterizedMsg, param1, null);
289     }
290 
291     /**
292      * {@inheritDoc}
293      */
294     public void error(final String parameterizedMsg,
295                       final Object param1,
296                       final Object param2) {
297         parameterizedLog(ERROR_STR, parameterizedMsg, param1, param2);
298     }
299 
300     /**
301      * {@inheritDoc}
302      */
303     public void error(final Object msg, final Throwable t) {
304         log(ERROR_STR, msg.toString(), t);
305     }
306 
307 }