Permalink
Browse files

SMX4-1256: Add Logstash event message format

git-svn-id: https://svn.apache.org/repos/asf/servicemix/smx4/features/trunk@1393356 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information...
1 parent 1c9f627 commit ec2a05634ef78d3805a618677d109fe2f4d72500 @gertv gertv committed Oct 3, 2012
View
@@ -2,5 +2,6 @@
.classpath
.project
target
+.idea
*.i??
velocity.log
@@ -34,21 +34,42 @@
<packaging>bundle</packaging>
<dependencies>
- <dependency>
+ <dependency>
<groupId>org.ops4j.pax.logging</groupId>
- <artifactId>pax-logging-api</artifactId>
+ <artifactId>pax-logging-service</artifactId>
<version>${pax.logging.version}</version>
</dependency>
<dependency>
<groupId>org.ops4j.pax.logging</groupId>
- <artifactId>pax-logging-service</artifactId>
+ <artifactId>pax-logging-api</artifactId>
<version>${pax.logging.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>${activemq.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.json</groupId>
+ <artifactId>json</artifactId>
+ <version>20090211</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.activemq</groupId>
+ <artifactId>activemq-camel</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
@@ -61,16 +82,14 @@
<instructions>
<Bundle-SymbolicName>${pom.artifactId}</Bundle-SymbolicName>
<Import-Package>
- org.ops4j.pax.logging;resolution:=optional,
- org.osgi.service.blueprint;resolution:=optional,
- org.ops4j.pax.logging.spi*;resolution:=optional,
- org.slf4j,
- javax.jms,
- org.apache.activemq
+ *
</Import-Package>
- <Export-Package>
- org.apache.servicemix.logging
- </Export-Package>
+ <Private-Package>
+ org.apache.servicemix.logging.jms
+ </Private-Package>
+ <Embed-Dependency>
+ json
+ </Embed-Dependency>
</instructions>
</configuration>
</plugin>
@@ -0,0 +1,70 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.logging.jms;
+
+import org.ops4j.pax.logging.spi.PaxLoggingEvent;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Default event logging format for the JMS appender
+ */
+public class DefaultLoggingEventFormat implements LoggingEventFormat {
+
+ private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+
+ public String toString(PaxLoggingEvent paxLoggingEvent) {
+ StringBuilder writer = new StringBuilder();
+
+ writer.append("Error");
+ writer.append(",\n \"timestamp\" : " + formatDate(paxLoggingEvent.getTimeStamp()));
+ writer.append(",\n \"level\" : " + paxLoggingEvent.getLevel().toString());
+ writer.append(",\n \"logger\" : " + paxLoggingEvent.getLoggerName());
+ writer.append(",\n \"thread\" : " + paxLoggingEvent.getThreadName());
+ writer.append(",\n \"message\" : " + paxLoggingEvent.getMessage());
+
+ String[] throwable = paxLoggingEvent.getThrowableStrRep();
+ if (throwable != null) {
+ writer.append(",\n \"exception\" : [");
+ for (int i = 0; i < throwable.length; i++) {
+ if (i != 0)
+ writer.append(", " + throwable[i]);
+ }
+ writer.append("]");
+ }
+
+ writer.append(",\n \"properties\" : { ");
+ boolean first = true;
+ for (Object key : paxLoggingEvent.getProperties().keySet()) {
+ if (first) {
+ first = false;
+ } else {
+ writer.append(", ");
+ }
+ writer.append("key : " + key.toString());
+ writer.append(": " + paxLoggingEvent.getProperties().get(key).toString());
+ }
+ writer.append(" }");
+ writer.append("\n}");
+ return writer.toString();
+ }
+
+ private String formatDate(long timestamp) {
+ return simpleDateFormat.format(new Date(timestamp));
+ }
+}
@@ -14,35 +14,38 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.servicemix.logging;
+package org.apache.servicemix.logging.jms;
import org.ops4j.pax.logging.spi.PaxAppender;
import org.ops4j.pax.logging.spi.PaxLoggingEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.jms.*;
-import java.text.SimpleDateFormat;
-import java.util.Date;
public class JMSAppender implements PaxAppender {
private static final transient Logger LOG = LoggerFactory.getLogger(JMSAppender.class);
+ private static final String DEFAULT_EVENT_FORMAT = "default";
+ private static final String LOGSTASH_EVENT_FORMAT = "logstash";
+
+
private ConnectionFactory jmsConnectionFactory;
private Connection connection;
private Session session;
private MessageProducer publisher;
private Topic topic;
private String destinationName;
- private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
+ private LoggingEventFormat format = new DefaultLoggingEventFormat();
+
+
public void init() {
/*
* Create connection. Create session from connection; false means
* session is not transacted.
- * Finally, close connection.
*/
try {
connection = jmsConnectionFactory.createConnection();
@@ -70,56 +73,14 @@ public void close() {
}
public void doAppend(PaxLoggingEvent paxLoggingEvent) {
-
try {
- StringBuilder writer = new StringBuilder();
-
- writer.append("Error");
- writer.append(",\n \"timestamp\" : " + formatDate(paxLoggingEvent.getTimeStamp()));
- writer.append(",\n \"level\" : " + paxLoggingEvent.getLevel().toString());
- writer.append(",\n \"logger\" : " + paxLoggingEvent.getLoggerName());
- writer.append(",\n \"thread\" : " + paxLoggingEvent.getThreadName());
- writer.append(",\n \"message\" : " + paxLoggingEvent.getMessage());
-
- String[] throwable = paxLoggingEvent.getThrowableStrRep();
- if (throwable != null) {
- writer.append(",\n \"exception\" : [");
- for (int i = 0; i < throwable.length; i++) {
- if (i != 0)
- writer.append(", " + throwable[i]);
- }
- writer.append("]");
- }
-
- writer.append(",\n \"properties\" : { ");
- boolean first = true;
- for (Object key : paxLoggingEvent.getProperties().keySet()) {
- if (first) {
- first = false;
- } else {
- writer.append(", ");
- }
- writer.append("key : " + key.toString());
- writer.append(": " + paxLoggingEvent.getProperties().get(key).toString());
- }
- writer.append(" }");
- writer.append("\n}");
-
// Send message to the destination
TextMessage message = session.createTextMessage();
- message.setText(writer.toString());
+ message.setText(format.toString(paxLoggingEvent));
publisher.send(message);
-
- // System.out.println(">> Message created : " + writer.toString());
-
- } catch (Exception e) {
+ } catch (JMSException e) {
e.printStackTrace();
}
-
- }
-
- private String formatDate(long timestamp) {
- return simpleDateFormat.format(new Date(timestamp));
}
public void setJmsConnectionFactory(ConnectionFactory jmsConnectionFactory) {
@@ -130,4 +91,11 @@ public void setDestinationName(String destinationName) {
this.destinationName = destinationName;
}
+ public void setFormat(String name) {
+ if (LOGSTASH_EVENT_FORMAT.equals(name)) {
+ format = new LogstashEventFormat();
+ } else {
+ format = new DefaultLoggingEventFormat();
+ }
+ }
}
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.logging.jms;
+
+import org.ops4j.pax.logging.spi.PaxLoggingEvent;
+
+/**
+ * Interface to represent an event message format, used for serializing log events into JMS messages
+ */
+public interface LoggingEventFormat {
+
+ public String toString(PaxLoggingEvent event);
+
+}
@@ -0,0 +1,68 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.logging.jms;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.ops4j.pax.logging.spi.PaxLoggingEvent;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * Creates a log message in Logstash' internal message format,
+ * cfr. https://github.com/logstash/logstash/wiki/logstash's-internal-message-format
+ */
+public class LogstashEventFormat implements LoggingEventFormat {
+
+ protected static final DateFormat TIMESTAMP_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
+
+ protected static final String FIELDS = "@fields";
+ protected static final String MESSAGE = "@message";
+ protected static final String SOURCE = "@source";
+ protected static final String TAGS = "@tags";
+ protected static final String TIMESTAMP = "@timestamp";
+
+ public String toString(PaxLoggingEvent event) {
+ JSONObject object = new JSONObject();
+ try {
+ object.put(MESSAGE, event.getMessage());
+ object.put(SOURCE, event.getLoggerName());
+ object.put(TIMESTAMP, TIMESTAMP_FORMAT.format(new Date(event.getTimeStamp())));
+
+ JSONObject fields = new JSONObject();
+ for (Object property : event.getProperties().entrySet()) {
+ Map.Entry<String, Object> entry = (Map.Entry<String, Object>) property;
+ fields.put(entry.getKey(), entry.getValue().toString());
+ }
+
+ object.put(FIELDS, fields);
+
+ JSONArray tags = new JSONArray();
+ tags.put(event.getLevel().toString());
+ object.put(TAGS, tags);
+ } catch (JSONException e) {
+ // let's return a minimal, String-based message representation instead
+ return "{ \"" + MESSAGE + "\" : " + event.getMessage() + "}";
+ }
+ return object.toString();
+ }
+
+}
@@ -25,9 +25,10 @@
<!-- Need OSGI JMS Connection Factory Service exposed -->
<reference id="jmsConnectionFactory" interface="javax.jms.ConnectionFactory"/>
- <bean id="appender" class="org.apache.servicemix.logging.JMSAppender" init-method="init" destroy-method="close">
+ <bean id="appender" class="org.apache.servicemix.logging.jms.JMSAppender" init-method="init" destroy-method="close">
<property name="jmsConnectionFactory" ref="jmsConnectionFactory"/>
<property name="destinationName" value="${destinationName}" />
+ <property name="format" value="${format}"/>
</bean>
<service ref="appender" interface="org.ops4j.pax.logging.spi.PaxAppender">
Oops, something went wrong.

0 comments on commit ec2a056

Please sign in to comment.