Skip to content

Instantly share code, notes, and snippets.

@mp911de
Last active August 29, 2015 14:07
Show Gist options
  • Save mp911de/649cc4338bc09896e266 to your computer and use it in GitHub Desktop.
Save mp911de/649cc4338bc09896e266 to your computer and use it in GitHub Desktop.
GelfAccessLogValve for Tomcat 6
package biz.paluch.logging.accesslogvalve;
import java.io.IOException;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.valves.AccessLogValve;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import biz.paluch.logging.RuntimeContainer;
import biz.paluch.logging.gelf.intern.ErrorReporter;
import biz.paluch.logging.gelf.intern.GelfMessage;
import biz.paluch.logging.gelf.intern.GelfSender;
import biz.paluch.logging.gelf.intern.GelfSenderFactory;
import biz.paluch.logging.gelf.intern.sender.DefaultGelfSenderProvider;
import biz.paluch.logging.gelf.standalone.DefaultGelfSenderConfiguration;
/**
* @author <a href="mailto:mpaluch@paluch.biz">Mark Paluch</a>
* @since 21.10.14 08:13
*/
public class GelfAccessLogValve extends AccessLogValve {
private final static Map<Class, String> names = Collections.unmodifiableMap(new HashMap<Class, String>() {
{
put(HeaderElement.class, "Header");
put(CookieElement.class, "Cookie");
put(ResponseHeaderElement.class, "ResponseHeader");
put(SessionAttributeElement.class, "SessionAttribute");
put(RemoteAddrElement.class, "RemoteAddr");
put(LocalAddrElement.class, "LocalAddr");
put(ByteSentElement.class, "ByteSent");
put(ElapsedTimeElement.class, "ElapsedTime");
put(HostElement.class, "Host");
put(ProtocolElement.class, "Protocol");
put(MethodElement.class, "Method");
put(LocalPortElement.class, "LocalPort");
put(QueryElement.class, "Query");
put(RequestElement.class, "Request");
put(HttpStatusCodeElement.class, "HttpStatusCode");
put(SessionIdElement.class, "SessionId");
put(DateAndTimeElement.class, "DateAndTime");
put(UserElement.class, "User");
put(RequestURIElement.class, "RequestURI");
put(LocalServerNameElement.class, "LocalServerName");
put(ThreadNameElement.class, "ThreadName");
}
});
public static final String SYSLOG_LEVEL = "6";
private String host = "localhost";
private int port = DefaultGelfSenderProvider.DEFAULT_PORT;
private GelfSender gelfSender;
public void invoke(Request request, Response response) throws IOException, ServletException {
if (started && getEnabled()) {
// Pass this request on to the next valve in our pipeline
long t1 = System.currentTimeMillis();
getNext().invoke(request, response);
long t2 = System.currentTimeMillis();
long time = t2 - t1;
if (logElements == null || condition != null && null != request.getRequest().getAttribute(condition)) {
return;
}
long start = request.getCoyoteRequest().getStartTime();
Date date = new Date(start + time);
GelfMessage message = new GelfMessage();
message.setFacility(getClass().getSimpleName());
message.setFullMessage(request.getMethod() + " " + request.getRequestURI());
message.setShortMessage(request.getMethod() + " " + request.getRequestURI());
message.setJavaTimestamp(start + time);
message.setHost(RuntimeContainer.FQDN_HOSTNAME);
message.setLevel(SYSLOG_LEVEL);
for (int i = 0; i < logElements.length; i++) {
String name = names.get(logElements[i].getClass());
if (name == null) {
continue;
}
StringBuffer result = new StringBuffer(128);
logElements[i].addElement(result, date, request, response, time);
message.addField(name, result.toString());
}
gelfSender.sendMessage(message);
} else
getNext().invoke(request, response);
}
private void createSender() {
DefaultGelfSenderConfiguration configuration = new DefaultGelfSenderConfiguration(new ErrorReporter() {
private final Log log = LogFactory.getLog(getClass());
@Override
public void reportError(String message, Exception e) {
log.error(message, e);
}
});
configuration.setHost(host);
configuration.setPort(port);
gelfSender = GelfSenderFactory.createSender(configuration);
}
@Override
public void start() throws LifecycleException {
createSender();
super.start();
}
@Override
public void stop() throws LifecycleException {
if (gelfSender != null) {
gelfSender.close();
gelfSender = null;
}
super.stop();
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>biz.paluch.logging</groupId>
<artifactId>gelf-accesslog-valve</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>biz.paluch.logging</groupId>
<artifactId>logstash-gelf</artifactId>
<version>1.5.1</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>catalina</artifactId>
<version>6.0.18</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>coyote</artifactId>
<version>6.0.18</version>
</dependency>
</dependencies>
</project>
<Server port="8005" shutdown="SHUTDOWN">
...
<Service name="Catalina">
...
<Engine name="Catalina" defaultHost="localhost">
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="biz.paluch.logging.accesslogvalve.GelfAccessLogValve" host="localhost"
port="12201" pattern="%h %m %U %I %l %u %t &quot;%r&quot; %s %b" resolveHosts="false" />
</Host>
</Engine>
</Service>
</Server>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment