/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (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.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is OpenEMRConnect. * * The Initial Developer of the Original Code is International Training & * Education Center for Health (I-TECH) <http://www.go2itech.org/> * * Portions created by the Initial Developer are Copyright (C) 2011 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * ***** END LICENSE BLOCK ***** */ package ke.go.moh.oec.lib; import java.util.Date; import java.util.logging.Formatter; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.LogRecord; import ke.go.moh.oec.LogEntry; import ke.go.moh.oec.RequestTypeId; /** * Sends messages to the central logging server. This class extends * java.util.logging.Handler to provide a custom handler within OpenEMRConnect. * Any messages logged by an OEC application of levels INFO, WARNING and ERROR * will be sent to the OEC Logging Server. * * @author Jim Grace */ public class LoggingServiceHandler extends Handler { Mediator mediator; LoggingServiceHandler(Mediator mediator) { this.mediator = mediator; } /** * Publishes a LogRecord. * <p> * The logging request was made initially to a Logger object, which initialized the LogRecord and forwarded it here. * We send the record off to the Logging Server (if it is important enough.) * <p> * Programming note: we want to avoid recursion if anything is logged while we are sending * the log record to the Logging Server. In that case, we don't want to try * sending this message to the Logging Server also (stack overflow!) * To prevent recursion, we look at the stack to see if we are on it. * More precisely, we start from the third element of the stack -- because * the first element is always from the Thread.getStackTrace() method, and * the second elements is always from us, as the caller of Thread.getStackTrace(). * But if we appear again at a higher level of the stack trace, that means * that we have called ourselves recursively. If this happens we will not * try to send the message to the Logging Server. * * @param record description of the log event */ @Override public void publish(LogRecord record) { if (isLoggable(record) && record.getLevel().intValue() >= Level.INFO.intValue()) { StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); for (int i = 2; i < stackTrace.length; i++) { StackTraceElement e = stackTrace[i]; if (e.getClassName().equals(LoggingServiceHandler.class.getName())) { return; // Return doing nothing -- don't recurse sending a message that our own message sending failed! } } Formatter formatter = getFormatter(); String message = formatter.format(record); LogEntry le = new LogEntry(); le.setDateTime(new Date()); le.setSeverity(record.getLevel().getName()); le.setClassName(record.getSourceClassName()); le.setMessage(message); mediator.getData(RequestTypeId.LOG_ENTRY, le); } } /** * Flushes any buffered output. */ @Override public void flush() { // Nothing needs to be done here. } /** * Closes the Handler and free all associated resources. * * @throws SecurityException */ @Override public void close() throws SecurityException { // Nothing needs to be done here. } }