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