You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by rg...@apache.org on 2011/05/30 08:02:08 UTC
svn commit: r1129003 - in
/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers:
log4j2-api/src/main/java/org/apache/logging/log4j/message/
log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/
log4j2-core/src/main/java/org/apache/logging/lo...
Author: rgoers
Date: Mon May 30 06:02:07 2011
New Revision: 1129003
URL: http://svn.apache.org/viewvc?rev=1129003&view=rev
Log:
Add RFC 5424 Syslog and BSD Syslog layouts
Added:
logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/RFC5424Layout.java
logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/SyslogLayout.java
- copied, changed from r1128132, logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/SerializedLayout.java
logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/net/
logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/net/Facility.java
logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/net/Priority.java
logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/net/Severity.java
logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/layout/RFC5424LayoutTest.java
- copied, changed from r1128132, logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/layout/XMLLayoutTest.java
logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/layout/SyslogLayoutTest.java
Modified:
logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-api/src/main/java/org/apache/logging/log4j/message/StructuredDataId.java
logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java
Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-api/src/main/java/org/apache/logging/log4j/message/StructuredDataId.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-api/src/main/java/org/apache/logging/log4j/message/StructuredDataId.java?rev=1129003&r1=1129002&r2=1129003&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-api/src/main/java/org/apache/logging/log4j/message/StructuredDataId.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-api/src/main/java/org/apache/logging/log4j/message/StructuredDataId.java Mon May 30 06:02:07 2011
@@ -74,6 +74,9 @@ public class StructuredDataId implements
if (name == null) {
throw new IllegalArgumentException("No structured id name was supplied");
}
+ if (name.contains("@")) {
+ throw new IllegalArgumentException("Structured id name cannot contain an '@");
+ }
if (enterpriseNumber <= 0) {
throw new IllegalArgumentException("No enterprise number was supplied");
}
Modified: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java?rev=1129003&r1=1129002&r2=1129003&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java Mon May 30 06:02:07 2011
@@ -21,6 +21,9 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+import java.util.SortedMap;
+import java.util.StringTokenizer;
+import java.util.TreeMap;
/**
* Represents a Message that conforms to RFC 5424 (http://tools.ietf.org/html/rfc5424).
@@ -30,7 +33,7 @@ public class StructuredDataMessage imple
public static final String FULL = "full";
- private Map data = new HashMap();
+ private Map<String, String> data = new HashMap<String, String>();
private StructuredDataId id;
@@ -99,7 +102,7 @@ public class StructuredDataMessage imple
this.message = msg;
}
- public Map getData() {
+ public Map<String, String> getData() {
return Collections.unmodifiableMap(data);
}
@@ -123,11 +126,11 @@ public class StructuredDataMessage imple
}
public String get(String key) {
- return (String) data.get(key);
+ return data.get(key);
}
public String remove(String key) {
- return (String) data.remove(key);
+ return data.remove(key);
}
/**
@@ -195,9 +198,8 @@ public class StructuredDataMessage imple
}
private void appendMap(Map map, StringBuffer sb) {
- Iterator iter = map.entrySet().iterator();
- while (iter.hasNext()) {
- Map.Entry entry = (Map.Entry) iter.next();
+ SortedMap<String, Object> sorted = new TreeMap<String, Object>(map);
+ for (Map.Entry<String, Object> entry : sorted.entrySet()) {
sb.append(" ");
sb.append(entry.getKey()).append("=\"").append(entry.getValue()).append("\"");
}
Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/RFC5424Layout.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/RFC5424Layout.java?rev=1129003&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/RFC5424Layout.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/RFC5424Layout.java Mon May 30 06:02:07 2011
@@ -0,0 +1,364 @@
+/*
+ * 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.logging.log4j.core.layout;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginAttr;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+import org.apache.logging.log4j.core.net.Facility;
+import org.apache.logging.log4j.core.net.Priority;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.message.StructuredDataId;
+import org.apache.logging.log4j.message.StructuredDataMessage;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.nio.charset.Charset;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+
+/**
+ *
+ */
+@Plugin(name="RFC5424Layout",type="Core",elementType="layout",printObject=true)
+public class RFC5424Layout extends LayoutBase {
+
+ private final Facility facility;
+ private final String defaultId;
+ private final Integer enterpriseNumber;
+ private final boolean includeMDC;
+ private final String mdcId;
+ private final Charset charset;
+ private final String localHostName;
+ private final String appName;
+ private final String messageId;
+ private final String configName;
+ private final List<String> mdcExcludes;
+ private final List<String> mdcIncludes;
+ private final ListChecker checker;
+ private final boolean includeNewLine;
+
+ private long lastTimestamp = -1;
+ private String timestamppStr = null;
+
+ private static final DecimalFormat TWO_DIGIT = new DecimalFormat("00");
+ private static final DecimalFormat FOUR_DIGIT = new DecimalFormat("0000");
+
+ // Not a very good default - it is the Apache Software Foundation's.
+ public static final int DEFAULT_ENTERPRISE_NUMBER = 18060;
+ public static final String DEFAULT_ID = "Audit";
+
+ public RFC5424Layout(Facility facility, String id, int ein, boolean includeMDC, boolean includeNL, String mdcId,
+ String appName, String messageId, String excludes, String includes, Charset charset) {
+ this.facility = facility;
+ this.defaultId = id == null ? DEFAULT_ID : id;
+ this.enterpriseNumber = ein;
+ this.includeMDC = includeMDC;
+ this.includeNewLine = includeNL;
+ this.mdcId = mdcId;
+ this.appName = appName;
+ this.messageId = messageId;
+ this.charset = charset;
+ this.localHostName = getLocalHostname();
+ ListChecker c = null;
+ if (excludes != null) {
+ String[] array = excludes.split(",");
+ if (array.length > 0) {
+ c = new ExcludeChecker();
+ mdcExcludes = new ArrayList<String>(array.length);
+ for (String str : array) {
+ mdcExcludes.add(str.trim());
+ }
+ } else {
+ mdcExcludes = null;
+ }
+ } else {
+ mdcExcludes = null;
+ }
+ if (includes != null) {
+ String[] array = includes.split(",");
+ if (array.length > 0) {
+ c = new IncludeChecker();
+ mdcIncludes = new ArrayList<String>(array.length);
+ for (String str : array) {
+ mdcIncludes.add(str.trim());
+ }
+ } else {
+ mdcIncludes = null;
+ }
+ } else {
+ mdcIncludes = null;
+ }
+ this.checker = c != null ? c : new NoopChecker();
+ LoggerContext ctx = (LoggerContext) LogManager.getContext();
+ String name = ctx.getConfiguration().getName();
+ configName = (name != null && name.length() > 0) ? name : null;
+ }
+
+ /**
+ * Formats a {@link org.apache.logging.log4j.core.LogEvent} in conformance with the RFC 5424 Syslog specification.
+ */
+ public byte[] format(final LogEvent event) {
+ Message msg = event.getMessage();
+ boolean isStructured = msg instanceof StructuredDataMessage;
+ StringBuilder buf = new StringBuilder();
+
+ buf.append("<");
+ buf.append(Priority.getPriority(facility, event.getLevel()));
+ buf.append(">1 ");
+ buf.append(computeTimeStampString(event.getMillis()));
+ buf.append(' ');
+ buf.append(localHostName);
+ buf.append(' ');
+ if (appName != null) {
+ buf.append(appName);
+ } else if (configName != null) {
+ buf.append(configName);
+ } else {
+ buf.append("-");
+ }
+ buf.append(" ");
+ buf.append(getProcId());
+ buf.append(" ");
+ String type = isStructured ? ((StructuredDataMessage) msg).getType() : null;
+ if (type != null) {
+ buf.append(type);
+ } else if (messageId != null) {
+ buf.append(messageId);
+ } else {
+ buf.append("-");
+ }
+ buf.append(" ");
+ if (isStructured) {
+ StructuredDataMessage data = (StructuredDataMessage) msg;
+ Map map = data.getData();
+ StructuredDataId id = data.getId();
+ formatStructuredElement(id, map, buf);
+ if (includeMDC)
+ {
+ int ein = id.getEnterpriseNumber() < 0 ? enterpriseNumber : id.getEnterpriseNumber();
+ StructuredDataId mdcSDID = new StructuredDataId(mdcId, ein, null, null);
+ formatStructuredElement(mdcSDID, event.getContextMap(), buf);
+ }
+ String text = data.getMessageFormat();
+ if (text != null && text.length() > 0) {
+ buf.append(" ").append(text);
+ }
+ } else {
+ buf.append("- ");
+ buf.append(event.getMessage().getFormattedMessage());
+ }
+ if (includeNewLine) {
+ buf.append("\n");
+ }
+ return buf.toString().getBytes(charset);
+ }
+
+ protected String getProcId() {
+ return "-";
+ }
+
+ /**
+ * This method gets the network name of the machine we are running on.
+ * Returns "UNKNOWN_LOCALHOST" in the unlikely case where the host name
+ * cannot be found.
+ *
+ * @return String the name of the local host
+ */
+ public String getLocalHostname() {
+ try {
+ InetAddress addr = InetAddress.getLocalHost();
+ return addr.getHostName();
+ } catch (UnknownHostException uhe) {
+ logger.error("Could not determine local host name", uhe);
+ return "UNKNOWN_LOCALHOST";
+ }
+ }
+
+ private String computeTimeStampString(long now) {
+ long last;
+ synchronized (this) {
+ last = lastTimestamp;
+ if (now == lastTimestamp) {
+ return timestamppStr;
+ }
+ }
+
+ StringBuilder buf = new StringBuilder();
+ Calendar cal = new GregorianCalendar();
+ cal.setTimeInMillis(now);
+ buf.append(Integer.toString(cal.get(Calendar.YEAR)));
+ buf.append("-");
+ pad(cal.get(Calendar.MONTH) + 1, 10, buf);
+ buf.append("-");
+ pad(cal.get(Calendar.DAY_OF_MONTH), 10, buf);
+ buf.append("T");
+ pad(cal.get(Calendar.HOUR_OF_DAY), 10, buf);
+ buf.append(":");
+ pad(cal.get(Calendar.MINUTE), 10, buf);
+ buf.append(":");
+ pad(cal.get(Calendar.SECOND), 10, buf);
+
+ int millis = cal.get(Calendar.MILLISECOND);
+ if (millis != 0) {
+ buf.append(".");
+ pad((int) ((float) millis / 10F), 100, buf);
+ }
+
+ int tzmin = (cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET)) / 60000;
+ if (tzmin == 0) {
+ buf.append("Z");
+ } else {
+ if (tzmin < 0) {
+ tzmin = -tzmin;
+ buf.append("-");
+ } else {
+ buf.append("+");
+ }
+ int tzhour = tzmin / 60;
+ tzmin -= tzhour * 60;
+ pad(tzhour, 10, buf);
+ buf.append(":");
+ pad(tzmin, 10, buf);
+ }
+ synchronized (this) {
+ if (last == lastTimestamp) {
+ lastTimestamp = now;
+ timestamppStr = buf.toString();
+ }
+ }
+ return buf.toString();
+ }
+
+ private void pad(int val, int max, StringBuilder buf) {
+ while (max > 1) {
+ if (val < max) {
+ buf.append("0");
+ }
+ max = max / 10;
+ }
+ buf.append(Integer.toString(val));
+ }
+
+ private void formatStructuredElement(StructuredDataId id, Map<String, Object> data, StringBuilder sb)
+ {
+ if (id == null && defaultId == null)
+ {
+ return;
+ }
+ sb.append("[");
+ sb.append(getId(id));
+ appendMap(data, sb);
+ sb.append("]");
+ }
+
+ private String getId(StructuredDataId id) {
+ StringBuilder sb = new StringBuilder();
+ if (id.getName() == null) {
+ sb.append(defaultId);
+ } else {
+ sb.append(id.getName());
+ }
+ int ein = id.getEnterpriseNumber();
+ if (ein < 0) {
+ ein = enterpriseNumber;
+ }
+ if (ein >=0) {
+ sb.append("@").append(ein);
+ }
+ return sb.toString();
+ }
+
+ private void appendMap(Map<String, Object> map, StringBuilder sb)
+ {
+ SortedMap<String, Object> sorted = new TreeMap<String, Object>(map);
+ for (Map.Entry<String, Object> entry : sorted.entrySet())
+ {
+ if (checker.check(entry.getKey())) {
+ sb.append(" ");
+ sb.append(entry.getKey()).append("=\"").append(entry.getValue()).append("\"");
+ }
+ }
+ }
+
+ private interface ListChecker {
+ boolean check(String key);
+ }
+
+ private class IncludeChecker implements ListChecker {
+ public boolean check(String key) {
+ return mdcIncludes.contains(key);
+ }
+ }
+
+ private class ExcludeChecker implements ListChecker {
+ public boolean check(String key) {
+ return !mdcExcludes.contains(key);
+ }
+ }
+
+ public class NoopChecker implements ListChecker {
+ public boolean check(String key) {
+ return true;
+ }
+ }
+
+ @PluginFactory
+ public static RFC5424Layout createLayout(@PluginAttr("facility") String facility,
+ @PluginAttr("id") String id,
+ @PluginAttr("enterpriseNumber") String ein,
+ @PluginAttr("includeMDC") String includeMDC,
+ @PluginAttr("mdcId") String mdcId,
+ @PluginAttr("newLine") String includeNL,
+ @PluginAttr("appName") String appName,
+ @PluginAttr("messageId") String msgId,
+ @PluginAttr("mdcExcludes") String excludes,
+ @PluginAttr("mdcINcludes") String includes,
+ @PluginAttr("charset") String charset) {
+ Charset c = Charset.isSupported("UTF-8") ? Charset.forName("UTF-8") : Charset.defaultCharset();
+ if (charset != null) {
+ if (Charset.isSupported(charset)) {
+ c = Charset.forName(charset);
+ } else {
+ logger.error("Charset " + charset + " is not supported for layout, using " + c.displayName());
+ }
+ }
+ if (includes != null && excludes != null) {
+ logger.error("mdcIncludes and mdcExcludes are mutually exclusive. Includes wil be ignored");
+ includes = null;
+ }
+ Facility f = facility != null ? Facility.valueOf(facility.toUpperCase()) : Facility.LOCAL0;
+ int enterpriseNumber = ein == null ? DEFAULT_ENTERPRISE_NUMBER : Integer.parseInt(ein);
+ boolean isMdc = includeMDC == null ? true : Boolean.valueOf(includeMDC);
+ boolean includeNewLine = includeNL == null ? false : Boolean.valueOf(includeNL);
+
+ return new RFC5424Layout(f, id, enterpriseNumber, isMdc, includeNewLine, mdcId, appName, msgId, excludes,
+ includes, c);
+ }
+}
Copied: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/SyslogLayout.java (from r1128132, logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/SerializedLayout.java)
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/SyslogLayout.java?p2=logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/SyslogLayout.java&p1=logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/SerializedLayout.java&r1=1128132&r2=1129003&rev=1129003&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/SerializedLayout.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/layout/SyslogLayout.java Mon May 30 06:02:07 2011
@@ -20,48 +20,106 @@ import org.apache.logging.log4j.core.Log
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttr;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
-import org.apache.logging.log4j.core.helpers.Transform;
+import org.apache.logging.log4j.core.net.Facility;
+import org.apache.logging.log4j.core.net.Priority;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.io.LineNumberReader;
-import java.io.ObjectOutputStream;
-import java.io.PrintWriter;
-import java.io.StringReader;
-import java.io.StringWriter;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
/**
*
*/
-@Plugin(name="SerializedLayout",type="Core",elementType="layout",printObject=true)
-public class SerializedLayout extends LayoutBase {
+@Plugin(name="SyslogLayout",type="Core",elementType="layout",printObject=true)
+public class SyslogLayout extends LayoutBase {
- public SerializedLayout() {
+ private final Charset charset;
+ private final Facility facility;
+ private final boolean includeNewLine;
+
+ /**
+ * Date format used if header = true.
+ */
+ private final SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd HH:mm:ss ", Locale.ENGLISH);
+ /**
+ * Host name used to identify messages from this appender.
+ */
+ private final String localHostname = getLocalHostname();
+
+
+ public SyslogLayout(Facility facility, boolean includeNL, Charset c) {
+ this.facility = facility;
+ this.header = header;
+ this.includeNewLine = includeNL;
+ this.charset = c;
}
/**
* Formats a {@link org.apache.logging.log4j.core.LogEvent} in conformance with the log4j.dtd.
*/
public byte[] format(final LogEvent event) {
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ StringBuilder buf = new StringBuilder();
+
+ buf.append("<");
+ buf.append(Priority.getPriority(facility, event.getLevel()));
+ buf.append(">");
+ addDate(event.getMillis(), buf);
+ buf.append(" ");
+ buf.append(localHostname);
+ buf.append(" ");
+ buf.append(event.getMessage().getFormattedMessage());
+ if (includeNewLine) {
+ buf.append("\n");
+ }
+ return buf.toString().getBytes(charset);
+ }
+
+ /**
+ * This method gets the network name of the machine we are running on.
+ * Returns "UNKNOWN_LOCALHOST" in the unlikely case where the host name
+ * cannot be found.
+ *
+ * @return String the name of the local host
+ */
+ private String getLocalHostname() {
try {
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- oos.writeObject(event);
- } catch (IOException ioe) {
- logger.error("Serialization of Logging Event failed.", ioe);
+ InetAddress addr = InetAddress.getLocalHost();
+ return addr.getHostName();
+ } catch (UnknownHostException uhe) {
+ logger.error("Could not determine local host name", uhe);
+ return "UNKNOWN_LOCALHOST";
+ }
+ }
+
+ private synchronized void addDate(final long timestamp, StringBuilder buf) {
+ int index = buf.length() + 4;
+ buf.append(dateFormat.format(new Date(timestamp)));
+ // RFC 3164 says leading space, not leading zero on days 1-9
+ if (buf.charAt(index) == '0') {
+ buf.setCharAt(index, ' ');
}
- return baos.toByteArray();
}
- @PluginFactory
- public static SerializedLayout createLayout() {
- return new SerializedLayout();
+ @PluginFactory
+ public static SyslogLayout createLayout(@PluginAttr("facility") String facility,
+ @PluginAttr("newLine") String includeNL,
+ @PluginAttr("charset") String charset) {
+
+ Charset c = Charset.isSupported("UTF-8") ? Charset.forName("UTF-8") : Charset.defaultCharset();
+ if (charset != null) {
+ if (Charset.isSupported(charset)) {
+ c = Charset.forName(charset);
+ } else {
+ logger.error("Charset " + charset + " is not supported for layout, using " + c.displayName());
+ }
+ }
+ boolean includeNewLine = includeNL == null ? false : Boolean.valueOf(includeNL);
+ Facility f = facility != null ? Facility.valueOf(facility.toUpperCase()) : Facility.LOCAL0;
+ return new SyslogLayout(f, includeNewLine, c);
}
}
Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/net/Facility.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/net/Facility.java?rev=1129003&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/net/Facility.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/net/Facility.java Mon May 30 06:02:07 2011
@@ -0,0 +1,74 @@
+package org.apache.logging.log4j.core.net;
+
+/**
+ * The facility codes used by the Syslog system.
+ *
+ * Numerical Facility<br>
+ * Code<br>
+ *
+ * 0 kernel messages<br>
+ * 1 user-level messages<br>
+ * 2 mail system<br>
+ * 3 system daemons<br>
+ * 4 security/authorization messages<br>
+ * 5 messages generated internally by syslogd<br>
+ * 6 line printer subsystem<br>
+ * 7 network news subsystem<br>
+ * 8 UUCP subsystem<br>
+ * 9 clock daemon<br>
+ * 10 security/authorization messages<br>
+ * 11 FTP daemon<br>
+ * 12 NTP subsystem<br>
+ * 13 log audit<br>
+ * 14 log alert<br>
+ * 15 clock daemon (note 2)<br>
+ * 16 local use 0 (local0)<br>
+ * 17 local use 1 (local1)<br>
+ * 18 local use 2 (local2)<br>
+ * 19 local use 3 (local3)<br>
+ * 20 local use 4 (local4)<br>
+ * 21 local use 5 (local5)<br>
+ * 22 local use 6 (local6)<br>
+ * 23 local use 7 (local7)<br>
+ */
+public enum Facility {
+ KERN(0),
+ USER(1),
+ MAIL(2),
+ DAEMON(3),
+ AUTH(4),
+ SYSLOG(5),
+ LPR(6),
+ NEWS(7),
+ UUCP(8),
+ CRON(9),
+ AUTHPRIV(10),
+ FTP(11),
+ NTP(12),
+ LOG_AUDIT(13),
+ LOG_ALERT(14),
+ CLOCK(15),
+ LOCAL0(16),
+ LOCAL1(17),
+ LOCAL2(18),
+ LOCAL3(19),
+ LOCAL4(20),
+ LOCAL5(21),
+ LOCAL6(22),
+ LOCAL7(23);
+
+ private final int code;
+
+ private Facility(int code) {
+ this.code = code;
+ }
+
+ public int getCode() {
+ return this.code;
+ }
+
+ public boolean equals(String name) {
+ return this.name().equalsIgnoreCase(name);
+ }
+
+}
Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/net/Priority.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/net/Priority.java?rev=1129003&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/net/Priority.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/net/Priority.java Mon May 30 06:02:07 2011
@@ -0,0 +1,53 @@
+/*
+ * 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.logging.log4j.core.net;
+
+import org.apache.logging.log4j.Level;
+
+/**
+ * The Priority used in the Syslog system. Calculated from the Facility and Severity values.
+ */
+public class Priority {
+
+ private final Facility facility;
+ private final Severity severity;
+
+ public Priority(Facility facility, Severity severity) {
+ this.facility = facility;
+ this.severity = severity;
+ }
+
+ public static int getPriority(Facility facility, Level level) {
+ return facility.getCode() << 3 + Severity.getSeverity(level).getCode();
+ }
+
+ public Facility getFacility() {
+ return facility;
+ }
+
+ public Severity getSeverity() {
+ return severity;
+ }
+
+ public int getValue() {
+ return facility.getCode() << 3 + severity.getCode();
+ }
+
+ public String toString() {
+ return Integer.toString(getValue());
+ }
+}
Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/net/Severity.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/net/Severity.java?rev=1129003&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/net/Severity.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/main/java/org/apache/logging/log4j/core/net/Severity.java Mon May 30 06:02:07 2011
@@ -0,0 +1,65 @@
+package org.apache.logging.log4j.core.net;
+
+import org.apache.logging.log4j.Level;
+
+/**
+ * Severity values used by the Syslog system
+ *
+ * Numerical Severity<br>
+ * Code<br>
+ *
+ * 0 Emergency: system is unusable<br>
+ * 1 Alert: action must be taken immediately<br>
+ * 2 Critical: critical conditions<br>
+ * 3 Error: error conditions<br>
+ * 4 Warning: warning conditions<br>
+ * 5 Notice: normal but significant condition<br>
+ * 6 Informational: informational messages<br>
+ * 7 Debug: debug-level messages
+ */
+public enum Severity {
+ EMERG(0),
+ ALERT(1),
+ CRITICAL(2),
+ ERROR(3),
+ WARNING(4),
+ NOTICE(5),
+ INFO(6),
+ DEBUG(7);
+
+ private final int code;
+
+ private Severity(int code) {
+ this.code = code;
+ }
+
+ public int getCode() {
+ return this.code;
+ }
+
+ public boolean equals(String name) {
+ return this.name().equalsIgnoreCase(name);
+ }
+
+ public static Severity getSeverity(Level level) {
+ switch (level) {
+ case ALL:
+ return DEBUG;
+ case TRACE:
+ return DEBUG;
+ case DEBUG:
+ return DEBUG;
+ case INFO:
+ return INFO;
+ case WARN:
+ return WARNING;
+ case ERROR:
+ return ERROR;
+ case FATAL:
+ return ALERT;
+ case OFF:
+ return EMERG;
+ }
+ return DEBUG;
+ }
+}
Copied: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/layout/RFC5424LayoutTest.java (from r1128132, logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/layout/XMLLayoutTest.java)
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/layout/RFC5424LayoutTest.java?p2=logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/layout/RFC5424LayoutTest.java&p1=logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/layout/XMLLayoutTest.java&r1=1128132&r2=1129003&rev=1129003&view=diff
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/layout/XMLLayoutTest.java (original)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/layout/RFC5424LayoutTest.java Mon May 30 06:02:07 2011
@@ -18,6 +18,7 @@ package org.apache.logging.log4j.core.la
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.MarkerManager;
import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.core.BasicConfigurationFactory;
import org.apache.logging.log4j.core.Logger;
@@ -25,21 +26,32 @@ import org.apache.logging.log4j.core.Log
import org.apache.logging.log4j.core.appender.ConsoleAppender;
import org.apache.logging.log4j.core.appender.ListAppender;
import org.apache.logging.log4j.core.config.ConfigurationFactory;
+import org.apache.logging.log4j.message.StructuredDataMessage;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.List;
+import java.util.Locale;
import static org.junit.Assert.assertTrue;
/**
*
*/
-public class XMLLayoutTest {
+public class RFC5424LayoutTest {
LoggerContext ctx = (LoggerContext) LogManager.getContext();
Logger root = ctx.getLogger("");
+
+ private static final String line1 = "ATM - - - starting mdc pattern test";
+ private static final String line2 = "ATM - - - empty mdc";
+ private static final String line3 = "ATM - - - filled mdc";
+ private static final String line4 =
+ "ATM - Audit [Transfer@18060 Amount=\"200.00\" FromAccount=\"123457\" ToAccount=\"123456\"]" +
+ "[RequestContext@18060 ipAddress=\"192.168.0.120\" locale=\"English (United States)\" " +
+ "loginId=\"JohnDoe\"] Transfer Complete";
+
static ConfigurationFactory cf = new BasicConfigurationFactory();
@BeforeClass
@@ -54,8 +66,7 @@ public class XMLLayoutTest {
ConfigurationFactory.removeConfigurationFactory(cf);
}
- private static final String body =
- "<log4j:message><![CDATA[empty mdc]]></log4j:message>\r";
+
/**
@@ -65,7 +76,8 @@ public class XMLLayoutTest {
public void testLayout() throws Exception {
// set up appender
- XMLLayout layout = XMLLayout.createLayout("true", "true", "true", null);
+ RFC5424Layout layout = RFC5424Layout.createLayout("Local0", "Event", "3692", "true", "RequestContext", "true",
+ "ATM", null, "key1, key2", null, null);
ListAppender appender = new ListAppender("List", null, layout, true, false);
appender.start();
@@ -83,18 +95,24 @@ public class XMLLayoutTest {
root.debug("filled mdc");
- ThreadContext.remove("key1");
- ThreadContext.remove("key2");
+ ThreadContext.put("loginId", "JohnDoe");
+ ThreadContext.put("ipAddress", "192.168.0.120");
+ ThreadContext.put("locale", Locale.US.getDisplayName());
+ StructuredDataMessage msg = new StructuredDataMessage("Transfer@18060", "Transfer Complete", "Audit");
+ msg.put("ToAccount", "123456");
+ msg.put("FromAccount", "123457");
+ msg.put("Amount", "200.00");
+ root.info(MarkerManager.getMarker("EVENT"), msg);
- root.error("finished mdc pattern test", new NullPointerException("test"));
+ ThreadContext.clear();
appender.stop();
List<String> list = appender.getMessages();
- assertTrue("Incorrect number of lines. Require at least 50 " + list.size(), list.size() > 50);
- assertTrue("Incorrect header", list.get(0).equals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r"));
- assertTrue("Incorrect footer", list.get(list.size() - 1).equals("</log4j:eventSet>\r"));
- assertTrue("Incorrect body. Expected " + body + " Actual: " + list.get(8), list.get(8).equals(body));
+ assertTrue("Expected line 1 to end with: " + line1 + " Actual " + list.get(0), list.get(0).endsWith(line1));
+ assertTrue("Expected line 2 to end with: " + line2 + " Actual " + list.get(1), list.get(1).endsWith(line2));
+ assertTrue("Expected line 3 to end with: " + line3 + " Actual " + list.get(2), list.get(2).endsWith(line3));
+ assertTrue("Expected line 4 to end with: " + line4 + " Actual " + list.get(3), list.get(3).endsWith(line4));
}
}
Added: logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/layout/SyslogLayoutTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/layout/SyslogLayoutTest.java?rev=1129003&view=auto
==============================================================================
--- logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/layout/SyslogLayoutTest.java (added)
+++ logging/log4j/branches/BRANCH_2_0_EXPERIMENTAL/rgoers/log4j2-core/src/test/java/org/apache/logging/log4j/core/layout/SyslogLayoutTest.java Mon May 30 06:02:07 2011
@@ -0,0 +1,116 @@
+/*
+ * 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.logging.log4j.core.layout;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.MarkerManager;
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.core.BasicConfigurationFactory;
+import org.apache.logging.log4j.core.Logger;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.appender.ConsoleAppender;
+import org.apache.logging.log4j.core.appender.ListAppender;
+import org.apache.logging.log4j.core.config.ConfigurationFactory;
+import org.apache.logging.log4j.message.StructuredDataMessage;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Locale;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ *
+ */
+public class SyslogLayoutTest {
+ LoggerContext ctx = (LoggerContext) LogManager.getContext();
+ Logger root = ctx.getLogger("");
+
+
+ private static final String line1 = "starting mdc pattern test";
+ private static final String line2 = "empty mdc";
+ private static final String line3 = "filled mdc";
+ private static final String line4 =
+ "Audit [Transfer@18060 Amount=\"200.00\" FromAccount=\"123457\" ToAccount=\"123456\"] Transfer Complete";
+
+ static ConfigurationFactory cf = new BasicConfigurationFactory();
+
+ @BeforeClass
+ public static void setupClass() {
+ ConfigurationFactory.setConfigurationFactory(cf);
+ LoggerContext ctx = (LoggerContext) LogManager.getContext();
+ ctx.reconfigure();
+ }
+
+ @AfterClass
+ public static void cleanupClass() {
+ ConfigurationFactory.removeConfigurationFactory(cf);
+ }
+
+
+
+
+ /**
+ * Test case for MDC conversion pattern.
+ */
+ @Test
+ public void testLayout() throws Exception {
+
+ // set up appender
+ SyslogLayout layout = SyslogLayout.createLayout("Local0", "true", null);
+ //ConsoleAppender appender = new ConsoleAppender("Console", layout);
+ ListAppender appender = new ListAppender("List", null, layout, true, false);
+ appender.start();
+
+ // set appender on root and set level to debug
+ root.addAppender(appender);
+ root.setLevel(Level.DEBUG);
+
+ // output starting message
+ root.debug("starting mdc pattern test");
+
+ root.debug("empty mdc");
+
+ ThreadContext.put("key1", "value1");
+ ThreadContext.put("key2", "value2");
+
+ root.debug("filled mdc");
+
+ ThreadContext.put("loginId", "JohnDoe");
+ ThreadContext.put("ipAddress", "192.168.0.120");
+ ThreadContext.put("locale", Locale.US.getDisplayName());
+ StructuredDataMessage msg = new StructuredDataMessage("Transfer@18060", "Transfer Complete", "Audit");
+ msg.put("ToAccount", "123456");
+ msg.put("FromAccount", "123457");
+ msg.put("Amount", "200.00");
+ root.info(MarkerManager.getMarker("EVENT"), msg);
+
+ ThreadContext.clear();
+
+ appender.stop();
+
+ List<String> list = appender.getMessages();
+
+ assertTrue("Expected line 1 to end with: " + line1 + " Actual " + list.get(0), list.get(0).endsWith(line1));
+ assertTrue("Expected line 2 to end with: " + line2 + " Actual " + list.get(1), list.get(1).endsWith(line2));
+ assertTrue("Expected line 3 to end with: " + line3 + " Actual " + list.get(2), list.get(2).endsWith(line3));
+ assertTrue("Expected line 4 to end with: " + line4 + " Actual " + list.get(3), list.get(3).endsWith(line4));
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org