Skip to content

Instantly share code, notes, and snippets.

Last active December 22, 2015 18:18
Show Gist options
  • Save nicmarti/6511635 to your computer and use it in GitHub Desktop.
Save nicmarti/6511635 to your computer and use it in GitHub Desktop.
Simple logback appender for Fluentd, ready to use with Play2 application
package org.zaptravel.logback.fluentd;
import java.util.HashMap;
import java.util.Map;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.UnsynchronizedAppenderBase;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.fluentd.logger.FluentLogger;
import org.slf4j.MDC;
* A simple logback appender for FluentD.
* @author nmartignole
public class FluentdLogbackAppenderBase<E> extends UnsynchronizedAppenderBase<E> {
private FluentLogger fluentdLogger;
public void start() {
fluentdLogger = FluentLogger.getLogger(tagprefix, fluentdHost, port);
String msg = "App starting ";
try {
msg = msg + InetAddress.getLocalHost().toString();
} catch (UnknownHostException e) {
Map<String, Object> data = new HashMap<String, Object>();
data.put("level", "INFO");
data.put("logger", "root");
data.put("thread", Thread.currentThread().getName());
data.put("uri", null);
data.put("msg", msg);
fluentdLogger.log(clientid, data);
public void stop() {
protected void append(E event) {
String cleanMsg = StringEscapeUtils.escapeEcmaScript(event.toString());
if (cleanMsg != null && cleanMsg.length() > MSG_SIZE_LIMIT) {
cleanMsg = StringUtils.abbreviate(cleanMsg, MSG_SIZE_LIMIT);
if (event instanceof LoggingEvent) {
ch.qos.logback.classic.spi.LoggingEvent loggingEvent = (ch.qos.logback.classic.spi.LoggingEvent) event;
Map<String, Object> data = new HashMap<String, Object>();
data.put("level", loggingEvent.getLevel());
data.put("logger", loggingEvent.getLoggerName());
data.put("thread", loggingEvent.getThreadName());
data.put("msg", cleanMsg);
String uri = MDC.get("URL");
if (uri != null) {
data.put("uri", uri);
} else {
Map mdcMap = loggingEvent.getMDCPropertyMap();
if (mdcMap != null && mdcMap.containsKey("URL")) {
data.put("uri", mdcMap.get("URL"));
} else {
data.put("uri", "unknown");
fluentdLogger.log(clientid, data);
public String getTagprefix() {
return tagprefix;
public void setTagprefix(String tagprefix) {
this.tagprefix = tagprefix;
public String getClientid() {
return clientid;
public void setClientid(String clientid) {
this.clientid = clientid;
public String getFluentdHost() {
return fluentdHost;
public void setFluentdHost(String fluentdHost) {
this.fluentdHost = fluentdHost;
public int getPort() {
return port;
public void setPort(int port) {
this.port = port;
private String tagprefix;
private String clientid;
private String fluentdHost;
private int port;
private static final int MSG_SIZE_LIMIT = 65535;
<configuration info="true" scan="false" scanPeriod="30 seconds">
<conversionRule conversionWord="coloredLevel" converterClass="play.api.Logger$ColoredLevel"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<pattern>%coloredLevel %d{HH:mm:ss,SSS} %X{URL} %logger: %message%n%ex{10}</pattern>
<appender name="FLUENTD" class="org.zaptravel.logback.fluentd.FluentdLogbackAppenderBase">
<logger name="play" level="WARN"/>
<logger name="application" level="INFO"/>
<logger name="net.sf.ehcache.sizeof.verboseDebugLogging" level="INFO"/>
<logger name="net.sf.ehcache" level="WARN"/>
<logger name="org.fluentd.logger.sender.RawSocketSender" level="INFO"/>
<logger name="org.apache.commons.pool" level="INFO"/>
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FLUENTD"/>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment