blob: 894045eca43c8e9dc8e3461f42612bd33da621c7 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache license, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the license for the specific language governing permissions and
* limitations under the license.
*/
package org.apache.log4j.bridge;
import org.apache.log4j.Category;
import org.apache.log4j.Level;
import org.apache.log4j.spi.LocationInfo;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ThrowableInformation;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.util.Loader;
import org.apache.logging.log4j.core.util.Throwables;
import org.apache.logging.log4j.spi.StandardLevel;
import org.apache.logging.log4j.status.StatusLogger;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;
/**
* Converts a Log4j 2 LogEvent into the components needed by a Log4j 1.x LoggingEvent.
* This class requires Log4j 2.
*/
public class LogEventAdapter extends LoggingEvent {
private static final long JVM_START_TIME = initStartTime();
private final LogEvent event;
public LogEventAdapter(LogEvent event) {
this.event = event;
}
/**
* Returns the time when the application started, in milliseconds
* elapsed since 01.01.1970.
* @return the time when the JVM started.
*/
public static long getStartTime() {
return JVM_START_TIME;
}
/**
* Returns the result of {@code ManagementFactory.getRuntimeMXBean().getStartTime()},
* or the current system time if JMX is not available.
*/
private static long initStartTime() {
// We'd like to call ManagementFactory.getRuntimeMXBean().getStartTime(),
// but Google App Engine throws a java.lang.NoClassDefFoundError
// "java.lang.management.ManagementFactory is a restricted class".
// The reflection is necessary because without it, Google App Engine
// will refuse to initialize this class.
try {
final Class<?> factoryClass = Loader.loadSystemClass("java.lang.management.ManagementFactory");
final Method getRuntimeMXBean = factoryClass.getMethod("getRuntimeMXBean");
final Object runtimeMXBean = getRuntimeMXBean.invoke(null);
final Class<?> runtimeMXBeanClass = Loader.loadSystemClass("java.lang.management.RuntimeMXBean");
final Method getStartTime = runtimeMXBeanClass.getMethod("getStartTime");
return (Long) getStartTime.invoke(runtimeMXBean);
} catch (final Throwable t) {
StatusLogger.getLogger().error("Unable to call ManagementFactory.getRuntimeMXBean().getStartTime(), "
+ "using system time for OnStartupTriggeringPolicy", t);
// We have little option but to declare "now" as the beginning of time.
return System.currentTimeMillis();
}
}
public LogEvent getEvent() {
return this.event;
}
/**
* Set the location information for this logging event. The collected
* information is cached for future use.
*/
@Override
public LocationInfo getLocationInformation() {
return new LocationInfo(event.getSource());
}
/**
* Return the level of this event. Use this form instead of directly
* accessing the <code>level</code> field.
*/
@Override
public Level getLevel() {
switch (StandardLevel.getStandardLevel(event.getLevel().intLevel())) {
case TRACE:
return Level.TRACE;
case DEBUG:
return Level.DEBUG;
case INFO:
return Level.INFO;
case WARN:
return Level.WARN;
case FATAL:
return Level.FATAL;
case OFF:
return Level.OFF;
case ALL:
return Level.ALL;
default:
return Level.ERROR;
}
}
/**
* Return the name of the logger. Use this form instead of directly
* accessing the <code>categoryName</code> field.
*/
@Override
public String getLoggerName() {
return event.getLoggerName();
}
/**
* Gets the logger of the event.
*/
@Override
public Category getLogger() {
return Category.getInstance(event.getLoggerName());
}
/*
Return the message for this logging event.
*/
@Override
public Object getMessage() {
return event.getMessage();
}
/*
* This method returns the NDC for this event.
*/
@Override
public String getNDC() {
return event.getContextStack().toString();
}
/*
Returns the the context corresponding to the <code>key</code> parameter.
*/
@Override
public Object getMDC(String key) {
if (event.getContextData() != null) {
return event.getContextData().getValue(key);
} else {
return null;
}
}
/**
* Obtain a copy of this thread's MDC prior to serialization or
* asynchronous logging.
*/
@Override
public void getMDCCopy() {
}
@Override
public String getRenderedMessage() {
return event.getMessage().getFormattedMessage();
}
@Override
public String getThreadName() {
return event.getThreadName();
}
/**
* Returns the throwable information contained within this
* event. May be <code>null</code> if there is no such information.
*
* <p>Note that the {@link Throwable} object contained within a
* {@link ThrowableInformation} does not survive serialization.
*
* @since 1.1
*/
@Override
public ThrowableInformation getThrowableInformation() {
if (event.getThrown() != null) {
return new ThrowableInformation(event.getThrown());
}
return null;
}
/**
* Return this event's throwable's string[] representaion.
*/
@Override
public String[] getThrowableStrRep() {
if (event.getThrown() != null) {
return Throwables.toStringList(event.getThrown()).toArray(new String[0]);
}
return null;
}
@Override
public String getProperty(final String key) {
return event.getContextData().getValue(key);
}
@Override
public Set getPropertyKeySet() {
return event.getContextData().toMap().keySet();
}
@Override
public Map getProperties() {
return event.getContextData().toMap();
}
}