/* * Lilith - a log event viewer. * Copyright (C) 2007-2017 Joern Huxhorn * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /* * Copyright 2007-2017 Joern Huxhorn * * Licensed 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 de.huxhorn.lilith.log4j.producer; import de.huxhorn.lilith.data.converter.Converter; import de.huxhorn.lilith.data.eventsource.LoggerContext; import de.huxhorn.lilith.data.logging.ExtendedStackTraceElement; import de.huxhorn.lilith.data.logging.LoggingEvent; import de.huxhorn.lilith.data.logging.Message; import de.huxhorn.lilith.data.logging.ThreadInfo; import de.huxhorn.lilith.data.logging.ThrowableInfoParser; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import org.apache.log4j.spi.LocationInfo; import org.apache.log4j.spi.ThrowableInformation; public class Log4jLoggingConverter implements Converter<LoggingEvent> { public static final String LOG4J_LEVEL_KEY="log4j.level"; public static final String LOG4J_LEVEL_VALUE_FATAL = "FATAL"; private static final String APPLICATION_MDC_KEY = "application"; public LoggingEvent convert(Object o) { if(o == null) { return null; } if(!(o instanceof org.apache.log4j.spi.LoggingEvent)) { throw new IllegalArgumentException(""+o+" is not a "+getSourceClass()+"!"); } org.apache.log4j.spi.LoggingEvent log4jEvent = (org.apache.log4j.spi.LoggingEvent) o; LoggingEvent result=new LoggingEvent(); Map<String, String> mdc=new HashMap<>(); // loggerName result.setLogger(log4jEvent.getLoggerName()); // level { org.apache.log4j.Level log4jLevel = log4jEvent.getLevel(); if(log4jLevel.equals(org.apache.log4j.Level.TRACE)) { result.setLevel(LoggingEvent.Level.TRACE); } else if(log4jLevel.equals(org.apache.log4j.Level.DEBUG)) { result.setLevel(LoggingEvent.Level.DEBUG); } else if(log4jLevel.equals(org.apache.log4j.Level.INFO)) { result.setLevel(LoggingEvent.Level.INFO); } else if(log4jLevel.equals(org.apache.log4j.Level.WARN)) { result.setLevel(LoggingEvent.Level.WARN); } else if(log4jLevel.equals(org.apache.log4j.Level.ERROR)) { result.setLevel(LoggingEvent.Level.ERROR); } else if(log4jLevel.equals(org.apache.log4j.Level.FATAL)) { mdc.put(LOG4J_LEVEL_KEY, LOG4J_LEVEL_VALUE_FATAL); result.setLevel(LoggingEvent.Level.ERROR); } } // timeStamp result.setTimeStamp(log4jEvent.getTimeStamp()); // Message { String msg = log4jEvent.getRenderedMessage(); if(msg != null) { result.setMessage(new Message(msg)); } } // threadInfo { String threadName=log4jEvent.getThreadName(); if(threadName != null) { ThreadInfo threadInfo=new ThreadInfo(); threadInfo.setName(threadName); result.setThreadInfo(threadInfo); } } // MDC { Map props = log4jEvent.getProperties(); if(props != null) { for(Object currentObj : props.entrySet()) { Map.Entry current= (Map.Entry) currentObj; String keyStr=null; String valueStr=null; Object key=current.getKey(); Object value=current.getValue(); if(key != null) { keyStr=key.toString(); // use safe toString } if(value != null) { valueStr=value.toString(); // use safe toString } if(keyStr != null && valueStr != null) { mdc.put(keyStr, valueStr); } } } } if(mdc.size()>0) { result.setMdc(mdc); } // application / contextName if(mdc.containsKey(APPLICATION_MDC_KEY)) { LoggerContext context=new LoggerContext(); context.setName(mdc.get(APPLICATION_MDC_KEY)); result.setLoggerContext(context); } // NDC { String ndc=log4jEvent.getNDC(); if("".equals(ndc)) { ndc = null; } if(ndc != null) { // TODO: tokenize? result.setNdc(new Message[]{new Message(ndc)}); } } // location information { LocationInfo location = log4jEvent.getLocationInformation(); if(location != null) { ExtendedStackTraceElement ste = new ExtendedStackTraceElement(); // LOG4J_MODULE // ste.setClassLoaderName(location.getClassLoaderName()); // ste.setModuleName(location.getModuleName()); // ste.setModuleVersion(location.getModuleVersion()); ste.setClassName(location.getClassName()); ste.setMethodName(location.getMethodName()); ste.setFileName(location.getFileName()); String line = location.getLineNumber(); if(line != null) { try { ste.setLineNumber(Integer.parseInt(line)); } catch(NumberFormatException ex) { // ignore } } result.setCallStack(new ExtendedStackTraceElement[]{ste}); } } // throwable information { // TODO: log4jEvent.getThrowableInformation(); ThrowableInformation ti = log4jEvent.getThrowableInformation(); if(ti != null) { String[] throwableStrRep = ti.getThrowableStrRep(); if(throwableStrRep != null && throwableStrRep.length>0) { result.setThrowable(ThrowableInfoParser.parse(Arrays.asList(throwableStrRep))); } } } return result; } public Class getSourceClass() { return org.apache.log4j.spi.LoggingEvent.class; } }