/***********************************************************************************
*
* Copyright (c) 2014 Kamil Baczkowicz
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* The Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
*
* Kamil Baczkowicz - initial API and implementation and/or initial documentation
*
*/
package pl.baczkowicz.mqttspy.logger;
import java.util.Queue;
import org.apache.log4j.Logger;
import org.apache.log4j.RollingFileAppender;
import pl.baczkowicz.mqttspy.common.generated.MessageLog;
import pl.baczkowicz.mqttspy.messages.FormattedMqttMessage;
import pl.baczkowicz.mqttspy.utils.Utils;
import pl.baczkowicz.spy.utils.ThreadingUtils;
/**
* This class is responsible for handling logging messages.
*/
public class MqttMessageLogger implements Runnable
{
/** Message log logger. */
private final static Logger logger = Logger.getLogger(MqttMessageLogger.class);
/** If X messages logged without a break, log this. */
private final static int LOG_INTERVAL = 10000;
/** Message log logger. */
private Logger localLogger;
/** Received messages that are to be logged. */
private final Queue<FormattedMqttMessage> queue;
/** Message log settings. */
private final MessageLog messageLogSettings;
/** Flag indicating whether the logger is/should be running. */
private boolean running;
private int sleepWhenNoMessages;
/**
* Creates a MqttMessageLogger.
*
* @param connectionId Connection ID
* @param queue The message queue to be used
* @param connectionSettings The connection details
*/
public MqttMessageLogger(
final String connectionId, final Queue<FormattedMqttMessage> queue,
final MessageLog messageLogSettings,
final boolean useAsTemplate, final int sleepWhenNoMessages)
{
this.queue = queue;
this.messageLogSettings = messageLogSettings;
this.sleepWhenNoMessages = sleepWhenNoMessages;
final String file = messageLogSettings.getLogFile();
if (file != null)
{
RollingFileAppender appender;
if (useAsTemplate)
{
final RollingFileAppender templateAppender = (RollingFileAppender) logger.getAppender("messagelog");
appender = new RollingFileAppender();
appender.setThreshold(templateAppender.getThreshold());
appender.setMaximumFileSize(templateAppender.getMaximumFileSize());
appender.setMaxBackupIndex(templateAppender.getMaxBackupIndex());
appender.setLayout(templateAppender.getLayout());
appender.setFile(file);
appender.activateOptions();
localLogger = Logger.getLogger("pl.baczkowicz.mqttspy.logger.ConnectionSpecificLogger" + connectionId);
localLogger.addAppender(appender);
localLogger.setAdditivity(false);
}
else
{
appender = (RollingFileAppender) logger.getAppender("messagelog");
appender.setFile(file);
}
}
}
public void run()
{
ThreadingUtils.logThreadStarting("Message Audit Logger");
running = true;
while (running)
{
try
{
int mesagesProcessed = 0;
while (queue.size() > 0)
{
mesagesProcessed++;
if (localLogger != null)
{
localLogger.info(SimpleMqttMessageLogComposer.createReceivedMessageLog(queue.remove(), messageLogSettings));
}
else
{
logger.info(SimpleMqttMessageLogComposer.createReceivedMessageLog(queue.remove(), messageLogSettings));
}
if (mesagesProcessed > LOG_INTERVAL)
{
Utils.logger.warn("Logged " + LOG_INTERVAL + " messages; logger not keeping up; queue size = " + queue.size());
mesagesProcessed = 0;
}
}
// When no messages present, sleep a bit
Thread.sleep(sleepWhenNoMessages);
}
catch (InterruptedException e)
{
// Not expected
}
}
ThreadingUtils.logThreadEnding();
}
/**
* Returns the number of message awaiting processing.
*
* @return The number of messages waiting to be logged
*/
public int getMessagesToProcess()
{
return queue.size();
}
/**
* The running state.
*
* @return True if the logger is running
*/
public boolean isRunning()
{
return running;
}
/**
* Stops the logger.
*/
public void stop()
{
running = false;
}
public Queue<FormattedMqttMessage> getQueue()
{
return queue;
}
}