Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Console appender for graylog2 #16

Merged
merged 4 commits into from Oct 10, 2011
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/main/java/org/graylog2/GelfMessage.java
Expand Up @@ -20,6 +20,7 @@ public class GelfMessage {
private String shortMessage;
private String fullMessage;
private Long timestamp;
private long javaTimestamp;
private String level;
private String facility = "gelf-java";
private String line;
Expand All @@ -29,17 +30,21 @@ public class GelfMessage {
public GelfMessage() {
}

// todo: merge these constructors.

public GelfMessage(String shortMessage, String fullMessage, Date timestamp, String level) {
this.shortMessage = shortMessage;
this.fullMessage = fullMessage;
this.timestamp = timestamp.getTime() / 1000L;
this.javaTimestamp = timestamp.getTime();
this.timestamp = javaTimestamp / 1000L;
this.level = level;
}

public GelfMessage(String shortMessage, String fullMessage, Long timestamp, String level, String line, String file) {
this.shortMessage = shortMessage;
this.fullMessage = fullMessage;
this.timestamp = timestamp / 1000L;
this.javaTimestamp = timestamp;
this.timestamp = javaTimestamp / 1000L;
this.level = level;
this.line = line;
this.file = file;
Expand Down Expand Up @@ -145,6 +150,10 @@ public void setFullMessage(String fullMessage) {
public Long getTimestamp() {
return timestamp;
}

public Long getJavaTimestamp() {
return javaTimestamp;
}

public void setTimestamp(Long timestamp) {
this.timestamp = timestamp;
Expand Down
103 changes: 103 additions & 0 deletions src/main/java/org/graylog2/GelfMessageFactory.java
@@ -0,0 +1,103 @@
package org.graylog2;

import org.apache.log4j.Level;
import org.apache.log4j.MDC;
import org.apache.log4j.spi.LocationInfo;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ThrowableInformation;
import org.graylog2.log.Log4jVersionChecker;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Map;

public class GelfMessageFactory {
private static final int MAX_SHORT_MESSAGE_LENGTH = 250;
private static final String ORIGIN_HOST_KEY = "originHost";
private static final String LOGGER_NAME = "logger";
private static final String LOGGER_NDC = "loggerNdc";
private static final String JAVA_TIMESTAMP = "timestampMs";

public static final GelfMessage makeMessage(LoggingEvent event, GelfMessageProvider provider) {
long timeStamp = Log4jVersionChecker.getTimeStamp(event);
Level level = event.getLevel();

LocationInfo locationInformation = event.getLocationInformation();
String file = locationInformation.getFileName();
String lineNumber = locationInformation.getLineNumber();

String renderedMessage = event.getRenderedMessage();
String shortMessage;

if (renderedMessage == null) {
renderedMessage = "";
}

if (renderedMessage.length() > MAX_SHORT_MESSAGE_LENGTH) {
shortMessage = renderedMessage.substring(0, MAX_SHORT_MESSAGE_LENGTH - 1);
}
else {
shortMessage = renderedMessage;
}

if (provider.isExtractStacktrace()) {
ThrowableInformation throwableInformation = event.getThrowableInformation();
if (throwableInformation != null) {
renderedMessage += "\n\r" + extractStacktrace(throwableInformation);
}
}

GelfMessage gelfMessage = new GelfMessage(shortMessage, renderedMessage, timeStamp,
String.valueOf(level.getSyslogEquivalent()), lineNumber, file);

if (provider.getOriginHost() != null) {
gelfMessage.setHost(provider.getOriginHost());
}

if (provider.getFacility() != null) {
gelfMessage.setFacility(provider.getFacility());
}

Map<String, String> fields = provider.getFields();
for (Map.Entry<String, String> entry : fields.entrySet()) {
if (entry.getKey().equals(ORIGIN_HOST_KEY) && gelfMessage.getHost() == null) {
gelfMessage.setHost(fields.get(ORIGIN_HOST_KEY));
} else {
gelfMessage.addField(entry.getKey(), entry.getValue());
}
}

if (provider.isAddExtendedInformation()) {

gelfMessage.addField(LOGGER_NAME, event.getLoggerName());
gelfMessage.addField(JAVA_TIMESTAMP, Long.toString(gelfMessage.getJavaTimestamp()));

// Get MDC and add a GELF field for each key/value pair
Map<String, Object> mdc = MDC.getContext();

if(mdc != null) {
for(Map.Entry<String, Object> entry : mdc.entrySet()) {

gelfMessage.addField(entry.getKey(), entry.getValue().toString());
}
}

// Get NDC and add a GELF field
String ndc = event.getNDC();

if(ndc != null) {

gelfMessage.addField(LOGGER_NDC, ndc);
}
}

return gelfMessage;
}

private static String extractStacktrace(ThrowableInformation throwableInformation) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
throwableInformation.getThrowable().printStackTrace(pw);
return sw.toString();
}
}
13 changes: 13 additions & 0 deletions src/main/java/org/graylog2/GelfMessageProvider.java
@@ -0,0 +1,13 @@
package org.graylog2;

import org.apache.log4j.spi.LoggingEvent;

import java.util.Map;

public interface GelfMessageProvider {
public boolean isExtractStacktrace();
public String getOriginHost();
public String getFacility();
public Map<String, String> getFields();
public boolean isAddExtendedInformation();
}
106 changes: 13 additions & 93 deletions src/main/java/org/graylog2/log/GelfAppender.java
Expand Up @@ -8,6 +8,8 @@
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ThrowableInformation;
import org.graylog2.GelfMessage;
import org.graylog2.GelfMessageFactory;
import org.graylog2.GelfMessageProvider;
import org.graylog2.GelfSender;
import org.json.simple.JSONValue;

Expand All @@ -16,14 +18,16 @@
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
*
* @author Anton Yakimov
* @author Jochen Schalanda
*/
public class GelfAppender extends AppenderSkeleton {
public class GelfAppender extends AppenderSkeleton implements GelfMessageProvider {

private String graylogHost;
private String originHost;
Expand All @@ -34,12 +38,6 @@ public class GelfAppender extends AppenderSkeleton {
private boolean addExtendedInformation;
private Map<String, String> fields;

private static final int MAX_SHORT_MESSAGE_LENGTH = 250;
private static final String ORIGIN_HOST_KEY = "originHost";
private static final String LOGGER_NAME = "logger";
private static final String LOGGER_NDC = "loggerNdc";
private static final String JAVA_TIMESTAMP = "timestampMs";

public GelfAppender() {
super();
this.originHost = getLocalHostName();
Expand Down Expand Up @@ -107,6 +105,13 @@ public boolean isAddExtendedInformation() {
public void setAddExtendedInformation(boolean addExtendedInformation) {
this.addExtendedInformation = addExtendedInformation;
}

public Map<String, String> getFields() {
if (fields == null) {
fields = new HashMap<String, String>();
}
return Collections.unmodifiableMap(fields);
}

@Override
public void activateOptions() {
Expand All @@ -121,81 +126,7 @@ public void activateOptions() {

@Override
protected void append(LoggingEvent event) {

long timeStamp = getTimestamp(event);

Level level = event.getLevel();

LocationInfo locationInformation = event.getLocationInformation();
String file = locationInformation.getFileName();
String lineNumber = locationInformation.getLineNumber();

String renderedMessage = event.getRenderedMessage();
String shortMessage;

if(renderedMessage == null) {
renderedMessage = "";
}

if (renderedMessage.length() > MAX_SHORT_MESSAGE_LENGTH) {
shortMessage = renderedMessage.substring(0, MAX_SHORT_MESSAGE_LENGTH - 1);
} else {
shortMessage = renderedMessage;
}

if (isExtractStacktrace()) {
ThrowableInformation throwableInformation = event.getThrowableInformation();
if (throwableInformation != null) {
renderedMessage += "\n\r" + extractStacktrace(throwableInformation);
}
}

GelfMessage gelfMessage = new GelfMessage(shortMessage, renderedMessage, timeStamp,
String.valueOf(level.getSyslogEquivalent()), lineNumber, file);

if (getOriginHost() != null) {
gelfMessage.setHost(getOriginHost());
}

if (getFacility() != null) {
gelfMessage.setFacility(getFacility());
}

if (fields != null && !fields.isEmpty()) {

if (fields.containsKey(ORIGIN_HOST_KEY) && gelfMessage.getHost() == null) {
gelfMessage.setHost(fields.get(ORIGIN_HOST_KEY));
fields.remove(ORIGIN_HOST_KEY);
}

for (Map.Entry<String, String> entry : fields.entrySet()) {
gelfMessage.addField(entry.getKey(), entry.getValue());
}
}

if (isAddExtendedInformation()) {

gelfMessage.addField(LOGGER_NAME, event.getLoggerName());
gelfMessage.addField(JAVA_TIMESTAMP, Long.toString(timeStamp));

// Get MDC and add a GELF field for each key/value pair
Map<String, Object> mdc = MDC.getContext();

if(mdc != null) {
for(Map.Entry<String, Object> entry : mdc.entrySet()) {

gelfMessage.addField(entry.getKey(), entry.getValue().toString());
}
}

// Get NDC and add a GELF field
String ndc = event.getNDC();

if(ndc != null) {

gelfMessage.addField(LOGGER_NDC, ndc);
}
}
GelfMessage gelfMessage = GelfMessageFactory.makeMessage(event, this);

if(getGelfSender() == null || !getGelfSender().sendMessage(gelfMessage)) {
errorHandler.error("Could not send GELF message");
Expand All @@ -206,17 +137,6 @@ public GelfSender getGelfSender() {
return gelfSender;
}

private long getTimestamp(LoggingEvent event) {
return Log4jVersionChecker.getTimeStamp(event);
}

private String extractStacktrace(ThrowableInformation throwableInformation) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
throwableInformation.getThrowable().printStackTrace(pw);
return sw.toString();
}

public void close() {
getGelfSender().close();
}
Expand Down