| /* |
| * 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(); |
| } |
| } |