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.slf4j;
    18
    19  import java.util.ArrayList;
    20  import java.util.Collection;
    21  import java.util.Iterator;
    22  import java.util.concurrent.ConcurrentHashMap;
    23  import java.util.concurrent.ConcurrentMap;
    24
    25  import org.apache.logging.log4j.Logger;
    26  import org.apache.logging.log4j.MarkerManager;
    27  import org.apache.logging.log4j.status.StatusLogger;
    28  import org.slf4j.IMarkerFactory;
    29  import org.slf4j.Marker;
    30
    31  /**
    32   * Log4j/SLF4J bridge to create SLF4J Markers based on name or based on existing SLF4J Markers.
    33   */
    34  public class Log4jMarkerFactory implements IMarkerFactory {
    35
    36      private static final Logger LOGGER = StatusLogger.getLogger();
    37
    38      private final ConcurrentMap<String, Marker> markerMap = new ConcurrentHashMap<String, Marker>();
    39
    40      /**
    41       * Returns a Log4j Marker that is compatible with SLF4J.
    42       * @param name The name of the Marker.
    43       * @return A Marker.
    44       */
    45      @Override
    46      public Marker getMarker(final String name) {
    47          if (name == null) {
    48              throw new IllegalArgumentException("Marker name must not be null");
    49          }
    50          final Marker marker = markerMap.get(name);
    51          if (marker != null) {
    52              return marker;
    53          }
    54          final org.apache.logging.log4j.Marker log4jMarker = MarkerManager.getMarker(name);
    55          return addMarkerIfAbsent(name, log4jMarker);
    56      }
    57
    58      private Marker addMarkerIfAbsent(final String name, final org.apache.logging.log4j.Marker log4jMarker) {
    59          final Marker marker = new Log4jMarker(log4jMarker);
    60          final Marker existing = markerMap.putIfAbsent(name, marker);
    61          return existing == null ? marker : existing;
    62      }
    63
    64      /**
    65       * Returns a Log4j Marker converted from an existing custom SLF4J Marker.
    66       * @param marker The SLF4J Marker to convert.
    67       * @return A converted Log4j/SLF4J Marker.
    68       * @since 2.1
    69       */
    70      public Marker getMarker(final Marker marker) {
    71          if (marker == null) {
    72              throw new IllegalArgumentException("Marker must not be null");
    73          }
    74          final Marker m = markerMap.get(marker.getName());
    75          if (m != null) {
    76              return m;
    77          }
    78          return addMarkerIfAbsent(marker.getName(), convertMarker(marker));
    79      }
    80
    81      private static org.apache.logging.log4j.Marker convertMarker(final Marker original) {
    82          if (original == null) {
    83              throw new IllegalArgumentException("Marker must not be null");
    84          }
    85          return convertMarker(original, new ArrayList<Marker>());
    86      }
    87
    88      private static org.apache.logging.log4j.Marker convertMarker(final Marker original,
    89                                                                   final Collection<Marker> visited) {
    90          final org.apache.logging.log4j.Marker marker = MarkerManager.getMarker(original.getName());
    91          if (original.hasReferences()) {
    92              final Iterator it = original.iterator();
    93              while (it.hasNext()) {
    94                  final Marker next = (Marker) it.next();
    95                  if (visited.contains(next)) {
    96                      LOGGER.warn("Found a cycle in Marker [{}]. Cycle will be broken.", next.getName());
    97                  } else {
    98                      visited.add(next);
    99                      marker.addParents(convertMarker(next, visited));
    100                 }
    101             }
    102         }
    103         return marker;
    104     }
    105
    106     /**
    107      * Returns true if the Marker exists.
    108      * @param name The Marker name.
    109      * @return {@code true} if the Marker exists, {@code false} otherwise.
    110      */
    111     @Override
    112     public boolean exists(final String name) {
    113         return markerMap.containsKey(name);
    114     }
    115
    116     /**
    117      * Log4j does not support detached Markers. This method always returns false.
    118      * @param name The Marker name.
    119      * @return {@code false}
    120      */
    121     @Override
    122     public boolean detachMarker(final String name) {
    123         return false;
    124     }
    125
    126     /**
    127      * Log4j does not support detached Markers for performance reasons. The returned Marker is attached.
    128      * @param name The Marker name.
    129      * @return The named Marker (unmodified).
    130      */
    131     @Override
    132     public Marker getDetachedMarker(final String name) {
    133         LOGGER.warn("Log4j does not support detached Markers. Returned Marker [{}] will be unchanged.", name);
    134         return getMarker(name);
    135     }
    136
    137
    138 }