Java tutorial
/* * $Id: CachingLogRegistry.java 545 2010-08-25 12:58:58Z kchristiansen $ * $Revision: 545 $ * $Date: 2010-08-25 14:58:58 +0200 (Wed, 25 Aug 2010) $ * $Author: kchristiansen $ * * The DOMS project. * Copyright (C) 2007-2010 The State and University Library * * 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 dk.statsbiblioteket.doms.domsutil.surveillance.logappender; import ch.qos.logback.classic.spi.ILoggingEvent; import dk.statsbiblioteket.doms.domsutil.surveyable.Status; import dk.statsbiblioteket.doms.domsutil.surveyable.StatusMessage; import dk.statsbiblioteket.sbutil.webservices.configuration.ConfigCollection; import dk.statsbiblioteket.util.qa.QAInfo; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.log4j.spi.LoggingEvent; import java.util.ArrayList; import java.util.Collection; import java.util.NavigableMap; import java.util.TreeMap; /** * A log survey that caches log messages for later inspection. * * Note that all methods in this class are synchronized. This may affect * performance if your logging level for what you register in the class is * too broad. */ @QAInfo(author = "kfc", reviewers = "jrg", comment = "Needs review on diff from revision 265", level = QAInfo.Level.NORMAL, state = QAInfo.State.QA_NEEDED) public class CachingLogRegistry implements LogRegistry { /** At most this many log messages are kept in the registry. */ private static int maxNumberOfMessagesKeptByLog = DEFAULT_MAX_NUMBER_OF_MESSAGES_KEPT_BY_LOG; /** Datastructure for remembered log messages. Maps from name to collection * of messages. The collections of messages are organised as a sorted map * from timestamp to message. */ private static final NavigableMap<Long, Collection<StatusMessage>> logStatusMessages = new TreeMap<Long, Collection<StatusMessage>>(); private static final Object lock = new Object(); private static boolean configured = false; /** The loggetr for this class. */ private static Log log = LogFactory.getLog(CachingLogRegistry.class); private static String name; /** Read paramters from configuration, and initialize caching log * registry. */ public CachingLogRegistry() { log.trace("Enter CachingLogEntry()"); configure(); } /** Read configuration. This method acts as fault barrier */ private void configure() { synchronized (lock) { log.trace("Enter configure()"); try { if (!configured) { String configValue = ConfigCollection.getProperties() .getProperty(NUMBEROFMESSAGES_CONFIGURATION_PARAMETER); if (configValue != null && !configValue.equals("")) { int configIntValue = Integer.parseInt(configValue); if (configIntValue != maxNumberOfMessagesKeptByLog) { maxNumberOfMessagesKeptByLog = configIntValue; log.info("Setting number of messages kept by registry to " + maxNumberOfMessagesKeptByLog); } } name = ConfigCollection.getProperties().getProperty(LOGGERNAME_CONFIGURATION_PARAMETER, "Unnamed"); configured = true; } } catch (Exception e) { log.warn("Error while configuring appender." + " Falling back to default values.", e); } } } /** * Register a message for later inspection. * * @param event The log message to register. Should never be null. * * @throws IllegalArgumentException if appender or event is null. */ public void registerMessage(LoggingEvent event) { synchronized (lock) { Collection<StatusMessage> collection; // Check parameters if (event == null) { throw new IllegalArgumentException("Parameter event must not be null"); } // Ensure the log doesn't grow too huge if (logStatusMessages.size() > maxNumberOfMessagesKeptByLog - 1) { long earliestTimeStamp = logStatusMessages.firstKey(); logStatusMessages.remove(earliestTimeStamp); } // Register it collection = logStatusMessages.get(event.getTimeStamp()); if (collection == null) { collection = new ArrayList<StatusMessage>(); logStatusMessages.put(event.getTimeStamp(), collection); } collection.add(new LogStatusMessage(event)); } } /** * Register a message for later inspection. * * @param event The log message to register. Should never be null. * * @throws IllegalArgumentException if appender or event is null. */ public synchronized void registerMessage(ILoggingEvent event) { synchronized (lock) { Collection<StatusMessage> collection; // Check parameters if (event == null) { throw new IllegalArgumentException("Parameter event must not be null"); } // Ensure the log doesn't grow too huge if (logStatusMessages.size() > maxNumberOfMessagesKeptByLog - 1) { long earliestTimeStamp = logStatusMessages.firstKey(); logStatusMessages.remove(earliestTimeStamp); } // Register it collection = logStatusMessages.get(event.getTimeStamp()); if (collection == null) { collection = new ArrayList<StatusMessage>(); logStatusMessages.put(event.getTimeStamp(), collection); } collection.add(new LogStatusMessage(event)); } } /** * Returns all log messages received since the given date. * * @param time Only messages strictly after the given date are returned. * @return A status containing list of log messages. */ public Status getStatusSince(long time) { synchronized (lock) { log.trace("Enter getStatusSince(" + time + ")"); Collection<Collection<StatusMessage>> listCollection = logStatusMessages .subMap(time, false, Long.MAX_VALUE, true).values(); Collection<StatusMessage> statusMessages = new ArrayList<StatusMessage>(); for (Collection<StatusMessage> collection : listCollection) { statusMessages.addAll(collection); } Status status = new Status(); status.setName(name); status.getMessages().addAll(statusMessages); return status; } } /** * Returns all log messages received. * * @return A status containing list of log messages. */ public Status getStatus() { synchronized (lock) { log.trace("Enter getStatus()"); return getStatusSince(0l); } } }