/** * Licensed to JumpMind Inc under one or more contributor * license agreements. See the NOTICE file distributed * with this work for additional information regarding * copyright ownership. JumpMind Inc licenses this file * to you under the GNU General Public License, version 3.0 (GPLv3) * (the "License"); you may not use this file except in compliance * with the License. * * You should have received a copy of the GNU General Public License, * version 3.0 (GPLv3) along with this library; if not, see * <http://www.gnu.org/licenses/>. * * 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.jumpmind.util; import static org.apache.commons.lang.StringUtils.isNotBlank; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.apache.log4j.AppenderSkeleton; import org.apache.log4j.Level; import org.apache.log4j.spi.LoggingEvent; public class LogSummaryAppender extends AppenderSkeleton { Map<String, Map<String, LogSummary>> errorsByEngineByMessage = new ConcurrentHashMap<String, Map<String, LogSummary>>(); Map<String, Map<String, LogSummary>> warningByEngineByMessage = new ConcurrentHashMap<String, Map<String, LogSummary>>(); @Override protected void append(LoggingEvent event) { Map<String, Map<String, LogSummary>> summaries = null; if (event.getLevel() == Level.ERROR) { summaries = errorsByEngineByMessage; } else if (event.getLevel() == Level.WARN) { summaries = warningByEngineByMessage; } if (summaries != null) { String engineName = (String) event.getMDC("engineName"); if (isNotBlank(engineName)) { Map<String, LogSummary> byMessage = summaries.get(engineName); if (byMessage == null) { byMessage = new ConcurrentHashMap<String, LogSummary>(); summaries.put(engineName, byMessage); } String message = (String) event.getMessage(); if (message == null) { message = "No Message"; } LogSummary summary = byMessage.get(message); if (summary == null) { summary = new LogSummary(); summary.setMessage(message); summary.setFirstOccurranceTime(event.getTimeStamp()); byMessage.put(message, summary); } summary.setLevel(event.getLevel()); summary.setMostRecentTime(event.getTimeStamp()); summary.setCount(summary.getCount() + 1); summary.setThrowable(event.getThrowableInformation() != null ? event .getThrowableInformation().getThrowable() : null); summary.setMostRecentThreadName(event.getThreadName()); } } } public void close() { } @Override public boolean requiresLayout() { return false; } public List<LogSummary> getLogSummaries(String engineName, Level level) { Map<String, Map<String, LogSummary>> summaries = null; if (level == Level.ERROR) { summaries = errorsByEngineByMessage; } else if (level == Level.WARN) { summaries = warningByEngineByMessage; } List<LogSummary> list = new ArrayList<LogSummary>(); if (summaries != null && summaries.get(engineName) != null) { list.addAll(summaries.get(engineName).values()); Collections.sort(list, new Comparator<LogSummary>() { @Override public int compare(LogSummary o1, LogSummary o2) { return new Long(o1.getMostRecentTime()).compareTo(o2.getMostRecentTime()); } }); } return list; } public void clearAll(String engineName) { errorsByEngineByMessage.remove(engineName); warningByEngineByMessage.remove(engineName); } public void purgeOlderThan(long time) { purgeOlderThan(time, errorsByEngineByMessage); purgeOlderThan(time, warningByEngineByMessage); } protected void purgeOlderThan(long time, Map<String, Map<String, LogSummary>> logSummaryByEngineByMessage) { Collection<Map<String, LogSummary>> all = logSummaryByEngineByMessage.values(); for (Map<String, LogSummary> map : all) { Set<String> keys = map.keySet(); for (String key : keys) { LogSummary summary = map.get(key); if (summary != null) { if (summary.getMostRecentTime() < time) { map.remove(key); } } } } } }