package com.logentries.logback; import ch.qos.logback.classic.PatternLayout; import ch.qos.logback.classic.encoder.PatternLayoutEncoder; import ch.qos.logback.classic.pattern.SyslogStartConverter; import ch.qos.logback.classic.spi.ILoggingEvent; import ch.qos.logback.classic.spi.IThrowableProxy; import ch.qos.logback.core.AppenderBase; import ch.qos.logback.core.Layout; import ch.qos.logback.core.net.SyslogConstants; import com.logentries.net.AsyncLogger; /** * Logentries appender for logback. * * @author Mark Lacomber * @author Ben McCann * @author Chris Mowforth */ public class LogentriesAppender extends AppenderBase<ILoggingEvent> { /** * Asynchronous Background logger */ private final AsyncLogger le_async; /** * Layout */ private Layout<ILoggingEvent> layout; /** * Facility String */ private String facilityStr; /** * Default Suffix Pattern */ public static final String DEFAULT_SUFFIX_PATTERN = "[%thread] %logger %msg"; private String suffixPattern; /** * Creates a new Logentries appender. */ public LogentriesAppender() { this.le_async = new AsyncLogger(); } /** * Creates a new Logentries appender. * <p>Used for unit testing.</p> * @param logger the {@link AsyncLogger} to dispatch events */ public LogentriesAppender(AsyncLogger logger) { this.le_async = logger; } /* * Public methods to send logback parameters to AsyncLogger */ /** * Sets the token. * * @param token */ public void setToken(String token) { this.le_async.setToken(token); } /** * Sets the HTTP PUTflag. <p>Send logs via HTTP PUT instead of default Token * TCP.</p> * * @param httpput true to use HTTP PUT API */ public void setHttpPut(boolean HttpPut) { this.le_async.setHttpPut(HttpPut); } /** * Sets the ACCOUNT KEY value for HTTP PUT. * * @param account_key */ public void setKey(String account_key) { this.le_async.setKey(account_key); } /** * Sets the LOCATION value for HTTP PUT. * * @param log_location */ public void setLocation(String log_location) { this.le_async.setLocation(log_location); } /** * Sets the SSL boolean flag * * @param ssl */ public void setSsl(boolean ssl) { this.le_async.setSsl(ssl); } /** * Sets the debug flag. * * <p>Appender in debug mode will print error messages on error console.</p> * * @param debug debug flag to set */ public void setDebug(boolean debug) { this.le_async.setDebug(debug); } /** * Sets the flag which determines if DataHub instance is used instead of Logentries service. * * @param useDataHub set to true to send log messaged to a DataHub instance. */ public void setIsUsingDataHub(boolean useDataHub){ this.le_async.setUseDataHub(useDataHub); } /** * Sets the address where DataHub server resides. * * @param dataHubAddr address like "127.0.0.1" */ public void setDataHubAddr(String dataHubAddr) { this.le_async.setDataHubAddr(dataHubAddr); } /** * Sets the port number on which DataHub instance waits for log messages. * * @param dataHubPort */ public void setDataHubPort(int dataHubPort) { this.le_async.setDataHubPort(dataHubPort); } /** * Determines whether to send HostName alongside with the log message * * @param logHostName */ public void setLogHostName(boolean logHostName) { this.le_async.setLogHostName(logHostName); } /** * Sets the HostName from the configuration * * @param hostName */ public void setHostName(String hostName) { this.le_async.setHostName(hostName); } /** * Sets LogID parameter from the configuration * * @param logID */ public void setLogID(String logID) { this.le_async.setLogID(logID); } /** * Sets the suffixPattern to be the <pattern> field in the .xml configuration file * * @param encoder */ public void setEncoder(PatternLayoutEncoder encoder) { this.suffixPattern = encoder.getPattern(); } @Override public void start() { if (layout == null) { layout = buildLayout(); } super.start(); } String getPrefixPattern() { return "%syslogStart{" + getFacility() + "}%nopex"; } /** * Returns the string value of the <b>Facility</b> option. * * See {@link #setFacility} for the set of allowed values. */ public String getFacility() { return facilityStr; } /** * The <b>Facility</b> option must be set one of the strings KERN, USER, * MAIL, DAEMON, AUTH, SYSLOG, LPR, NEWS, UUCP, CRON, AUTHPRIV, FTP, NTP, * AUDIT, ALERT, CLOCK, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, * LOCAL6, LOCAL7. Case is not important. * * <p>See {@link SyslogConstants} and RFC 3164 for more information about * the <b>Facility</b> option. */ public void setFacility(String facilityStr) { if (facilityStr != null) { facilityStr = facilityStr.trim(); } this.facilityStr = facilityStr; } /** * Sets the layout for the Appender */ public void setLayout(Layout<ILoggingEvent> layout) { this.layout = layout; } public Layout<ILoggingEvent> getLayout() { return layout; } /** * Implements AppenderSkeleton Append method, handles time and format * * @event event to log */ @Override protected void append(ILoggingEvent event) { // Render the event according to layout String formattedEvent = layout.doLayout(event); // Prepare to be queued this.le_async.addLineToQueue(formattedEvent); } /** * Closes all connections to Logentries */ @Override public void stop() { super.stop(); this.le_async.close(); } public Layout<ILoggingEvent> buildLayout() { PatternLayout l = new PatternLayout(); l.getInstanceConverterMap().put("syslogStart", SyslogStartConverter.class.getName()); if (suffixPattern == null) { suffixPattern = DEFAULT_SUFFIX_PATTERN; } l.setPattern(getPrefixPattern() + suffixPattern); l.setContext(getContext()); l.start(); return l; } /** * See {@link #setSuffixPattern(String). * * @return */ public String getSuffixPattern() { return suffixPattern; } /** * The <b>suffixPattern</b> option specifies the format of the * non-standardized part of the message sent to the syslog server. * * @param suffixPattern */ public void setSuffixPattern(String suffixPattern) { this.suffixPattern = suffixPattern; } }