001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.commons.logging.impl;
019
020 import java.io.Serializable;
021 import java.util.logging.Level;
022 import java.util.logging.Logger;
023 import java.util.logging.LogRecord;
024 import java.util.StringTokenizer;
025 import java.io.PrintWriter;
026 import java.io.StringWriter;
027
028 import org.apache.commons.logging.Log;
029
030 /**
031 * Implementation of the <code>org.apache.commons.logging.Log</code>
032 * interface that wraps the standard JDK logging mechanisms that are
033 * available in SourceForge's Lumberjack for JDKs prior to 1.4.
034 *
035 * @version $Id: Jdk13LumberjackLogger.html 862526 2013-05-20 17:07:42Z tn $
036 * @since 1.1
037 */
038 public class Jdk13LumberjackLogger implements Log, Serializable {
039
040 /** Serializable version identifier. */
041 private static final long serialVersionUID = -8649807923527610591L;
042
043 // ----------------------------------------------------- Instance Variables
044
045 /**
046 * The underlying Logger implementation we are using.
047 */
048 protected transient Logger logger = null;
049 protected String name = null;
050 private String sourceClassName = "unknown";
051 private String sourceMethodName = "unknown";
052 private boolean classAndMethodFound = false;
053
054 /**
055 * This member variable simply ensures that any attempt to initialise
056 * this class in a pre-1.4 JVM will result in an ExceptionInInitializerError.
057 * It must not be private, as an optimising compiler could detect that it
058 * is not used and optimise it away.
059 */
060 protected static final Level dummyLevel = Level.FINE;
061
062 // ----------------------------------------------------------- Constructors
063
064 /**
065 * Construct a named instance of this Logger.
066 *
067 * @param name Name of the logger to be constructed
068 */
069 public Jdk13LumberjackLogger(String name) {
070 this.name = name;
071 logger = getLogger();
072 }
073
074 // --------------------------------------------------------- Public Methods
075
076 private void log( Level level, String msg, Throwable ex ) {
077 if( getLogger().isLoggable(level) ) {
078 LogRecord record = new LogRecord(level, msg);
079 if( !classAndMethodFound ) {
080 getClassAndMethod();
081 }
082 record.setSourceClassName(sourceClassName);
083 record.setSourceMethodName(sourceMethodName);
084 if( ex != null ) {
085 record.setThrown(ex);
086 }
087 getLogger().log(record);
088 }
089 }
090
091 /**
092 * Gets the class and method by looking at the stack trace for the
093 * first entry that is not this class.
094 */
095 private void getClassAndMethod() {
096 try {
097 Throwable throwable = new Throwable();
098 throwable.fillInStackTrace();
099 StringWriter stringWriter = new StringWriter();
100 PrintWriter printWriter = new PrintWriter( stringWriter );
101 throwable.printStackTrace( printWriter );
102 String traceString = stringWriter.getBuffer().toString();
103 StringTokenizer tokenizer =
104 new StringTokenizer( traceString, "\n" );
105 tokenizer.nextToken();
106 String line = tokenizer.nextToken();
107 while ( line.indexOf( this.getClass().getName() ) == -1 ) {
108 line = tokenizer.nextToken();
109 }
110 while ( line.indexOf( this.getClass().getName() ) >= 0 ) {
111 line = tokenizer.nextToken();
112 }
113 int start = line.indexOf( "at " ) + 3;
114 int end = line.indexOf( '(' );
115 String temp = line.substring( start, end );
116 int lastPeriod = temp.lastIndexOf( '.' );
117 sourceClassName = temp.substring( 0, lastPeriod );
118 sourceMethodName = temp.substring( lastPeriod + 1 );
119 } catch ( Exception ex ) {
120 // ignore - leave class and methodname unknown
121 }
122 classAndMethodFound = true;
123 }
124
125 /**
126 * Logs a message with <code>java.util.logging.Level.FINE</code>.
127 *
128 * @param message to log
129 * @see org.apache.commons.logging.Log#debug(Object)
130 */
131 public void debug(Object message) {
132 log(Level.FINE, String.valueOf(message), null);
133 }
134
135 /**
136 * Logs a message with <code>java.util.logging.Level.FINE</code>.
137 *
138 * @param message to log
139 * @param exception log this cause
140 * @see org.apache.commons.logging.Log#debug(Object, Throwable)
141 */
142 public void debug(Object message, Throwable exception) {
143 log(Level.FINE, String.valueOf(message), exception);
144 }
145
146 /**
147 * Logs a message with <code>java.util.logging.Level.SEVERE</code>.
148 *
149 * @param message to log
150 * @see org.apache.commons.logging.Log#error(Object)
151 */
152 public void error(Object message) {
153 log(Level.SEVERE, String.valueOf(message), null);
154 }
155
156 /**
157 * Logs a message with <code>java.util.logging.Level.SEVERE</code>.
158 *
159 * @param message to log
160 * @param exception log this cause
161 * @see org.apache.commons.logging.Log#error(Object, Throwable)
162 */
163 public void error(Object message, Throwable exception) {
164 log(Level.SEVERE, String.valueOf(message), exception);
165 }
166
167 /**
168 * Logs a message with <code>java.util.logging.Level.SEVERE</code>.
169 *
170 * @param message to log
171 * @see org.apache.commons.logging.Log#fatal(Object)
172 */
173 public void fatal(Object message) {
174 log(Level.SEVERE, String.valueOf(message), null);
175 }
176
177 /**
178 * Logs a message with <code>java.util.logging.Level.SEVERE</code>.
179 *
180 * @param message to log
181 * @param exception log this cause
182 * @see org.apache.commons.logging.Log#fatal(Object, Throwable)
183 */
184 public void fatal(Object message, Throwable exception) {
185 log(Level.SEVERE, String.valueOf(message), exception);
186 }
187
188 /**
189 * Return the native Logger instance we are using.
190 */
191 public Logger getLogger() {
192 if (logger == null) {
193 logger = Logger.getLogger(name);
194 }
195 return logger;
196 }
197
198 /**
199 * Logs a message with <code>java.util.logging.Level.INFO</code>.
200 *
201 * @param message to log
202 * @see org.apache.commons.logging.Log#info(Object)
203 */
204 public void info(Object message) {
205 log(Level.INFO, String.valueOf(message), null);
206 }
207
208 /**
209 * Logs a message with <code>java.util.logging.Level.INFO</code>.
210 *
211 * @param message to log
212 * @param exception log this cause
213 * @see org.apache.commons.logging.Log#info(Object, Throwable)
214 */
215 public void info(Object message, Throwable exception) {
216 log(Level.INFO, String.valueOf(message), exception);
217 }
218
219 /**
220 * Is debug logging currently enabled?
221 */
222 public boolean isDebugEnabled() {
223 return getLogger().isLoggable(Level.FINE);
224 }
225
226 /**
227 * Is error logging currently enabled?
228 */
229 public boolean isErrorEnabled() {
230 return getLogger().isLoggable(Level.SEVERE);
231 }
232
233 /**
234 * Is fatal logging currently enabled?
235 */
236 public boolean isFatalEnabled() {
237 return getLogger().isLoggable(Level.SEVERE);
238 }
239
240 /**
241 * Is info logging currently enabled?
242 */
243 public boolean isInfoEnabled() {
244 return getLogger().isLoggable(Level.INFO);
245 }
246
247 /**
248 * Is trace logging currently enabled?
249 */
250 public boolean isTraceEnabled() {
251 return getLogger().isLoggable(Level.FINEST);
252 }
253
254 /**
255 * Is warn logging currently enabled?
256 */
257 public boolean isWarnEnabled() {
258 return getLogger().isLoggable(Level.WARNING);
259 }
260
261 /**
262 * Logs a message with <code>java.util.logging.Level.FINEST</code>.
263 *
264 * @param message to log
265 * @see org.apache.commons.logging.Log#trace(Object)
266 */
267 public void trace(Object message) {
268 log(Level.FINEST, String.valueOf(message), null);
269 }
270
271 /**
272 * Logs a message with <code>java.util.logging.Level.FINEST</code>.
273 *
274 * @param message to log
275 * @param exception log this cause
276 * @see org.apache.commons.logging.Log#trace(Object, Throwable)
277 */
278 public void trace(Object message, Throwable exception) {
279 log(Level.FINEST, String.valueOf(message), exception);
280 }
281
282 /**
283 * Logs a message with <code>java.util.logging.Level.WARNING</code>.
284 *
285 * @param message to log
286 * @see org.apache.commons.logging.Log#warn(Object)
287 */
288 public void warn(Object message) {
289 log(Level.WARNING, String.valueOf(message), null);
290 }
291
292 /**
293 * Logs a message with <code>java.util.logging.Level.WARNING</code>.
294 *
295 * @param message to log
296 * @param exception log this cause
297 * @see org.apache.commons.logging.Log#warn(Object, Throwable)
298 */
299 public void warn(Object message, Throwable exception) {
300 log(Level.WARNING, String.valueOf(message), exception);
301 }
302 }