From a8dfeba434f7eb993653209f2df999a75841b077 Mon Sep 17 00:00:00 2001 From: Johannes Beck Date: Sun, 13 May 2012 17:49:05 +0200 Subject: [PATCH] Initial add: syslog module for JBoss AS 7 --- modules/x1/jboss-syslog/main/module.xml | 9 + pom.xml | 97 +++++++++ .../java/x1/jboss/syslog/BooleanLatch.java | 60 ++++++ src/main/java/x1/jboss/syslog/Syslog.java | 113 ++++++++++ .../java/x1/jboss/syslog/SyslogHandler.java | 197 ++++++++++++++++++ src/test/java/x1/jboss/syslog/SysLogTest.java | 61 ++++++ 6 files changed, 537 insertions(+) create mode 100644 modules/x1/jboss-syslog/main/module.xml create mode 100644 pom.xml create mode 100644 src/main/java/x1/jboss/syslog/BooleanLatch.java create mode 100644 src/main/java/x1/jboss/syslog/Syslog.java create mode 100644 src/main/java/x1/jboss/syslog/SyslogHandler.java create mode 100644 src/test/java/x1/jboss/syslog/SysLogTest.java diff --git a/modules/x1/jboss-syslog/main/module.xml b/modules/x1/jboss-syslog/main/module.xml new file mode 100644 index 0000000..edb0273 --- /dev/null +++ b/modules/x1/jboss-syslog/main/module.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..0ca0b77 --- /dev/null +++ b/pom.xml @@ -0,0 +1,97 @@ + + 4.0.0 + x1.jboss + x1.jboss-syslog + 1.0.0-SNAPSHOT + jboss-syslog + Syslog appender for JBoss AS 7 + http://maven.x1/site/x1/jboss-syslog + 2012 + + scm:svn:http://www.x1/repos/x1/trunk/x1/jboss-syslog + https://www.x1/cgi-bin/viewvc.cgi/x1/trunk/x1/jboss-syslog + + + + GNU General Public License, version 2, with the Classpath Exception + + + + UTF-8 + + + Hudson + http://apollo.x1:9080/job/jboss-syslog/ + + + mail + true + true + true + true + +
root@www.x1
+
+
+
+
+ + + jboss-syslog.x1.website + X1 Website + scp://joe@www.x1/var/maven/site/x1/jboss-syslog + + + x1-repo + X1 Maven Repository + http://www.x1/nexus/content/repositories/x1-repo + + + x1-snapshot-repo + X1 Maven Snapshot Repository + http://www.x1/nexus/content/repositories/x1-snapshot-repo + + + + X1 + https://www.x1 + + + + joe + Johannes Beck + mail@johannes-beck.name + http://johannes-beck.name + X1 + https://www.x1 + + Developer + + +1 + + johannesbeck + + + + + + + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + + + + + + + junit + junit + 4.10 + test + + +
\ No newline at end of file diff --git a/src/main/java/x1/jboss/syslog/BooleanLatch.java b/src/main/java/x1/jboss/syslog/BooleanLatch.java new file mode 100644 index 0000000..71d7d33 --- /dev/null +++ b/src/main/java/x1/jboss/syslog/BooleanLatch.java @@ -0,0 +1,60 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * The contents of this file are subject to the terms of the GNU + * General Public License Version 2 only ("GPL"). + * You may not use this file except in compliance with the License. You can + * obtain a copy of the License at http://www.gnu.org/licenses/gpl-2.0.html + * See the License for the specific language governing permissions and + * limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * This particular file is designated as subject to the "Classpath" + * exception. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright (c) 2009-2010 Oracle and/or its affiliates. + * + * 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 x1.jboss.syslog; + +import java.util.concurrent.locks.AbstractQueuedSynchronizer; + +/** + * Acts like a CountDownLatch except that it only requires a single signal to + * fire. Because a latch is non-exclusive, it uses the shared acquire and + * release methods. + * + * @author Jerome Dochez + */ +public class BooleanLatch extends AbstractQueuedSynchronizer { + private static final long serialVersionUID = -2380570517815530977L; + + public boolean isSignalled() { + return getState() != 0; + } + + public int tryAcquireShared(int ignore) { + return isSignalled() ? 1 : -1; + } + + public boolean tryReleaseShared(int ignore) { + setState(1); + return true; + } +} \ No newline at end of file diff --git a/src/main/java/x1/jboss/syslog/Syslog.java b/src/main/java/x1/jboss/syslog/Syslog.java new file mode 100644 index 0000000..73542e2 --- /dev/null +++ b/src/main/java/x1/jboss/syslog/Syslog.java @@ -0,0 +1,113 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * The contents of this file are subject to the terms of the GNU + * General Public License Version 2 only ("GPL"). + * You may not use this file except in compliance with the License. You can + * obtain a copy of the License at http://www.gnu.org/licenses/gpl-2.0.html + * See the License for the specific language governing permissions and + * limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * This particular file is designated as subject to the "Classpath" + * exception. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright (c) 2009-2010 Oracle and/or its affiliates. + * + * 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 x1.jboss.syslog; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.UnknownHostException; + +import java.util.logging.Logger; +import java.util.logging.Level; + +/** + * Send a message via syslog. + * + * this code is taken from spy.jar and enhanced User: cmott + */ +public class Syslog { + public static final int EMERG = 0; + public static final int ALERT = 1; + public static final int CRIT = 2; + public static final int ERR = 3; + public static final int WARNING = 4; + public static final int NOTICE = 5; + public static final int INFO = 6; + public static final int DEBUG = 7; + + public static final int KERN = 0; + public static final int USER = 8; + public static final int MAIL = 16; + public static final int DAEMON = 24; + public static final int AUTH = 32; + public static final int SYSLOG = 40; + public static final int LPR = 48; + public static final int NEWS = 56; + public static final int UUCP = 64; + public static final int CRON = 72; + public static final int AUTHPRIV = 80; + public static final int FTP = 88; + public static final int LOCAL0 = 128; + public static final int LOCAL1 = 136; + public static final int LOCAL2 = 144; + public static final int LOCAL3 = 152; + public static final int LOCAL4 = 160; + public static final int LOCAL5 = 168; + public static final int LOCAL6 = 176; + public static final int LOCAL7 = 184; + + private static final int PORT = 514; + + private final InetAddress addr; + private Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).getParent(); + + /** + * Log to a particular log host. + */ + public Syslog(String loghost) throws UnknownHostException { + addr = InetAddress.getByName(loghost); + } + + /** + * Send a log message. + */ + public void log(int facility, int level, String msg) { + int fl = facility | level; + + String what = "<" + fl + ">" + msg; + + try { + DatagramPacket dp = new DatagramPacket(what.getBytes(), what.length(), addr, PORT); + DatagramSocket s = new DatagramSocket(); + s.send(dp); + if (!s.isClosed()) { + s.close(); + } + } catch (IOException e) { + logger.log(Level.WARNING, "Error sending syslog packet", e); + } + } + +} \ No newline at end of file diff --git a/src/main/java/x1/jboss/syslog/SyslogHandler.java b/src/main/java/x1/jboss/syslog/SyslogHandler.java new file mode 100644 index 0000000..ae6e877 --- /dev/null +++ b/src/main/java/x1/jboss/syslog/SyslogHandler.java @@ -0,0 +1,197 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * The contents of this file are subject to the terms of the GNU + * General Public License Version 2 only ("GPL"). + * You may not use this file except in compliance with the License. You can + * obtain a copy of the License at http://www.gnu.org/licenses/gpl-2.0.html + * See the License for the specific language governing permissions and + * limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * This particular file is designated as subject to the "Classpath" + * exception. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright (c) 2009-2010 Oracle and/or its affiliates. + * + * 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 x1.jboss.syslog; + +import java.util.logging.*; +import java.lang.management.ManagementFactory; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ArrayBlockingQueue; + +public class SyslogHandler extends Handler { + private Syslog sysLogger; + private Thread pump = null; + private BooleanLatch done = new BooleanLatch(); + private BlockingQueue pendingRecords = new ArrayBlockingQueue(5000); + private String loghost = "localhost"; + private String hostname = "localhost"; + private String application = "java"; + private String pid; + + public SyslogHandler() { + } + + private void init() { + pid = ManagementFactory.getRuntimeMXBean().getName(); + LogManager manager = LogManager.getLogManager(); + String cname = getClass().getName(); + String systemLogging = manager.getProperty(cname + ".useSystemLogging"); + if (systemLogging != null && systemLogging.equals("false")) { + return; + } + // set up the connection + try { + sysLogger = new Syslog(loghost); + } catch (java.net.UnknownHostException e) { + Logger.getAnonymousLogger().log(Level.SEVERE, "unknown host"); + return; + } + try { + InetAddress addr = InetAddress.getLocalHost(); + hostname = addr.getHostName(); + } catch (UnknownHostException e) { + } + + // start the Queue consummer thread. + pump = new Thread() { + public void run() { + try { + while (!done.isSignalled()) { + log(); + } + } catch (RuntimeException e) { + Logger.getAnonymousLogger().log(Level.WARNING, "Error while logging: " + e.getMessage()); + } + } + }; + pump.start(); + } + + private void log() { + LogRecord record; + + try { + record = pendingRecords.take(); + } catch (InterruptedException e) { + return; + } + Level level = record.getLevel(); + // long millisec = record.getMillis(); + int l; + String slLvl; + + if (level.equals(Level.SEVERE)) { + l = Syslog.CRIT; + slLvl = "ERR "; + } else if (level.equals(Level.WARNING)) { + l = Syslog.WARNING; + slLvl = "WARN "; + } else if (level.equals(Level.INFO)) { + l = Syslog.INFO; + slLvl = "INFO "; + } else { + l = Syslog.DEBUG; + slLvl = "DEBUG"; + } + + // SimpleDateFormat formatter = new + // SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS"); + + // format the message + String msg; + msg = hostname + " " + application + "[" + pid + "]: " + + // formatter.format(millisec) + " " + + slLvl + " [" + record.getLoggerName() + "] " + record.getMessage(); + if (msg.length() > 1024) { + msg = msg.substring(0, 1024); + } + // send message + sysLogger.log(Syslog.DAEMON, l, msg); + } + + /* + * (non-Javadoc) + * + * @see java.util.logging.Handler#publish(java.util.logging.LogRecord) + */ + @Override + public void publish(LogRecord record) { + if (pid == null) { + init(); + } + if (pump == null) { + return; + } + try { + pendingRecords.add(record); + } catch (IllegalStateException e) { + // queue is full, start waiting. + try { + pendingRecords.put(record); + } catch (InterruptedException e1) { + // record is lost... + } + } + } + + /* + * (non-Javadoc) + * + * @see java.util.logging.Handler#close() + */ + @Override + public void close() { + done.tryReleaseShared(0); + pump = null; + } + + /* + * (non-Javadoc) + * + * @see java.util.logging.Handler#flush() + */ + @Override + public void flush() { + if (!pendingRecords.isEmpty()) { + log(); + } + } + + public String getLoghost() { + return loghost; + } + + public void setLoghost(String loghost) { + this.loghost = loghost; + } + + public String getApplication() { + return application; + } + + public void setApplication(String application) { + this.application = application; + } +} \ No newline at end of file diff --git a/src/test/java/x1/jboss/syslog/SysLogTest.java b/src/test/java/x1/jboss/syslog/SysLogTest.java new file mode 100644 index 0000000..c200dc4 --- /dev/null +++ b/src/test/java/x1/jboss/syslog/SysLogTest.java @@ -0,0 +1,61 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * The contents of this file are subject to the terms of the GNU + * General Public License Version 2 only ("GPL"). + * You may not use this file except in compliance with the License. You can + * obtain a copy of the License at http://www.gnu.org/licenses/gpl-2.0.html + * See the License for the specific language governing permissions and + * limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at packager/legal/LICENSE.txt. + * + * GPL Classpath Exception: + * This particular file is designated as subject to the "Classpath" + * exception. + * + * Modifications: + * If applicable, add the following below the License Header, with the fields + * enclosed by brackets [] replaced by your own identifying information: + * "Portions Copyright [year] [name of copyright owner]" + * + * This file incorporates work covered by the following copyright and + * permission notice: + * + * Copyright (c) 2009-2010 Oracle and/or its affiliates. + * + * 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 x1.jboss.syslog; + +import static org.junit.Assert.*; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.junit.Test; + +public class SysLogTest { + + @Test + public void testLogger() throws Exception { + Logger logger = Logger.getLogger(SysLogTest.class.getName()); + SyslogHandler handler = new SyslogHandler(); + assertEquals("localhost", handler.getLoghost()); + handler.setLoghost("192.168.122.251"); + assertNull(handler.getFormatter()); + logger.addHandler(handler); + logger.warning("test-1"); + handler.setLevel(Level.WARNING); + logger.severe("test-2"); + logger.fine("test-3"); + Thread.sleep(500); + handler.flush(); + } + +}