3 messages in org.apache.logging.log4j-userRE: Remote logging over HTTP
FromSent OnAttachments
Thomas MullerJun 10, 2004 3:27 am 
Ceki GülcüJun 10, 2004 3:33 am 
Thomas MullerJun 10, 2004 3:51 am 
Actions with this message:
Paste this link in email or IM:
Paste this link in email or IM:
Atom feed for this thread
Paste this URL into your reader:
Subject:RE: Remote logging over HTTPActions...
From:Thomas Muller (tt@online.no)
Date:Jun 10, 2004 3:51:53 am
List:org.apache.logging.log4j-user

Here's the code in raw text:

import java.net.*; import java.io.*; import java.util.*;

import org.apache.log4j.*; import org.apache.log4j.helpers.*; import org.apache.log4j.spi.*;

public class HTTPAppender extends AppenderSkeleton {

public static final int DEFAULT_BUFFER_SIZE = 50;

public static final int MIN_BUFFER_SIZE = 1; public static final int MAX_BUFFER_SIZE = 500;

protected String url;

protected URL scriptURL;

protected int bufferSize = DEFAULT_BUFFER_SIZE;

private final List eventBuffer = new LinkedList();

private final Object bufferMutex = new Object();

protected void append( LoggingEvent event ) { if( scriptURL == null ) { LogLog.error( "Missing property: url" ); return ; }

synchronized( bufferMutex ) { eventBuffer.add( event ); if( eventBuffer.size() >= bufferSize ) { sendRequest(); } } }

public void close() { // noop }

public boolean requiresLayout() { return false; }

public void activateOptions() { if( url != null ) { try { scriptURL = new URL( url ); if( ! scriptURL.getProtocol().equals( "http" ) ) { LogLog.error( "Protocol must be HTTP, not [" + scriptURL.getProtocol() + "]" ); scriptURL = null; } } catch( MalformedURLException e ) { LogLog.error( "Invalid URL assigned [" + url + "]" ); } } else { LogLog.error( "Missing property: url" ); } }

public void setURL( String url ) { this.url = url; }

public String getURL() { return url; }

public void setBufferSize( int bufferSize ) { this.bufferSize = Math.min( Math.max( MIN_BUFFER_SIZE, bufferSize ), MAX_BUFFER_SIZE ); }

public int getBufferSize() { return bufferSize; }

private void sendRequest() { ObjectOutputStream objOut = null; ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); try { objOut = new ObjectOutputStream( byteOut ); } catch( IOException cantHappen ) { throw new Error( cantHappen ); }

for( Iterator eventIterator = eventBuffer.iterator(); eventIterator.hasNext(); ) { LoggingEvent event = ( LoggingEvent ) eventIterator.next(); try { objOut.writeObject( event ); } catch( Exception e ) { LogLog.error( "Error writing LoggingEvent [" + event + "]", e ); } } eventBuffer.clear();

byte[] byteArray = byteOut.toByteArray();

try { HttpURLConnection connection = ( HttpURLConnection ) scriptURL.openConnection();

// Post message connection.setRequestMethod( "POST" ); connection.setDoOutput( true );

connection.setRequestProperty( "Content-Length", String.valueOf( byteArray.length ) );

connection.connect();

// Write post string OutputStream out = connection.getOutputStream(); out.write( byteArray ); out.flush(); out.close();

int responseCode = connection.getResponseCode(); if( responseCode != HttpURLConnection.HTTP_OK ) { LogLog.error( "HTTP response != HTTP_OK [" + responseCode + "]" ); } } catch( Exception e ) { LogLog.error( "Error POSTing [" + e.getMessage() + "]", e ); } }

}

import java.util.*; import java.io.*; import java.net.*;

import javax.servlet.*; import javax.servlet.http.*;

import org.apache.log4j.*; import org.apache.log4j.or.*; import org.apache.log4j.xml.*; import org.apache.log4j.spi.*;

public final class Log4jRemoteServlet extends HttpServlet {

private static final String GENERIC = "generic";

private static final Logger log = Logger.getLogger( Log4jRemoteServlet.class );

private static final ObjectRenderer REQ_RENDERER = new Renderers.HttpServletRequestRenderer();

private String baseDir; private String confDir; private String logDir;

private final Map hierarchyMap = new HashMap();

public void init( ServletConfig config ) throws ServletException { super.init( config ); baseDir = getServletContext().getRealPath( "/" );

if( baseDir == null ) { String msg = "Can't find base path"; log.error( msg ); throw new ServletException( msg ); }

String webinfDir = ( new File( baseDir, "WEB-INF" ) ).getAbsolutePath();

confDir = ( new File( webinfDir, "conf" ) ).getAbsolutePath();

logDir = ( new File( webinfDir, "log" ) ).getAbsolutePath();

log.debug( "Log4jRemoteServlet initialized" ); }

public void doPost( HttpServletRequest req, HttpServletResponse res ) throws ServletException, IOException {

String extraPathInfo = req.getPathInfo(); if( extraPathInfo == null ) { log.warn( "extraPathInfo missing" ); throw new ServletException( "Extra path-info missing in request" ); }

Hierarchy hierarchy = null;

synchronized( hierarchyMap ) { hierarchy = ( Hierarchy ) hierarchyMap.get( extraPathInfo ); if( hierarchy == null ) { log.info( "No hierarchy defined for client [" + extraPathInfo + "], creating new" ); hierarchyMap.put( extraPathInfo, hierarchy = configureHierarchy( extraPathInfo ) ); } }

ObjectInputStream objIn = new ObjectInputStream( req.getInputStream() );

for( ;; ) { try { LoggingEvent event = ( LoggingEvent ) objIn.readObject(); Logger remoteLogger = hierarchy.getLogger( event.getLoggerName() ); if( event.getLevel().isGreaterOrEqual(

remoteLogger.getEffectiveLevel() ) ) { remoteLogger.callAppenders( event ); } } catch( ClassNotFoundException e ) { log.error( e.getMessage(), e ); throw new ServletException( e.getMessage() );

} catch( EOFException e ) { break; } }

res.setStatus( HttpServletResponse.SC_OK ); res.flushBuffer(); }

public void log( String msg ) { log.info( msg ); }

public void log( String msg, Throwable t ) { log.info( msg, t ); }

public String getServletInfo() { return getClass().getName() + " version: " + "$Id$"; }

private synchronized Hierarchy configureHierarchy( String key ) throws ServletException { log.debug( "Configuring hierarchy key [" + key + "]" ); File configFile = new File( confDir, key + "-log4j.xml" ); if( ! configFile.exists() ) { log.debug( "Can't find Log4j XML file for [" + key + "]" ); configFile = new File( confDir, "generic-log4j.xml" ); }

Configurator configurator = new DOMConfigurator(); Hierarchy hierarchy = new Hierarchy( new RootCategory( Level.DEBUG ) );

URL url = null; try { url = configFile.toURI().toURL(); } catch( MalformedURLException e ) { throw new ServletException( e.getMessage() ); }

// Make log dir File logRoot = new File( logDir, key ); if( ! ( logRoot.exists() || logRoot.mkdir() ) ) { String msg = "Failed to create dir [" + logRoot + "]"; log.error( msg ); throw new ServletException( msg ); }

log.debug( "Configuring Log4j Hierarchy with [" + url + "]" );

System.setProperty( "log.root", logRoot.getAbsolutePath() ); configurator.doConfigure( url, hierarchy ); return hierarchy; }

}

-----Original Message----- From: Ceki Gülcü [mailto:ce@qos.ch] Sent: 10 June 2004 11:34 To: Log4J Users List Subject: Re: Remote logging over HTTP

Thomas,

The attachments did not make it. Pelase try sending your message to log4j-dev.

At 12:28 PM 6/10/2004, Thomas Muller wrote:

Log4j freaks,

Just wanted to share a couple of classes I've coded for remote logging over HTTP. I noticed that HTTPAppender used to be part of the API some versions ago, but this one used a non-serialization tehcnique to transfer the LoggingEvents.

The code is poorly documented but should be self-explanatory. I've used

ideas/code from org.apache.net's SocketAppender/SocketNode/SocketServer without scruple.

Feel free to use/demolish/disregard.

Regards,

--

Thomas

-- Ceki Gülcü

For log4j documentation consider "The complete log4j manual" ISBN: 2970036908 http://www.qos.ch/shop/products/clm_t.jsp