All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.coos.plugin.logback.impl.COOSAppenderBase Maven / Gradle / Ivy

There is a newer version: 1.3.1
Show newest version
/**
 * COOS - Connected Objects Operating System (www.connectedobjects.org).
 *
 * Copyright (C) 2009 Telenor ASA and Tellu AS. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This library 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 .
 *
 * You may also contact one of the following for additional information:
 * Telenor ASA, Snaroyveien 30, N-1331 Fornebu, Norway (www.telenor.no)
 * Tellu AS, Hagalokkveien 13, N-1383 Asker, Norway (www.tellu.no)
 */
package org.coos.plugin.logback.impl;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import org.coos.plugin.logagent.impl.LogAgentEndpoint;

import ch.qos.logback.core.AppenderBase;
import ch.qos.logback.core.boolex.EvaluationException;
import ch.qos.logback.core.boolex.EventEvaluator;
import ch.qos.logback.core.spi.PreSerializationTransformer;

/**
 * Base class for CoosAppender implementations.
 * 
 * @author Robert Bjærum, Tellu AS
 * 
 */
public abstract class COOSAppenderBase extends AppenderBase {

	/**
	 * The default end-point URI to which of the remote logging server (coos://logServer)
	 */
	static final String DEFAULT_LOGSERVER_URI = "coos://logServer";

	/**
	 * The default reconnection delay (30000 milliseconds or 30 seconds).
	 */
	static final int DEFAULT_RECONNECTION_DELAY = 30000;

	protected EventEvaluator eventEvaluator;


	private String logServerUri = DEFAULT_LOGSERVER_URI;
	private int reconnectionDelay = DEFAULT_RECONNECTION_DELAY;
	private boolean enabled = true;

	private Connector connector;
	private volatile LogAgentEndpoint endpoint = null;

	/* Sequence number counting logging events sent through this appender. */
	private int eventSeq;

	public COOSAppenderBase() {
		this.logServerUri = DEFAULT_LOGSERVER_URI;
	}

	/**
	 * The EventEvaluator option takes a string value representing the name of the class
	 * implementing the {@link EventEvaluators} interface. A corresponding object will be
	 * instantiated and assigned as the event evaluator for the COOSAppender.
	 */
	public void setEvaluator(EventEvaluator eventEvaluator) {
		this.eventEvaluator = eventEvaluator;
	}

	/**
	 * Returns the value of the LogServerUri option.
	 * 
	 * @return
	 */
	public String getLogServerUri() {
		return logServerUri;
	}

	/**
	 * The LogServerUri option takes a string representing the COOS address URI of the COOS
	 * Log Server to receive log messages.
	 * 
	 * @param logServerUri
	 *            the log server URI (default: coos://logServer)
	 * @throws IllegalArgumentException
	 *             if null or empty
	 */
	public void setLogServerUri(String logServerUri) {
		if (logServerUri == null || logServerUri.isEmpty()) {
			throw new IllegalArgumentException("Property logServerUri cannot be null or empty");
		}
		this.logServerUri = logServerUri;
	}

	/**
	 * The ReconnectionDelay option takes a positive integer representing the number of
	 * milliseconds to wait between each failed connection attempt to the server. The default value
	 * of this option is 30000 which corresponds to 30 seconds.
	 * 
	 * 

* Setting this option to zero turns off reconnection capability. */ public void setReconnectionDelay(int delay) { this.reconnectionDelay = delay; } /** * Returns value of the ReconnectionDelay option. */ public int getReconnectionDelay() { return reconnectionDelay; } public boolean isEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } /** * Start the appender. The method isStarted() will return true if errors did not occur. It may * still not be connected, since the Connector may be active. */ @Override public void start() { if (!enabled || isStarted()) { return; } if (this.eventEvaluator == null) { addError("No EventEvaluator is set for appender [" + name + "]."); return; } this.started = true; fireConnector(); } /** * Stop this appender. */ @Override public void stop() { if (!isStarted()) { return; } cleanUp(); this.started = false; } /** * Drop the endpoint-connection and release the underlying connector thread if it exists. */ public void cleanUp() { endpoint = null; if (connector != null) { addInfo("Interrupting the connector."); connector.interrupted = true; try { connector.join(); } catch (InterruptedException ignore) { } connector = null; } } /** * Return true if the appender is connected to a COOS node through a Plugin. * * @return true if connected */ public boolean isConnected() { return (isStarted() && endpoint != null && endpoint.getPlugin().isConnected()); } @Override protected void append(E event) { if (event == null || !isConnected()) { return; } try { if (eventEvaluator.evaluate(event)) { postProcessEvent(event); Serializable serEvent = getPST().transform(event); ByteArrayOutputStream bos = new ByteArrayOutputStream(); // Serialize ObjectOutputStream out = new ObjectOutputStream(bos); out.writeObject(serEvent); out.close(); eventSeq = endpoint.sendLoggingEvent(logServerUri, bos.toByteArray()); } } catch (EvaluationException ex) { addError("COOSAppender's EventEvaluator threw an Exception" + ex); } catch (IOException ex) { ex.printStackTrace(); } } protected abstract void postProcessEvent(E event); protected abstract PreSerializationTransformer getPST(); /* * Sends the events in buffer */ protected void sendBuffer() { } /* * Used by unit tests */ protected void waitForConnector(long timeout) throws InterruptedException { if (connector == null) { return; } connector.join(timeout); } public int getEventSeq() { return eventSeq; } private void fireConnector() { cleanUp(); addInfo("Starting a new connector thread."); connector = new Connector(); connector.setDaemon(true); connector.setPriority(Thread.MIN_PRIORITY); connector.start(); } /** * The Connector will connect to the default COOS instance when it becomes available and is * started. It does this by attempting to open a new connection every * reconnectionDelay milliseconds. */ private class Connector extends Thread { boolean interrupted = false; public void run() { while (!interrupted) { try { LogAgentEndpoint ep = LogAgentEndpoint.getLastInstance(); addInfo("Attempting connection to LogAgentEndpoint " + ep); if (ep != null && ep.getPlugin().isConnected()) { addInfo("Connection established. Exiting connector thread."); endpoint = ep; connector = null; break; } /* * Arrive here if connection failed. If retries are disabled, turn of started * flag. */ if (reconnectionDelay <= 0) { addWarn("Could not connect and reconnection is disabled as reconnectionDelay is zero or negative"); started = false; break; } sleep(reconnectionDelay); } catch (InterruptedException e) { addInfo("Connector interrupted. Leaving loop."); e.printStackTrace(); break; } catch (Exception e) { addInfo("Unidentified Exception caught. Exception is " + e); } } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy