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 */ 017package org.apache.logging.slf4j; 018 019import java.io.IOException; 020import java.io.ObjectInputStream; 021import java.io.ObjectOutputStream; 022import java.io.Serializable; 023 024import org.apache.logging.log4j.Level; 025import org.apache.logging.log4j.LogManager; 026import org.apache.logging.log4j.message.Message; 027import org.apache.logging.log4j.message.ParameterizedMessage; 028import org.apache.logging.log4j.message.SimpleMessage; 029import org.apache.logging.log4j.spi.ExtendedLogger; 030import org.apache.logging.log4j.util.LoaderUtil; 031import org.slf4j.Marker; 032import org.slf4j.MarkerFactory; 033import org.slf4j.spi.LocationAwareLogger; 034 035/** 036 * SLF4J logger implementation that uses Log4j. 037 */ 038public class Log4jLogger implements LocationAwareLogger, Serializable { 039 040 public static final String FQCN = Log4jLogger.class.getName(); 041 042 private static final long serialVersionUID = 7869000638091304316L; 043 private static final Marker EVENT_MARKER = MarkerFactory.getMarker("EVENT"); 044 private final boolean eventLogger; 045 private transient ExtendedLogger logger; 046 private final String name; 047 private transient EventDataConverter converter; 048 private transient Log4jMarkerFactory markerFactory; 049 050 public Log4jLogger(final Log4jMarkerFactory markerFactory, final ExtendedLogger logger, final String name) { 051 this.markerFactory = markerFactory; 052 this.logger = logger; 053 this.eventLogger = "EventLogger".equals(name); 054 this.name = name; 055 this.converter = createConverter(); 056 } 057 058 @Override 059 public void trace(final String format) { 060 logger.logIfEnabled(FQCN, Level.TRACE, null, format); 061 } 062 063 @Override 064 public void trace(final String format, final Object o) { 065 logger.logIfEnabled(FQCN, Level.TRACE, null, format, o); 066 } 067 068 @Override 069 public void trace(final String format, final Object arg1, final Object arg2) { 070 logger.logIfEnabled(FQCN, Level.TRACE, null, format, arg1, arg2); 071 } 072 073 @Override 074 public void trace(final String format, final Object... args) { 075 logger.logIfEnabled(FQCN, Level.TRACE, null, format, args); 076 } 077 078 @Override 079 public void trace(final String format, final Throwable t) { 080 logger.logIfEnabled(FQCN, Level.TRACE, null, format, t); 081 } 082 083 @Override 084 public boolean isTraceEnabled() { 085 return logger.isEnabled(Level.TRACE, null, null); 086 } 087 088 @Override 089 public boolean isTraceEnabled(final Marker marker) { 090 return logger.isEnabled(Level.TRACE, getMarker(marker), null); 091 } 092 093 @Override 094 public void trace(final Marker marker, final String s) { 095 logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s); 096 } 097 098 @Override 099 public void trace(final Marker marker, final String s, final Object o) { 100 logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, o); 101 } 102 103 @Override 104 public void trace(final Marker marker, final String s, final Object o, final Object o1) { 105 logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, o, o1); 106 } 107 108 @Override 109 public void trace(final Marker marker, final String s, final Object... objects) { 110 logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, objects); 111 } 112 113 @Override 114 public void trace(final Marker marker, final String s, final Throwable throwable) { 115 logger.logIfEnabled(FQCN, Level.TRACE, getMarker(marker), s, throwable); 116 } 117 118 @Override 119 public void debug(final String format) { 120 logger.logIfEnabled(FQCN, Level.DEBUG, null, format); 121 } 122 123 @Override 124 public void debug(final String format, final Object o) { 125 logger.logIfEnabled(FQCN, Level.DEBUG, null, format, o); 126 } 127 128 @Override 129 public void debug(final String format, final Object arg1, final Object arg2) { 130 logger.logIfEnabled(FQCN, Level.DEBUG, null, format, arg1, arg2); 131 } 132 133 @Override 134 public void debug(final String format, final Object... args) { 135 logger.logIfEnabled(FQCN, Level.DEBUG, null, format, args); 136 } 137 138 @Override 139 public void debug(final String format, final Throwable t) { 140 logger.logIfEnabled(FQCN, Level.DEBUG, null, format, t); 141 } 142 143 @Override 144 public boolean isDebugEnabled() { 145 return logger.isEnabled(Level.DEBUG, null, null); 146 } 147 148 @Override 149 public boolean isDebugEnabled(final Marker marker) { 150 return logger.isEnabled(Level.DEBUG, getMarker(marker), null); 151 } 152 153 @Override 154 public void debug(final Marker marker, final String s) { 155 logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s); 156 } 157 158 @Override 159 public void debug(final Marker marker, final String s, final Object o) { 160 logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, o); 161 } 162 163 @Override 164 public void debug(final Marker marker, final String s, final Object o, final Object o1) { 165 logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, o, o1); 166 } 167 168 @Override 169 public void debug(final Marker marker, final String s, final Object... objects) { 170 logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, objects); 171 } 172 173 @Override 174 public void debug(final Marker marker, final String s, final Throwable throwable) { 175 logger.logIfEnabled(FQCN, Level.DEBUG, getMarker(marker), s, throwable); 176 } 177 178 @Override 179 public void info(final String format) { 180 logger.logIfEnabled(FQCN, Level.INFO, null, format); 181 } 182 183 @Override 184 public void info(final String format, final Object o) { 185 logger.logIfEnabled(FQCN, Level.INFO, null, format, o); 186 } 187 188 @Override 189 public void info(final String format, final Object arg1, final Object arg2) { 190 logger.logIfEnabled(FQCN, Level.INFO, null, format, arg1, arg2); 191 } 192 193 @Override 194 public void info(final String format, final Object... args) { 195 logger.logIfEnabled(FQCN, Level.INFO, null, format, args); 196 } 197 198 @Override 199 public void info(final String format, final Throwable t) { 200 logger.logIfEnabled(FQCN, Level.INFO, null, format, t); 201 } 202 203 @Override 204 public boolean isInfoEnabled() { 205 return logger.isEnabled(Level.INFO, null, null); 206 } 207 208 @Override 209 public boolean isInfoEnabled(final Marker marker) { 210 return logger.isEnabled(Level.INFO, getMarker(marker), null); 211 } 212 213 @Override 214 public void info(final Marker marker, final String s) { 215 logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s); 216 } 217 218 @Override 219 public void info(final Marker marker, final String s, final Object o) { 220 logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, o); 221 } 222 223 @Override 224 public void info(final Marker marker, final String s, final Object o, final Object o1) { 225 logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, o, o1); 226 } 227 228 @Override 229 public void info(final Marker marker, final String s, final Object... objects) { 230 logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, objects); 231 } 232 233 @Override 234 public void info(final Marker marker, final String s, final Throwable throwable) { 235 logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, throwable); 236 } 237 238 @Override 239 public void warn(final String format) { 240 logger.logIfEnabled(FQCN, Level.WARN, null, format); 241 } 242 243 @Override 244 public void warn(final String format, final Object o) { 245 logger.logIfEnabled(FQCN, Level.WARN, null, format, o); 246 } 247 248 @Override 249 public void warn(final String format, final Object arg1, final Object arg2) { 250 logger.logIfEnabled(FQCN, Level.WARN, null, format, arg1, arg2); 251 } 252 253 @Override 254 public void warn(final String format, final Object... args) { 255 logger.logIfEnabled(FQCN, Level.WARN, null, format, args); 256 } 257 258 @Override 259 public void warn(final String format, final Throwable t) { 260 logger.logIfEnabled(FQCN, Level.WARN, null, format, t); 261 } 262 263 @Override 264 public boolean isWarnEnabled() { 265 return logger.isEnabled(Level.WARN, null, null); 266 } 267 268 @Override 269 public boolean isWarnEnabled(final Marker marker) { 270 return logger.isEnabled(Level.WARN, getMarker(marker), null); 271 } 272 273 @Override 274 public void warn(final Marker marker, final String s) { 275 logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s); 276 } 277 278 @Override 279 public void warn(final Marker marker, final String s, final Object o) { 280 logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, o); 281 } 282 283 @Override 284 public void warn(final Marker marker, final String s, final Object o, final Object o1) { 285 logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, o, o1); 286 } 287 288 @Override 289 public void warn(final Marker marker, final String s, final Object... objects) { 290 logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, objects); 291 } 292 293 @Override 294 public void warn(final Marker marker, final String s, final Throwable throwable) { 295 logger.logIfEnabled(FQCN, Level.WARN, getMarker(marker), s, throwable); 296 } 297 298 @Override 299 public void error(final String format) { 300 logger.logIfEnabled(FQCN, Level.ERROR, null, format); 301 } 302 303 @Override 304 public void error(final String format, final Object o) { 305 logger.logIfEnabled(FQCN, Level.ERROR, null, format, o); 306 } 307 308 @Override 309 public void error(final String format, final Object arg1, final Object arg2) { 310 logger.logIfEnabled(FQCN, Level.ERROR, null, format, arg1, arg2); 311 } 312 313 @Override 314 public void error(final String format, final Object... args) { 315 logger.logIfEnabled(FQCN, Level.ERROR, null, format, args); 316 } 317 318 @Override 319 public void error(final String format, final Throwable t) { 320 logger.logIfEnabled(FQCN, Level.ERROR, null, format, t); 321 } 322 323 @Override 324 public boolean isErrorEnabled() { 325 return logger.isEnabled(Level.ERROR, null, null); 326 } 327 328 @Override 329 public boolean isErrorEnabled(final Marker marker) { 330 return logger.isEnabled(Level.ERROR, getMarker(marker), null); 331 } 332 333 @Override 334 public void error(final Marker marker, final String s) { 335 logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s); 336 } 337 338 @Override 339 public void error(final Marker marker, final String s, final Object o) { 340 logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, o); 341 } 342 343 @Override 344 public void error(final Marker marker, final String s, final Object o, final Object o1) { 345 logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, o, o1); 346 } 347 348 @Override 349 public void error(final Marker marker, final String s, final Object... objects) { 350 logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, objects); 351 } 352 353 @Override 354 public void error(final Marker marker, final String s, final Throwable throwable) { 355 logger.logIfEnabled(FQCN, Level.ERROR, getMarker(marker), s, throwable); 356 } 357 358 @Override 359 public void log(final Marker marker, final String fqcn, final int level, final String message, final Object[] params, Throwable throwable) { 360 final Level log4jLevel = getLevel(level); 361 final org.apache.logging.log4j.Marker log4jMarker = getMarker(marker); 362 363 if (!logger.isEnabled(log4jLevel, log4jMarker, message, params)) { 364 return; 365 } 366 final Message msg; 367 if (eventLogger && marker != null && marker.contains(EVENT_MARKER) && converter != null) { 368 msg = converter.convertEvent(message, params, throwable); 369 } else if (params == null) { 370 msg = new SimpleMessage(message); 371 } else { 372 msg = new ParameterizedMessage(message, params, throwable); 373 if (throwable != null) { 374 throwable = msg.getThrowable(); 375 } 376 } 377 logger.logMessage(fqcn, log4jLevel, log4jMarker, msg, throwable); 378 } 379 380 private org.apache.logging.log4j.Marker getMarker(final Marker marker) { 381 if (marker == null) { 382 return null; 383 } else if (marker instanceof Log4jMarker) { 384 return ((Log4jMarker) marker).getLog4jMarker(); 385 } else { 386 return ((Log4jMarker) markerFactory.getMarker(marker)).getLog4jMarker(); 387 } 388 } 389 390 @Override 391 public String getName() { 392 return name; 393 } 394 395 /** 396 * Always treat de-serialization as a full-blown constructor, by validating the final state of 397 * the de-serialized object. 398 */ 399 private void readObject(final ObjectInputStream aInputStream) throws ClassNotFoundException, IOException { 400 // always perform the default de-serialization first 401 aInputStream.defaultReadObject(); 402 logger = LogManager.getContext().getLogger(name); 403 converter = createConverter(); 404 markerFactory = ((Log4jLoggerFactory) org.slf4j.LoggerFactory.getILoggerFactory()).getMarkerFactory(); 405 } 406 407 /** 408 * This is the default implementation of writeObject. Customise if necessary. 409 */ 410 private void writeObject(final ObjectOutputStream aOutputStream) throws IOException { 411 // perform the default serialization for all non-transient, non-static fields 412 aOutputStream.defaultWriteObject(); 413 } 414 415 private static EventDataConverter createConverter() { 416 try { 417 LoaderUtil.loadClass("org.slf4j.ext.EventData"); 418 return new EventDataConverter(); 419 } catch (final ClassNotFoundException cnfe) { 420 return null; 421 } 422 } 423 424 private static Level getLevel(final int i) { 425 switch (i) { 426 case TRACE_INT: 427 return Level.TRACE; 428 case DEBUG_INT: 429 return Level.DEBUG; 430 case INFO_INT: 431 return Level.INFO; 432 case WARN_INT: 433 return Level.WARN; 434 case ERROR_INT: 435 return Level.ERROR; 436 } 437 return Level.ERROR; 438 } 439}