org.apache.log4j.bridge.LogEventWrapper Maven / Gradle / Ivy
/*
* 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 java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import org.apache.log4j.NDC;
import org.apache.log4j.helpers.OptionConverter;
import org.apache.log4j.spi.LocationInfo;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ThrowableInformation;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.impl.ThrowableProxy;
import org.apache.logging.log4j.core.time.Instant;
import org.apache.logging.log4j.core.time.MutableInstant;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.SimpleMessage;
import org.apache.logging.log4j.spi.MutableThreadContextStack;
import org.apache.logging.log4j.util.BiConsumer;
import org.apache.logging.log4j.util.ReadOnlyStringMap;
import org.apache.logging.log4j.util.TriConsumer;
/**
* Exposes a Log4j 1 logging event as a Log4j 2 LogEvent.
*/
public class LogEventWrapper implements LogEvent {
private final LoggingEvent event;
private final ContextDataMap contextData;
private final MutableThreadContextStack contextStack;
private Thread thread;
public LogEventWrapper(LoggingEvent event) {
this.event = event;
this.contextData = new ContextDataMap(event.getProperties());
this.contextStack = new MutableThreadContextStack(NDC.cloneStack());
this.thread = Objects.equals(event.getThreadName(), Thread.currentThread().getName())
? Thread.currentThread() : null;
}
@Override
public LogEvent toImmutable() {
return this;
}
@Override
public Map getContextMap() {
return contextData;
}
@Override
public ReadOnlyStringMap getContextData() {
return contextData;
}
@Override
public ThreadContext.ContextStack getContextStack() {
return contextStack;
}
@Override
public String getLoggerFqcn() {
return null;
}
@Override
public Level getLevel() {
return OptionConverter.convertLevel(event.getLevel());
}
@Override
public String getLoggerName() {
return event.getLoggerName();
}
@Override
public Marker getMarker() {
return null;
}
@Override
public Message getMessage() {
return new SimpleMessage(event.getRenderedMessage());
}
@Override
public long getTimeMillis() {
return event.getTimeStamp();
}
@Override
public Instant getInstant() {
MutableInstant mutable = new MutableInstant();
mutable.initFromEpochMilli(event.getTimeStamp(), 0);
return mutable;
}
@Override
public StackTraceElement getSource() {
LocationInfo info = event.getLocationInformation();
return new StackTraceElement(info.getClassName(), info.getMethodName(), info.getFileName(),
Integer.parseInt(info.getLineNumber()));
}
@Override
public String getThreadName() {
return event.getThreadName();
}
@Override
public long getThreadId() {
Thread thread = getThread();
return thread != null ? thread.getId() : 0;
}
@Override
public int getThreadPriority() {
Thread thread = getThread();
return thread != null ? thread.getPriority() : 0;
}
private Thread getThread() {
if (thread == null && event.getThreadName() != null) {
for (Thread thread : Thread.getAllStackTraces().keySet()) {
if (thread.getName().equals(event.getThreadName())) {
this.thread = thread;
return thread;
}
}
}
return thread;
}
@Override
public Throwable getThrown() {
ThrowableInformation throwableInformation = event.getThrowableInformation();
return throwableInformation == null ? null : throwableInformation.getThrowable();
}
@Override
public ThrowableProxy getThrownProxy() {
return null;
}
@Override
public boolean isEndOfBatch() {
return false;
}
@Override
public boolean isIncludeLocation() {
return false;
}
@Override
public void setEndOfBatch(boolean endOfBatch) {
}
@Override
public void setIncludeLocation(boolean locationRequired) {
}
@Override
public long getNanoTime() {
return 0;
}
private static class ContextDataMap extends HashMap implements ReadOnlyStringMap {
ContextDataMap(Map map) {
if (map != null) {
super.putAll(map);
}
}
@Override
public Map toMap() {
return this;
}
@Override
public boolean containsKey(String key) {
return super.containsKey(key);
}
@Override
public void forEach(BiConsumer action) {
super.forEach((k,v) -> action.accept(k, (V) v));
}
@Override
public void forEach(TriConsumer action, S state) {
super.forEach((k,v) -> action.accept(k, (V) v, state));
}
@Override
public V getValue(String key) {
return (V) super.get(key);
}
}
}