/* ESXX - The friendly ECMAscript/XML Application Server Copyright (C) 2007-2015 Martin Blom <martin@blom.org> This program is free software: you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.esxx.util; import java.util.logging.*; public class SyslogHandler extends Handler { public static synchronized void setDefaultIdent(String syslog_ident) { defaultSyslogIdent = syslog_ident; } public static synchronized void setDefaultFacility(int facility) { defaultFacility = facility; } public static synchronized Logger createLogger(String logger_name, Level logger_level ) { return createLogger(logger_name, logger_level, null, -1); } /** A static utility method that returns a Logger for the given * name. If no handlers are configured for this logger, it is set * up with a SyslogHandler and a ConsoleHandler, both using the * TrivialFormatter (however, the console handler will include * the log level on each line, while the syslog handler will * not). * * @param logger_name The name of the java.util.logging logger * @param Level The Logger level * @param syslog_ident The 'ident' string (program name) used for Syslog. * May be null. * @param facility The Syslog facility. May be -1. */ public static synchronized Logger createLogger(String logger_name, Level logger_level, String syslog_ident, int facility) { Logger logger = Logger.getLogger(logger_name); if (logger.getHandlers().length == 0) { try { // No specific log handler configured in // jre/lib/logging.properties -- log everything to both // syslog and console using the TrivialFormatter. ConsoleHandler ch = new ConsoleHandler(); ch.setLevel(Level.ALL); ch.setFormatter(getTrivialFormatter(true)); logger.addHandler(new SyslogHandler(syslog_ident, facility)); logger.addHandler(ch); logger.setUseParentHandlers(false); logger.setLevel(logger_level); } catch (Throwable ex) { // Probably a Google App Engine problem } } return logger; } private static synchronized Formatter getTrivialFormatter(boolean include_level) { int idx = include_level ? 0 : 1; if (trivialFormatters == null) { trivialFormatters = new Formatter[2]; } if (trivialFormatters[idx] == null) { trivialFormatters[idx] = new TrivialFormatter(include_level); } return trivialFormatters[idx]; } private static Formatter[] trivialFormatters; public SyslogHandler() { this(null, Syslog.LOG_DAEMON); } public SyslogHandler(String ident, int facility) { try { syslog = new Syslog(ident != null ? ident : defaultSyslogIdent, 0, facility != -1 ? facility : defaultFacility); } catch (Syslog.SyslogException ex) { throw new UnsupportedOperationException(ex); } } @Override public synchronized void publish(LogRecord record) { if (!isLoggable(record)) { return; } Formatter formatter = getFormatter(); if (formatter == null) { formatter = getTrivialFormatter(false); setFormatter(formatter); } String message; try { message = formatter.format(record); } catch (Exception ex) { reportError(null, ex, ErrorManager.FORMAT_FAILURE); return; } // Convert Java priority level to Syslog level int priority = record.getLevel().intValue(); if (priority >= Level.SEVERE.intValue()) { priority = Syslog.LOG_ERR; } else if (priority >= Level.WARNING.intValue()) { priority = Syslog.LOG_WARNING; } else if (priority >= Level.INFO.intValue()) { priority = Syslog.LOG_NOTICE; } else if (priority >= Level.CONFIG.intValue()) { priority = Syslog.LOG_INFO; } else { priority = Syslog.LOG_DEBUG; } try { if (syslog != null) { syslog.syslog(priority, message); } } catch (Exception ex) { reportError(null, ex, ErrorManager.WRITE_FAILURE); } } @Override public boolean isLoggable(LogRecord record) { if (syslog == null) { return false; } return super.isLoggable(record); } @Override public void flush() { // Nothing to do } @Override public void close() { syslog = null; } private Syslog syslog; private static String defaultSyslogIdent = "java"; private static int defaultFacility = Syslog.LOG_DAEMON; }