Find attached an HTTPAppender. This is a RESTful appender that uses the
Atom Publishing protocol to post a log record.
/*
* Copyright 1999-2007 The Apache Software Foundation.
*
* Licensed 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.log4j.net;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import java.util.UUID;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.spi.LocationInfo;
import org.apache.log4j.spi.LoggingEvent;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Namespace;
import org.jdom.output.XMLOutputter;
/**
* This is a RESTful HTTP appender that POSTs an atom publishing protocol (APP)
* XML message to the URL specified in the logUrl parameter.
*
* @author Adrian Blakey
* TODO test https
*/
public class HTTPAppender extends AppenderSkeleton {
/**
* implemented to perform the logging, as per super class description
*/
protected void append(LoggingEvent event) {
if (url == null)
return;
try {
sendRequest(event); // Send it
} catch (IOException ioe) {
String errMsg = "An exception: "
+ ioe
+ " was thrown trying to send the resquest to the server URL: "
+ logURL;
LogLog.error(errMsg);
// throw new IllegalStateException(errMsg);
}
}
/**
* nop
*/
public synchronized void close() {
}
/**
* called by configurators - no layout required
*/
public boolean requiresLayout() {
return false;
}
/**
* overridden as per superclass description
*/
public void activateOptions() {
if (logURL == null) {
String errMsg = "The logURL option must be set for HTTPAppender named ["
+ name + "].";
LogLog.error(errMsg);
// throw new IllegalStateException(errMsg);
} else {
try {
url = new URL(logURL);
} catch (MalformedURLException e) {
String errMsg = "The URL [" + logURL
+ "] in the logURL option for HTTPAppender named ["
+ name + "] is not a proper URL.";
LogLog.error(errMsg);
// throw new IllegalStateException(errMsg);
}
}
cacheDomainname(); // cache our name
super.activateOptions();
}
/**
* Set the logURL property
*/
public void setLogURL(String logURL) {
this.logURL = logURL;
}
/**
* return logUrl
* @return logUrl
*/
public String getLogURL() {
return logURL;
}
/**
* sends the request
* @param event
*/
private void sendRequest(LoggingEvent event) throws IOException {
if (event == null)
return;
Namespace atom = Namespace.getNamespace("http://www.w3.org/2005/Atom");
Element entry = new Element("entry", atom);
Namespace logNs = Namespace.getNamespace("log",
"http://log4j.apache.org/2007/Log"); // local ns
entry.addNamespaceDeclaration(logNs);
Element title = new Element("title", atom);
title.setAttribute("type", "text");
title.setText("HTTPAppender log record");
entry.addContent(title);
Element id = new Element("id", atom);
id.setText("urn:uuid:" + UUID.randomUUID().toString());
entry.addContent(id);
Element updated = new Element("updated", atom); // current time
updated.setText(getDateAsISO8601String(new Date().getTime()));
entry.addContent(updated);
Element hostName = new Element("hostName", logNs);
hostName.setText(localHostname);
entry.addContent(hostName);
Element fqnOfCategoryClass = new Element("fqnOfCategoryClass", logNs);
fqnOfCategoryClass.setText(event.fqnOfCategoryClass);
entry.addContent(fqnOfCategoryClass);
Element name = new Element("loggerName", logNs);
name.setText(event.getLoggerName());
entry.addContent(name);
Element timeStamp = new Element("timeStamp", logNs);
timeStamp.setText(getDateAsISO8601String(event.timeStamp));
entry.addContent(timeStamp);
Element msg = new Element("msg", logNs);
msg.setText((String) event.getMessage());
entry.addContent(msg);
Element threadName = new Element("threadName", logNs);
threadName.setText(event.getThreadName());
entry.addContent(threadName);
Element ndc = new Element("ndc", logNs);
ndc.setText(event.getNDC());
entry.addContent(ndc);
Element level = new Element("level", logNs);
level.setText(event.getLevel().toString());
entry.addContent(level);
String[] s = event.getThrowableStrRep();
if (s != null) {
StringBuffer sb = new StringBuffer();
for (int j = 0; j < s.length; j++) {
sb.append(s[j]).append("\n");
}
sb.setLength(sb.length() - 1);
Element stackTrace = new Element("stackTrace", logNs);
stackTrace.setText(sb.toString());
entry.addContent(stackTrace);
}
LocationInfo li = event.getLocationInformation();
Element className = new Element("className", logNs);
className.setText(li.getClassName());
entry.addContent(className);
Element fileName = new Element("fileName", logNs);
fileName.setText(li.getFileName());
entry.addContent(fileName);
Element lineNumber = new Element("lineNumber", logNs);
lineNumber.setText(li.getLineNumber());
entry.addContent(lineNumber);
Element methodName = new Element("methodName", logNs);
methodName.setText(li.getMethodName());
entry.addContent(methodName);
Document doc = new Document(entry);
XMLOutputter serializer = new XMLOutputter();
postItem(serializer.outputString(doc));
}
/**
* helper to format a iso8601 date string. Converts a YYYYMMDDTHH:mm:ss+HH00
* into YYYYMMDDTHH:mm:ss+HH:00 - note the added colon for the Timezone
*
* @param date
* @return
*/
private String getDateAsISO8601String(long date) {
SimpleDateFormat ISO8601FORMAT = new SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US);
ISO8601FORMAT.setTimeZone(TimeZone.getTimeZone("GMT"));
String result = ISO8601FORMAT.format(date);
result = result.substring(0, result.length() - 2) + ":"
+ result.substring(result.length() - 2);
return result;
}
/**
* POST a request to the url
*
* @param xml
* @throws IOException
* if an I/O exception occurs while creating/writing/ reading
* the request
*/
public void postItem(String xml) throws IOException {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/atom+xml");
OutputStream outputStream = connection.getOutputStream();
outputStream.write(xml.getBytes());
outputStream.close();
int responseCode = connection.getResponseCode();
InputStream inputStream;
if (responseCode == HttpURLConnection.HTTP_CREATED) {
inputStream = connection.getInputStream();
} else {
inputStream = connection.getErrorStream();
LogLog.error(toString(inputStream));
}
if (inputStream != null) inputStream.close();
}
/**
* helper to get the network name of the machine we are running on.
* Returns "UNKNOWN_HOST" in the unlikely case where the host name cannot be
* found.
*
* @return String
*/
private void cacheDomainname() {
if (localHostname != null) return;
try {
InetAddress addr = InetAddress.getLocalHost();
localHostname = addr.getCanonicalHostName();
} catch (UnknownHostException uhe) {
LogLog.error("Could not determine local host name for HTTPAppender"
+ "named [" + name + "]. ", uhe);
localHostname = "UNKNOWN_HOST";
}
}
/**
* helper to write the response from the server
* @param inputStream
* @return
* @throws IOException
*/
private String toString(InputStream inputStream) throws IOException {
String string;
StringBuilder outputBuilder = new StringBuilder();
if (inputStream != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(
inputStream));
while (null != (string = reader.readLine())) {
outputBuilder.append(string).append('\n');
}
}
return outputBuilder.toString();
}
/**
* property the must be set in the log4j property file
*/
private String logURL;
/**
* the http/s URL to which the log is sent
*/
private URL url;
/**
* our hostname
*/
private String localHostname;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]