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.log4j.jul; 018 019import java.util.Collections; 020import java.util.Enumeration; 021import java.util.logging.Logger; 022 023import org.apache.logging.log4j.LoggingException; 024import org.apache.logging.log4j.status.StatusLogger; 025import org.apache.logging.log4j.util.LoaderUtil; 026import org.apache.logging.log4j.util.PropertiesUtil; 027 028/** 029 * Log4j implementation of {@link java.util.logging.LogManager}. Note that the system property 030 * {@code java.util.logging.manager} must be set to {@code org.apache.logging.log4j.jul.LogManager} in order to use 031 * this adaptor. This LogManager requires the {@code log4j-api} library to be available. If {@code log4j-core} is 032 * also available, then more features of {@link java.util.logging.Logger} are supported. 033 * 034 * <p>To override the default {@link AbstractLoggerAdapter} that is used, specify the Log4j property 035 * {@code log4j.jul.LoggerAdapter} and set it to the fully qualified class name of a custom 036 * implementation. All implementations must have a default constructor.</p> 037 * 038 * @since 2.1 039 */ 040public class LogManager extends java.util.logging.LogManager { 041 042 private static final org.apache.logging.log4j.Logger LOGGER = StatusLogger.getLogger(); 043 private final AbstractLoggerAdapter loggerAdapter; 044 045 public LogManager() { 046 super(); 047 AbstractLoggerAdapter adapter = null; 048 final String overrideAdaptorClassName = 049 PropertiesUtil.getProperties().getStringProperty(Constants.LOGGER_ADAPTOR_PROPERTY); 050 if (overrideAdaptorClassName != null) { 051 try { 052 LOGGER.info("Trying to use LoggerAdaptor [{}] specified by Log4j property.", overrideAdaptorClassName); 053 adapter = LoaderUtil.newCheckedInstanceOf(overrideAdaptorClassName, AbstractLoggerAdapter.class); 054 } catch (final Exception e) { 055 LOGGER.error("Specified LoggerAdapter [{}] is incompatible.", overrideAdaptorClassName, e); 056 } 057 } 058 if (adapter == null) { 059 // default adapter 060 String adapterClassName; 061 try { 062 // find out if log4j-core is available 063 LoaderUtil.loadClass(Constants.CORE_LOGGER_CLASS_NAME); 064 adapterClassName = Constants.CORE_LOGGER_ADAPTER_CLASS_NAME; 065 } catch (final ClassNotFoundException ignored) { 066 adapterClassName = Constants.API_LOGGER_ADAPTER_CLASS_NAME; 067 } 068 LOGGER.debug("Attempting to use {}", adapterClassName); 069 try { 070 adapter = LoaderUtil.newCheckedInstanceOf(adapterClassName, AbstractLoggerAdapter.class); 071 } catch (final Exception e) { 072 throw LOGGER.throwing(new LoggingException(e)); 073 } 074 } 075 loggerAdapter = adapter; 076 LOGGER.info("Registered Log4j as the java.util.logging.LogManager."); 077 } 078 079 @Override 080 public boolean addLogger(final Logger logger) { 081 // in order to prevent non-bridged loggers from being registered, we always return false to indicate that 082 // the named logger should be obtained through getLogger(name) 083 return false; 084 } 085 086 @Override 087 public Logger getLogger(final String name) { 088 LOGGER.trace("Call to LogManager.getLogger({})", name); 089 return loggerAdapter.getLogger(name); 090 } 091 092 @Override 093 public Enumeration<String> getLoggerNames() { 094 return Collections.enumeration(loggerAdapter.getLoggersInContext(loggerAdapter.getContext()).keySet()); 095 } 096 097}