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.logging.log4j.simple;
18  
19  import java.io.PrintStream;
20  import java.text.DateFormat;
21  import java.text.SimpleDateFormat;
22  import java.util.Date;
23  import java.util.Map;
24  
25  import org.apache.logging.log4j.Level;
26  import org.apache.logging.log4j.Marker;
27  import org.apache.logging.log4j.ThreadContext;
28  import org.apache.logging.log4j.message.Message;
29  import org.apache.logging.log4j.message.MessageFactory;
30  import org.apache.logging.log4j.spi.AbstractLogger;
31  import org.apache.logging.log4j.util.PropertiesUtil;
32  import org.apache.logging.log4j.util.Strings;
33  
34  /**
35   * This is the default logger that is used when no suitable logging implementation is available.
36   */
37  public class SimpleLogger extends AbstractLogger {
38  
39      private static final long serialVersionUID = 1L;
40  
41      private static final char SPACE = ' ';
42  
43      /**
44       * Used to format times.
45       * <p>
46       * Note that DateFormat is not Thread-safe.
47       * </p>
48       */
49      private final DateFormat dateFormatter;
50  
51      private Level level;
52  
53      private final boolean showDateTime;
54  
55      private final boolean showContextMap;
56  
57      private PrintStream stream;
58  
59      private final String logName;
60  
61      public SimpleLogger(final String name, final Level defaultLevel, final boolean showLogName,
62              final boolean showShortLogName, final boolean showDateTime, final boolean showContextMap,
63              final String dateTimeFormat, final MessageFactory messageFactory, final PropertiesUtil props,
64              final PrintStream stream) {
65          super(name, messageFactory);
66          final String lvl = props.getStringProperty(SimpleLoggerContext.SYSTEM_PREFIX + name + ".level");
67          this.level = Level.toLevel(lvl, defaultLevel);
68          if (showShortLogName) {
69              final int index = name.lastIndexOf(".");
70              if (index > 0 && index < name.length()) {
71                  this.logName = name.substring(index + 1);
72              } else {
73                  this.logName = name;
74              }
75          } else if (showLogName) {
76              this.logName = name;
77          } else {
78              this.logName = null;
79          }
80          this.showDateTime = showDateTime;
81          this.showContextMap = showContextMap;
82          this.stream = stream;
83  
84          if (showDateTime) {
85              DateFormat format;
86              try {
87                  format = new SimpleDateFormat(dateTimeFormat);
88              } catch (final IllegalArgumentException e) {
89                  // If the format pattern is invalid - use the default format
90                  format = new SimpleDateFormat(SimpleLoggerContext.DEFAULT_DATE_TIME_FORMAT);
91              }
92              this.dateFormatter = format;
93          } else {
94              this.dateFormatter = null;
95          }
96      }
97  
98      @Override
99      public Level getLevel() {
100         return level;
101     }
102 
103     @Override
104     public boolean isEnabled(final Level testLevel, final Marker marker, final Message msg, final Throwable t) {
105         return this.level.intLevel() >= testLevel.intLevel();
106     }
107 
108     @Override
109     public boolean isEnabled(final Level testLevel, final Marker marker, final CharSequence msg, final Throwable t) {
110         return this.level.intLevel() >= testLevel.intLevel();
111     }
112 
113     @Override
114     public boolean isEnabled(final Level testLevel, final Marker marker, final Object msg, final Throwable t) {
115         return this.level.intLevel() >= testLevel.intLevel();
116     }
117 
118     @Override
119     public boolean isEnabled(final Level testLevel, final Marker marker, final String msg) {
120         return this.level.intLevel() >= testLevel.intLevel();
121     }
122 
123     @Override
124     public boolean isEnabled(final Level testLevel, final Marker marker, final String msg, final Object... p1) {
125         return this.level.intLevel() >= testLevel.intLevel();
126     }
127 
128     @Override
129     public boolean isEnabled(final Level testLevel, final Marker marker, final String message, final Object p0) {
130         return this.level.intLevel() >= testLevel.intLevel();
131     }
132 
133     @Override
134     public boolean isEnabled(final Level testLevel, final Marker marker, final String message, final Object p0,
135             final Object p1) {
136         return this.level.intLevel() >= testLevel.intLevel();
137     }
138 
139     @Override
140     public boolean isEnabled(final Level testLevel, final Marker marker, final String message, final Object p0,
141             final Object p1, final Object p2) {
142         return this.level.intLevel() >= testLevel.intLevel();
143     }
144 
145     @Override
146     public boolean isEnabled(final Level testLevel, final Marker marker, final String message, final Object p0,
147             final Object p1, final Object p2, final Object p3) {
148         return this.level.intLevel() >= testLevel.intLevel();
149     }
150 
151     @Override
152     public boolean isEnabled(final Level testLevel, final Marker marker, final String message, final Object p0,
153             final Object p1, final Object p2, final Object p3,
154             final Object p4) {
155         return this.level.intLevel() >= testLevel.intLevel();
156     }
157 
158     @Override
159     public boolean isEnabled(final Level testLevel, final Marker marker, final String message, final Object p0,
160             final Object p1, final Object p2, final Object p3,
161             final Object p4, final Object p5) {
162         return this.level.intLevel() >= testLevel.intLevel();
163     }
164 
165     @Override
166     public boolean isEnabled(final Level testLevel, final Marker marker, final String message, final Object p0,
167             final Object p1, final Object p2, final Object p3,
168             final Object p4, final Object p5, final Object p6) {
169         return this.level.intLevel() >= testLevel.intLevel();
170     }
171 
172     @Override
173     public boolean isEnabled(final Level testLevel, final Marker marker, final String message, final Object p0,
174             final Object p1, final Object p2, final Object p3,
175             final Object p4, final Object p5, final Object p6,
176             final Object p7) {
177         return this.level.intLevel() >= testLevel.intLevel();
178     }
179 
180     @Override
181     public boolean isEnabled(final Level testLevel, final Marker marker, final String message, final Object p0,
182             final Object p1, final Object p2, final Object p3,
183             final Object p4, final Object p5, final Object p6,
184             final Object p7, final Object p8) {
185         return this.level.intLevel() >= testLevel.intLevel();
186     }
187 
188     @Override
189     public boolean isEnabled(final Level testLevel, final Marker marker, final String message, final Object p0,
190             final Object p1, final Object p2, final Object p3,
191             final Object p4, final Object p5, final Object p6,
192             final Object p7, final Object p8, final Object p9) {
193         return this.level.intLevel() >= testLevel.intLevel();
194     }
195 
196     @Override
197     public boolean isEnabled(final Level testLevel, final Marker marker, final String msg, final Throwable t) {
198         return this.level.intLevel() >= testLevel.intLevel();
199     }
200 
201     @Override
202     public void logMessage(final String fqcn, final Level mgsLevel, final Marker marker, final Message msg,
203             final Throwable throwable) {
204         final StringBuilder sb = new StringBuilder();
205         // Append date-time if so configured
206         if (showDateTime) {
207             final Date now = new Date();
208             String dateText;
209             synchronized (dateFormatter) {
210                 dateText = dateFormatter.format(now);
211             }
212             sb.append(dateText);
213             sb.append(SPACE);
214         }
215 
216         sb.append(mgsLevel.toString());
217         sb.append(SPACE);
218         if (Strings.isNotEmpty(logName)) {
219             sb.append(logName);
220             sb.append(SPACE);
221         }
222         sb.append(msg.getFormattedMessage());
223         if (showContextMap) {
224             final Map<String, String> mdc = ThreadContext.getImmutableContext();
225             if (mdc.size() > 0) {
226                 sb.append(SPACE);
227                 sb.append(mdc.toString());
228                 sb.append(SPACE);
229             }
230         }
231         final Object[] params = msg.getParameters();
232         Throwable t;
233         if (throwable == null && params != null && params.length > 0
234                 && params[params.length - 1] instanceof Throwable) {
235             t = (Throwable) params[params.length - 1];
236         } else {
237             t = throwable;
238         }
239         stream.println(sb.toString());
240         if (t != null) {
241             stream.print(SPACE);
242             t.printStackTrace(stream);
243         }
244     }
245 
246     public void setLevel(final Level level) {
247         if (level != null) {
248             this.level = level;
249         }
250     }
251 
252     public void setStream(final PrintStream stream) {
253         this.stream = stream;
254     }
255 
256 }