package org.wildfly.swarm.fluentd.runtime; import java.util.HashMap; import java.util.Map; import java.util.logging.ErrorManager; import java.util.logging.Logger; import org.fluentd.logger.sender.RawSocketSender; import org.jboss.logmanager.ExtHandler; import org.jboss.logmanager.ExtLogRecord; /** * @author Heiko Braun * @since 14/11/2016 */ public class FluentdHandler extends ExtHandler { public enum Key { EXCEPTION("exception"), LEVEL("level"), LOGGER_CLASS_NAME("loggerClassName"), LOGGER_NAME("loggerName"), MDC("mdc"), MESSAGE("message"), NDC("ndc"), RECORD("record"), SEQUENCE("sequence"), THREAD_ID("threadId"), THREAD_NAME("threadName"), TIMESTAMP("timestamp"); private final String key; Key(final String key) { this.key = key; } /** * Returns the name of the key for the structure. * * @return the name of they key */ public String getKey() { return key; } } public FluentdHandler() { setAutoFlush(false); } public void setHostname(String hostname) { this.hostname = hostname; } public void setPort(int port) { this.port = port; } public void setTag(String tag) { this.tag = tag; } @Override protected void doPublish(ExtLogRecord record) { synchronized (this) { if (!initialized) { try { initialize(); } catch (Exception e) { reportError("Error creating fluentd connection", e, ErrorManager.OPEN_FAILURE); setEnabled(false); } } } if (initialized) { Map<String, Object> entries = new HashMap<>(); entries.put(Key.SEQUENCE.getKey(), record.getSequenceNumber()); entries.put(Key.LEVEL.getKey(), record.getLevel().getName()); entries.put(Key.THREAD_NAME.getKey(), record.getThreadName()); entries.put(Key.MESSAGE.getKey(), record.getFormattedMessage()); entries.put(Key.THREAD_ID.getKey(), record.getThreadID()); entries.put(Key.MDC.getKey(), record.getMdcCopy()); entries.put(Key.NDC.getKey(), record.getNdc()); this.sender.emit(this.tag, record.getMillis(), entries); } } private void initialize() { try { this.sender = new RawSocketSender(hostname, port); this.initialized = true; log.info("Connected to fluentd daemon"); } catch (Throwable t) { throw new RuntimeException("Failed to initialise fluentd connection", t); } } @Override public void flush() { // should not happen } @Override public void close() { super.close(); log.info("Disconnect from fluentd daemon ..."); synchronized (this) { safeClose(this.sender); this.sender = null; this.initialized = false; } } private void safeClose(RawSocketSender c) { try { if (c != null) { c.close(); } } catch (Exception e) { reportError("Error closing resource", e, ErrorManager.CLOSE_FAILURE); } catch (Throwable ignored) { } } private static final java.util.logging.Logger log = Logger.getLogger("org.wildfly.swarm.fluentd"); private String hostname; private int port; private boolean initialized; private RawSocketSender sender; private String tag; }