Refactoring jetty-centralized-logger to be more real-world.
* Moving jetty specific pieces out to jetty-webapp-logging so that the core logging implementation can exist in places such as JVM endorsed library paths and still function, without bringin in all of Jetty in the process. * Removing dependency on any jetty components from jetty-centralized-logging per reasons above. * Establishing jetty-webapp-logging as central place to house the webapp logging integration bits and pieces. git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@883 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
parent
576ee80d2a
commit
c148b97ffc
|
@ -50,33 +50,11 @@
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-webapp</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-deploy</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-api</artifactId>
|
<artifactId>slf4j-api</artifactId>
|
||||||
<version>1.5.6</version>
|
<version>1.5.6</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-simple</artifactId>
|
|
||||||
<version>1.5.6</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>jul-to-slf4j</artifactId>
|
|
||||||
<version>1.5.6</version>
|
|
||||||
</dependency>
|
|
||||||
-->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>jcl-over-slf4j</artifactId>
|
<artifactId>jcl-over-slf4j</artifactId>
|
||||||
|
|
|
@ -1,40 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
M2REPO=$HOME/.m2/repository
|
|
||||||
|
|
||||||
function jettydep()
|
|
||||||
{
|
|
||||||
echo "$M2REPO/org/eclipse/jetty/$1/7.0.1-SNAPSHOT/$1-7.0.1-SNAPSHOT.jar"
|
|
||||||
}
|
|
||||||
|
|
||||||
function slf4jdep()
|
|
||||||
{
|
|
||||||
echo "$M2REPO/org/slf4j/$1/1.5.6/$1-1.5.6.jar"
|
|
||||||
}
|
|
||||||
|
|
||||||
CP="target/classes:target/test-classes"
|
|
||||||
CP="$CP:"`jettydep "jetty-util"`
|
|
||||||
CP="$CP:"`jettydep "jetty-io"`
|
|
||||||
CP="$CP:"`jettydep "jetty-http"`
|
|
||||||
CP="$CP:"`jettydep "jetty-xml"`
|
|
||||||
CP="$CP:"`jettydep "jetty-server"`
|
|
||||||
CP="$CP:"`jettydep "jetty-security"`
|
|
||||||
CP="$CP:"`jettydep "jetty-servlet"`
|
|
||||||
CP="$CP:"`jettydep "jetty-webapp"`
|
|
||||||
CP="$CP:"`jettydep "jetty-deploy"`
|
|
||||||
CP="$CP:"`jettydep "jetty-continuation"`
|
|
||||||
CP="$CP:$M2REPO/javax/servlet/servlet-api/2.5/servlet-api-2.5.jar"
|
|
||||||
CP="$CP:"`slf4jdep "slf4j-api"`
|
|
||||||
CP="$CP:"`slf4jdep "jcl-over-slf4j"`
|
|
||||||
CP="$CP:"`slf4jdep "log4j-over-slf4j"`
|
|
||||||
CP="$CP:$M2REPO/junit/junit/3.8.2/junit-3.8.2.jar"
|
|
||||||
|
|
||||||
TESTBASEDIR=`pwd`
|
|
||||||
EXTRA=""
|
|
||||||
# EXTRA="-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"
|
|
||||||
|
|
||||||
java -cp $CP $EXTRA \
|
|
||||||
"-Dbasedir=$TESTBASEDIR" \
|
|
||||||
junit.textui.TestRunner \
|
|
||||||
org.eclipse.jetty.logging.CentralizedLoggingTest
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ public class CentralLoggerFactory implements ILoggerFactory
|
||||||
{
|
{
|
||||||
this.root = root;
|
this.root = root;
|
||||||
this.loggers = new HashMap<String, CentralLogger>();
|
this.loggers = new HashMap<String, CentralLogger>();
|
||||||
|
JavaUtilLoggingRouting.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRoot(CentralLoggerConfig root)
|
public void setRoot(CentralLoggerConfig root)
|
||||||
|
|
|
@ -13,89 +13,19 @@
|
||||||
//
|
//
|
||||||
// You may elect to redistribute this code under either of these licenses.
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
package org.eclipse.jetty.logging;
|
package org.eclipse.jetty.logging.impl;
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.MissingResourceException;
|
import java.util.MissingResourceException;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
import org.eclipse.jetty.logging.impl.CentralLoggerConfig;
|
|
||||||
import org.eclipse.jetty.util.IO;
|
|
||||||
import org.eclipse.jetty.util.log.Log;
|
|
||||||
import org.eclipse.jetty.util.log.Slf4jLog;
|
|
||||||
import org.eclipse.jetty.webapp.Configuration;
|
|
||||||
import org.eclipse.jetty.webapp.WebAppContext;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WebAppContext {@link Configuration} for Centralized Logging.
|
* Setup Routing in {@link java.util.logging.LogManager} to Centralized Logger.
|
||||||
*/
|
*/
|
||||||
public class CentralizedWebAppLoggingConfiguration implements Configuration
|
public class JavaUtilLoggingRouting
|
||||||
{
|
{
|
||||||
private static boolean loggerConfigured = false;
|
public static void init()
|
||||||
|
|
||||||
public static CentralLoggerConfig getLoggerRoot()
|
|
||||||
{
|
{
|
||||||
loggerConfigured = true;
|
|
||||||
return org.slf4j.impl.StaticLoggerBinder.getSingleton().getRoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isLoggerConfigured()
|
|
||||||
{
|
|
||||||
return loggerConfigured;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setConfiguredLoggerRoot(CentralLoggerConfig root)
|
|
||||||
{
|
|
||||||
loggerConfigured = true;
|
|
||||||
org.slf4j.impl.StaticLoggerBinder.getSingleton().setRoot(root);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Reset jetty logger.
|
|
||||||
Slf4jLog jettyLogger = new Slf4jLog();
|
|
||||||
Log.setLog(jettyLogger);
|
|
||||||
}
|
|
||||||
catch (Exception ignore)
|
|
||||||
{
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setLoggerConfigurationFilename(String filename) throws IOException
|
|
||||||
{
|
|
||||||
FileInputStream stream = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
stream = new FileInputStream(filename);
|
|
||||||
CentralLoggerConfig root = CentralLoggerConfig.load(stream);
|
|
||||||
setConfiguredLoggerRoot(root);
|
|
||||||
loggerConfigured = true;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
IO.close(stream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void configure(WebAppContext context) throws Exception
|
|
||||||
{
|
|
||||||
context.addSystemClass("org.apache.log4j.");
|
|
||||||
context.addSystemClass("org.slf4j.");
|
|
||||||
context.addSystemClass("org.apache.commons.logging.");
|
|
||||||
|
|
||||||
initializeJavaUtilLogRouting();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean javaUtilLoggingInitialized = false;
|
|
||||||
|
|
||||||
private static void initializeJavaUtilLogRouting()
|
|
||||||
{
|
|
||||||
if (javaUtilLoggingInitialized)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get root logger.
|
// Get root logger.
|
||||||
java.util.logging.Logger rootLogger = java.util.logging.Logger.getLogger("");
|
java.util.logging.Logger rootLogger = java.util.logging.Logger.getLogger("");
|
||||||
|
|
||||||
|
@ -229,22 +159,5 @@ public class CentralizedWebAppLoggingConfiguration implements Configuration
|
||||||
|
|
||||||
// Tweak levels.
|
// Tweak levels.
|
||||||
rootLogger.setLevel(java.util.logging.Level.ALL);
|
rootLogger.setLevel(java.util.logging.Level.ALL);
|
||||||
|
|
||||||
javaUtilLoggingInitialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deconfigure(WebAppContext context) throws Exception
|
|
||||||
{
|
|
||||||
/* do nothing */
|
|
||||||
}
|
|
||||||
|
|
||||||
public void postConfigure(WebAppContext context) throws Exception
|
|
||||||
{
|
|
||||||
/* do nothing */
|
|
||||||
}
|
|
||||||
|
|
||||||
public void preConfigure(WebAppContext context) throws Exception
|
|
||||||
{
|
|
||||||
/* do nothing */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -13,7 +13,7 @@
|
||||||
//
|
//
|
||||||
// You may elect to redistribute this code under either of these licenses.
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
package org.eclipse.jetty.logging;
|
package org.eclipse.jetty.logging.impl;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic System Property string expansion "${user.home}"
|
* Basic System Property string expansion "${user.home}"
|
|
@ -21,8 +21,7 @@ import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import org.eclipse.jetty.logging.PropertyExpansion;
|
import org.eclipse.jetty.logging.impl.io.RolloverFileOutputStream;
|
||||||
import org.eclipse.jetty.util.RolloverFileOutputStream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rolling File Appender
|
* Rolling File Appender
|
||||||
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) Webtide LLC
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// All rights reserved. This program and the accompanying materials
|
||||||
|
// are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
// and Apache License v2.0 which accompanies this distribution.
|
||||||
|
//
|
||||||
|
// The Eclipse Public License is available at
|
||||||
|
// http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
//
|
||||||
|
// The Apache License v2.0 is available at
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||||
|
//
|
||||||
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
|
// ========================================================================
|
||||||
|
package org.eclipse.jetty.logging.impl.io;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.io.Writer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simplified IO for logging reasons only.
|
||||||
|
*/
|
||||||
|
public class LogIO
|
||||||
|
{
|
||||||
|
public static void close(InputStream stream)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (stream != null)
|
||||||
|
stream.close();
|
||||||
|
}
|
||||||
|
catch (IOException ignore)
|
||||||
|
{
|
||||||
|
/* ignore */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void close(OutputStream stream)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (stream != null)
|
||||||
|
stream.close();
|
||||||
|
}
|
||||||
|
catch (IOException ignore)
|
||||||
|
{
|
||||||
|
/* ignore */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void close(Reader reader)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (reader != null)
|
||||||
|
reader.close();
|
||||||
|
}
|
||||||
|
catch (IOException ignore)
|
||||||
|
{
|
||||||
|
/* ignore */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void close(Writer writer)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (writer != null)
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
catch (IOException ignore)
|
||||||
|
{
|
||||||
|
/* ignore */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void copy(Reader in, Writer out) throws IOException
|
||||||
|
{
|
||||||
|
final int bufferSize = 8096;
|
||||||
|
char buffer[] = new char[bufferSize];
|
||||||
|
int len = bufferSize;
|
||||||
|
|
||||||
|
if (out instanceof PrintWriter)
|
||||||
|
{
|
||||||
|
PrintWriter pout = (PrintWriter)out;
|
||||||
|
while (!pout.checkError())
|
||||||
|
{
|
||||||
|
len = in.read(buffer,0,bufferSize);
|
||||||
|
if (len == -1)
|
||||||
|
break;
|
||||||
|
out.write(buffer,0,len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
len = in.read(buffer,0,bufferSize);
|
||||||
|
if (len == -1)
|
||||||
|
break;
|
||||||
|
out.write(buffer,0,len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toString(Reader in) throws IOException
|
||||||
|
{
|
||||||
|
StringWriter writer = new StringWriter();
|
||||||
|
copy(in,writer);
|
||||||
|
return writer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,330 @@
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 2006-2009 Mort Bay Consulting Pty. Ltd.
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// All rights reserved. This program and the accompanying materials
|
||||||
|
// are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
// and Apache License v2.0 which accompanies this distribution.
|
||||||
|
// The Eclipse Public License is available at
|
||||||
|
// http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
// The Apache License v2.0 is available at
|
||||||
|
// http://www.opensource.org/licenses/apache2.0.php
|
||||||
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
|
// ========================================================================
|
||||||
|
|
||||||
|
package org.eclipse.jetty.logging.impl.io;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.FilterOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log specific RolloverFileOutputStream
|
||||||
|
*
|
||||||
|
* This output stream puts content in a file that is rolled over every 24 hours. The filename must include the string
|
||||||
|
* "yyyy_mm_dd", which is replaced with the actual date when creating and rolling over the file.
|
||||||
|
*
|
||||||
|
* Old files are retained for a number of days before being deleted.
|
||||||
|
*/
|
||||||
|
public class RolloverFileOutputStream extends FilterOutputStream
|
||||||
|
{
|
||||||
|
private static Timer __rollover;
|
||||||
|
|
||||||
|
final static String YYYY_MM_DD="yyyy_mm_dd";
|
||||||
|
final static String ROLLOVER_FILE_DATE_FORMAT = "yyyy_MM_dd";
|
||||||
|
final static String ROLLOVER_FILE_BACKUP_FORMAT = "HHmmssSSS";
|
||||||
|
final static int ROLLOVER_FILE_RETAIN_DAYS = 31;
|
||||||
|
|
||||||
|
private RollTask _rollTask;
|
||||||
|
private SimpleDateFormat _fileBackupFormat;
|
||||||
|
private SimpleDateFormat _fileDateFormat;
|
||||||
|
|
||||||
|
private String _filename;
|
||||||
|
private File _file;
|
||||||
|
private boolean _append;
|
||||||
|
private int _retainDays;
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @param filename The filename must include the string "yyyy_mm_dd",
|
||||||
|
* which is replaced with the actual date when creating and rolling over the file.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public RolloverFileOutputStream(String filename)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
this(filename,true,ROLLOVER_FILE_RETAIN_DAYS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @param filename The filename must include the string "yyyy_mm_dd",
|
||||||
|
* which is replaced with the actual date when creating and rolling over the file.
|
||||||
|
* @param append If true, existing files will be appended to.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public RolloverFileOutputStream(String filename, boolean append)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
this(filename,append,ROLLOVER_FILE_RETAIN_DAYS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @param filename The filename must include the string "yyyy_mm_dd",
|
||||||
|
* which is replaced with the actual date when creating and rolling over the file.
|
||||||
|
* @param append If true, existing files will be appended to.
|
||||||
|
* @param retainDays The number of days to retain files before deleting them. 0 to retain forever.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public RolloverFileOutputStream(String filename,
|
||||||
|
boolean append,
|
||||||
|
int retainDays)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
this(filename,append,retainDays,TimeZone.getDefault());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @param filename The filename must include the string "yyyy_mm_dd",
|
||||||
|
* which is replaced with the actual date when creating and rolling over the file.
|
||||||
|
* @param append If true, existing files will be appended to.
|
||||||
|
* @param retainDays The number of days to retain files before deleting them. 0 to retain forever.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public RolloverFileOutputStream(String filename,
|
||||||
|
boolean append,
|
||||||
|
int retainDays,
|
||||||
|
TimeZone zone)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
|
||||||
|
this(filename,append,retainDays,zone,null,null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
* @param filename The filename must include the string "yyyy_mm_dd",
|
||||||
|
* which is replaced with the actual date when creating and rolling over the file.
|
||||||
|
* @param append If true, existing files will be appended to.
|
||||||
|
* @param retainDays The number of days to retain files before deleting them. 0 to retain forever.
|
||||||
|
* @param dateFormat The format for the date file substitution. The default is "yyyy_MM_dd".
|
||||||
|
* @param backupFormat The format for the file extension of backup files. The default is "HHmmssSSS".
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public RolloverFileOutputStream(String filename,
|
||||||
|
boolean append,
|
||||||
|
int retainDays,
|
||||||
|
TimeZone zone,
|
||||||
|
String dateFormat,
|
||||||
|
String backupFormat)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
super(null);
|
||||||
|
|
||||||
|
if (dateFormat==null)
|
||||||
|
dateFormat=ROLLOVER_FILE_DATE_FORMAT;
|
||||||
|
_fileDateFormat = new SimpleDateFormat(dateFormat);
|
||||||
|
|
||||||
|
if (backupFormat==null)
|
||||||
|
backupFormat=ROLLOVER_FILE_BACKUP_FORMAT;
|
||||||
|
_fileBackupFormat = new SimpleDateFormat(backupFormat);
|
||||||
|
|
||||||
|
_fileBackupFormat.setTimeZone(zone);
|
||||||
|
_fileDateFormat.setTimeZone(zone);
|
||||||
|
|
||||||
|
if (filename!=null)
|
||||||
|
{
|
||||||
|
filename=filename.trim();
|
||||||
|
if (filename.length()==0)
|
||||||
|
filename=null;
|
||||||
|
}
|
||||||
|
if (filename==null)
|
||||||
|
throw new IllegalArgumentException("Invalid filename");
|
||||||
|
|
||||||
|
_filename=filename;
|
||||||
|
_append=append;
|
||||||
|
_retainDays=retainDays;
|
||||||
|
setFile();
|
||||||
|
|
||||||
|
synchronized(RolloverFileOutputStream.class)
|
||||||
|
{
|
||||||
|
if (__rollover==null)
|
||||||
|
__rollover=new Timer(RolloverFileOutputStream.class.getName(),true);
|
||||||
|
|
||||||
|
_rollTask=new RollTask();
|
||||||
|
|
||||||
|
Calendar now = Calendar.getInstance();
|
||||||
|
now.setTimeZone(zone);
|
||||||
|
|
||||||
|
GregorianCalendar midnight =
|
||||||
|
new GregorianCalendar(now.get(Calendar.YEAR),
|
||||||
|
now.get(Calendar.MONTH),
|
||||||
|
now.get(Calendar.DAY_OF_MONTH),
|
||||||
|
23,0);
|
||||||
|
midnight.setTimeZone(zone);
|
||||||
|
midnight.add(Calendar.HOUR,1);
|
||||||
|
__rollover.scheduleAtFixedRate(_rollTask,midnight.getTime(),1000L*60*60*24);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public String getFilename()
|
||||||
|
{
|
||||||
|
return _filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public String getDatedFilename()
|
||||||
|
{
|
||||||
|
if (_file==null)
|
||||||
|
return null;
|
||||||
|
return _file.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
public int getRetainDays()
|
||||||
|
{
|
||||||
|
return _retainDays;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
private synchronized void setFile()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
// Check directory
|
||||||
|
File file = new File(_filename);
|
||||||
|
_filename=file.getCanonicalPath();
|
||||||
|
file=new File(_filename);
|
||||||
|
File dir= new File(file.getParent());
|
||||||
|
if (!dir.isDirectory() || !dir.canWrite())
|
||||||
|
throw new IOException("Cannot write log directory "+dir);
|
||||||
|
|
||||||
|
Date now=new Date();
|
||||||
|
|
||||||
|
// Is this a rollover file?
|
||||||
|
String filename=file.getName();
|
||||||
|
int i=filename.toLowerCase().indexOf(YYYY_MM_DD);
|
||||||
|
if (i>=0)
|
||||||
|
{
|
||||||
|
file=new File(dir,
|
||||||
|
filename.substring(0,i)+
|
||||||
|
_fileDateFormat.format(now)+
|
||||||
|
filename.substring(i+YYYY_MM_DD.length()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.exists()&&!file.canWrite())
|
||||||
|
throw new IOException("Cannot write log file "+file);
|
||||||
|
|
||||||
|
// Do we need to change the output stream?
|
||||||
|
if (out==null || !file.equals(_file))
|
||||||
|
{
|
||||||
|
// Yep
|
||||||
|
_file=file;
|
||||||
|
if (!_append && file.exists())
|
||||||
|
file.renameTo(new File(file.toString()+"."+_fileBackupFormat.format(now)));
|
||||||
|
OutputStream oldOut=out;
|
||||||
|
out=new FileOutputStream(file.toString(),_append);
|
||||||
|
if (oldOut!=null)
|
||||||
|
oldOut.close();
|
||||||
|
//if(log.isDebugEnabled())log.debug("Opened "+_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
private void removeOldFiles()
|
||||||
|
{
|
||||||
|
if (_retainDays>0)
|
||||||
|
{
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
|
||||||
|
File file= new File(_filename);
|
||||||
|
File dir = new File(file.getParent());
|
||||||
|
String fn=file.getName();
|
||||||
|
int s=fn.toLowerCase().indexOf(YYYY_MM_DD);
|
||||||
|
if (s<0)
|
||||||
|
return;
|
||||||
|
String prefix=fn.substring(0,s);
|
||||||
|
String suffix=fn.substring(s+YYYY_MM_DD.length());
|
||||||
|
|
||||||
|
String[] logList=dir.list();
|
||||||
|
for (int i=0;i<logList.length;i++)
|
||||||
|
{
|
||||||
|
fn = logList[i];
|
||||||
|
if(fn.startsWith(prefix)&&fn.indexOf(suffix,prefix.length())>=0)
|
||||||
|
{
|
||||||
|
File f = new File(dir,fn);
|
||||||
|
long date = f.lastModified();
|
||||||
|
if ( ((now-date)/(1000*60*60*24))>_retainDays)
|
||||||
|
f.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
|
public void write (byte[] buf)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
out.write (buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
@Override
|
||||||
|
public void write (byte[] buf, int off, int len)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
out.write (buf, off, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void close()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
synchronized(RolloverFileOutputStream.class)
|
||||||
|
{
|
||||||
|
try{super.close();}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
out=null;
|
||||||
|
_file=null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_rollTask.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
/* ------------------------------------------------------------ */
|
||||||
|
private class RollTask extends TimerTask
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
RolloverFileOutputStream.this.setFile();
|
||||||
|
RolloverFileOutputStream.this.removeOldFiles();
|
||||||
|
|
||||||
|
}
|
||||||
|
catch(IOException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,9 +18,9 @@ package org.eclipse.jetty.logging;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import junit.framework.TestCase;
|
import org.eclipse.jetty.logging.impl.io.LogIO;
|
||||||
|
|
||||||
import org.eclipse.jetty.util.IO;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common utility methods for working with JUnit tests cases in a maven friendly way.
|
* Common utility methods for working with JUnit tests cases in a maven friendly way.
|
||||||
|
@ -30,7 +30,6 @@ public class MavenTestingUtils
|
||||||
private static File basedir;
|
private static File basedir;
|
||||||
private static File testResourcesDir;
|
private static File testResourcesDir;
|
||||||
private static File targetDir;
|
private static File targetDir;
|
||||||
private static Boolean surefireRunning;
|
|
||||||
|
|
||||||
public static File getBasedir()
|
public static File getBasedir()
|
||||||
{
|
{
|
||||||
|
@ -168,29 +167,11 @@ public class MavenTestingUtils
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
reader = new FileReader(file);
|
reader = new FileReader(file);
|
||||||
return IO.toString(reader);
|
return LogIO.toString(reader);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
IO.close(reader);
|
LogIO.close(reader);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSurefireExecuting()
|
|
||||||
{
|
|
||||||
if (surefireRunning == null)
|
|
||||||
{
|
|
||||||
String val = System.getProperty("surefire.test.class.path");
|
|
||||||
if (val != null)
|
|
||||||
{
|
|
||||||
surefireRunning = Boolean.TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
surefireRunning = Boolean.FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return surefireRunning;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,9 @@ import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.logging.impl.Appender;
|
||||||
|
import org.eclipse.jetty.logging.impl.Severity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test Appender, records the logging events.
|
* Test Appender, records the logging events.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,155 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) Webtide LLC
|
||||||
|
//
|
||||||
|
// All rights reserved. This program and the accompanying materials
|
||||||
|
// are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
// and Apache License v2.0 which accompanies this distribution.
|
||||||
|
//
|
||||||
|
// The Eclipse Public License is available at
|
||||||
|
// http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
//
|
||||||
|
// The Apache License v2.0 is available at
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||||
|
//
|
||||||
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
|
// ========================================================================
|
||||||
|
-->
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-project</artifactId>
|
||||||
|
<version>7.0.1-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-webapp-logging</artifactId>
|
||||||
|
<name>Jetty :: Centralized WebApp Logging</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<forkMode>always</forkMode>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<descriptors>
|
||||||
|
<descriptor>config.xml</descriptor>
|
||||||
|
</descriptors>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-centralized-logging</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-webapp</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-deploy</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<reporting>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-project-info-reports-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jxr-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>cobertura-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</reporting>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>copy-fresh-webapps</id>
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy-testing-wars</id>
|
||||||
|
<phase>validate</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<artifactItems>
|
||||||
|
<artifactItem>
|
||||||
|
<groupId>org.eclipse.jetty.tests</groupId>
|
||||||
|
<artifactId>dummy-webapp-logging-commons</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<type>war</type>
|
||||||
|
</artifactItem>
|
||||||
|
<artifactItem>
|
||||||
|
<groupId>org.eclipse.jetty.tests</groupId>
|
||||||
|
<artifactId>dummy-webapp-logging-java</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<type>war</type>
|
||||||
|
</artifactItem>
|
||||||
|
<artifactItem>
|
||||||
|
<groupId>org.eclipse.jetty.tests</groupId>
|
||||||
|
<artifactId>dummy-webapp-logging-log4j</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<type>war</type>
|
||||||
|
</artifactItem>
|
||||||
|
<artifactItem>
|
||||||
|
<groupId>org.eclipse.jetty.tests</groupId>
|
||||||
|
<artifactId>dummy-webapp-logging-slf4j</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<type>war</type>
|
||||||
|
</artifactItem>
|
||||||
|
</artifactItems>
|
||||||
|
<outputDirectory>${basedir}/src/test/resources/webapps</outputDirectory>
|
||||||
|
<overWriteIfNewer>true</overWriteIfNewer>
|
||||||
|
<stripVersion>true</stripVersion>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
</project>
|
|
@ -13,7 +13,7 @@
|
||||||
//
|
//
|
||||||
// You may elect to redistribute this code under either of these licenses.
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
package org.eclipse.jetty.logging;
|
package org.eclipse.jetty.webapp.logging;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
|
@ -0,0 +1,98 @@
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) Webtide LLC
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// All rights reserved. This program and the accompanying materials
|
||||||
|
// are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
// and Apache License v2.0 which accompanies this distribution.
|
||||||
|
//
|
||||||
|
// The Eclipse Public License is available at
|
||||||
|
// http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
//
|
||||||
|
// The Apache License v2.0 is available at
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||||
|
//
|
||||||
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
|
// ========================================================================
|
||||||
|
package org.eclipse.jetty.webapp.logging;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.eclipse.jetty.logging.impl.CentralLoggerConfig;
|
||||||
|
import org.eclipse.jetty.util.IO;
|
||||||
|
import org.eclipse.jetty.util.log.Log;
|
||||||
|
import org.eclipse.jetty.util.log.Slf4jLog;
|
||||||
|
import org.eclipse.jetty.webapp.Configuration;
|
||||||
|
import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WebAppContext {@link Configuration} for Centralized Logging.
|
||||||
|
*/
|
||||||
|
public class CentralizedWebAppLoggingConfiguration implements Configuration
|
||||||
|
{
|
||||||
|
private static boolean loggerConfigured = false;
|
||||||
|
|
||||||
|
public static CentralLoggerConfig getLoggerRoot()
|
||||||
|
{
|
||||||
|
loggerConfigured = true;
|
||||||
|
return org.slf4j.impl.StaticLoggerBinder.getSingleton().getRoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isLoggerConfigured()
|
||||||
|
{
|
||||||
|
return loggerConfigured;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setConfiguredLoggerRoot(CentralLoggerConfig root)
|
||||||
|
{
|
||||||
|
loggerConfigured = true;
|
||||||
|
org.slf4j.impl.StaticLoggerBinder.getSingleton().setRoot(root);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Reset jetty logger.
|
||||||
|
Slf4jLog jettyLogger = new Slf4jLog();
|
||||||
|
Log.setLog(jettyLogger);
|
||||||
|
}
|
||||||
|
catch (Exception ignore)
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setLoggerConfigurationFilename(String filename) throws IOException
|
||||||
|
{
|
||||||
|
FileInputStream stream = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
stream = new FileInputStream(filename);
|
||||||
|
CentralLoggerConfig root = CentralLoggerConfig.load(stream);
|
||||||
|
setConfiguredLoggerRoot(root);
|
||||||
|
loggerConfigured = true;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IO.close(stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void configure(WebAppContext context) throws Exception
|
||||||
|
{
|
||||||
|
context.addSystemClass("org.apache.log4j.");
|
||||||
|
context.addSystemClass("org.slf4j.");
|
||||||
|
context.addSystemClass("org.apache.commons.logging.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deconfigure(WebAppContext context) throws Exception
|
||||||
|
{
|
||||||
|
/* do nothing */
|
||||||
|
}
|
||||||
|
|
||||||
|
public void postConfigure(WebAppContext context) throws Exception
|
||||||
|
{
|
||||||
|
/* do nothing */
|
||||||
|
}
|
||||||
|
|
||||||
|
public void preConfigure(WebAppContext context) throws Exception
|
||||||
|
{
|
||||||
|
/* do nothing */
|
||||||
|
}
|
||||||
|
}
|
9
jetty-webapp-logging/src/test/artifacts/dummy-webapp-logging-slf4j/.gitignore
vendored
Normal file
9
jetty-webapp-logging/src/test/artifacts/dummy-webapp-logging-slf4j/.gitignore
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
target/
|
||||||
|
.classpath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
*.swp
|
||||||
|
*.patch
|
||||||
|
*.diff
|
||||||
|
*.log
|
||||||
|
cobertura.ser
|
|
@ -13,7 +13,7 @@
|
||||||
//
|
//
|
||||||
// You may elect to redistribute this code under either of these licenses.
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
package org.eclipse.jetty.logging;
|
package org.eclipse.jetty.webapp.logging;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@ -21,8 +21,7 @@ import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.eclipse.jetty.logging.impl.CentralLoggerConfig;
|
import org.eclipse.jetty.logging.impl.CentralLoggerConfig;
|
||||||
import org.eclipse.jetty.logging.impl.Severity;
|
import org.eclipse.jetty.logging.impl.Severity;
|
||||||
import org.eclipse.jetty.logging.impl.TestAppender;
|
import org.eclipse.jetty.webapp.logging.TestAppender.LogEvent;
|
||||||
import org.eclipse.jetty.logging.impl.TestAppender.LogEvent;
|
|
||||||
|
|
||||||
public class CentralizedLoggingTest extends TestCase
|
public class CentralizedLoggingTest extends TestCase
|
||||||
{
|
{
|
||||||
|
@ -69,30 +68,12 @@ public class CentralizedLoggingTest extends TestCase
|
||||||
TestAppender testAppender = (TestAppender)root.findAppender(TestAppender.class);
|
TestAppender testAppender = (TestAppender)root.findAppender(TestAppender.class);
|
||||||
assertNotNull("Should have found TestAppender in configuration",testAppender);
|
assertNotNull("Should have found TestAppender in configuration",testAppender);
|
||||||
|
|
||||||
boolean isSurefireExecuting = MavenTestingUtils.isSurefireExecuting();
|
|
||||||
|
|
||||||
// HACK: causes failures within surefire.
|
|
||||||
if (!isSurefireExecuting)
|
|
||||||
{
|
|
||||||
SimpleRequest.get(jetty,"/dummy-webapp-logging-log4j/logging");
|
SimpleRequest.get(jetty,"/dummy-webapp-logging-log4j/logging");
|
||||||
SimpleRequest.get(jetty,"/dummy-webapp-logging-commons/logging");
|
SimpleRequest.get(jetty,"/dummy-webapp-logging-commons/logging");
|
||||||
}
|
|
||||||
|
|
||||||
SimpleRequest.get(jetty,"/dummy-webapp-logging-slf4j/logging");
|
SimpleRequest.get(jetty,"/dummy-webapp-logging-slf4j/logging");
|
||||||
SimpleRequest.get(jetty,"/dummy-webapp-logging-java/logging");
|
SimpleRequest.get(jetty,"/dummy-webapp-logging-java/logging");
|
||||||
|
|
||||||
TestAppender.LogEvent expectedLogs[];
|
TestAppender.LogEvent expectedLogs[] =
|
||||||
if (isSurefireExecuting)
|
|
||||||
{
|
|
||||||
expectedLogs = new LogEvent[]
|
|
||||||
{ new LogEvent(Severity.DEBUG,LOGGING_SERVLET_ID,"LoggingServlet(slf4j) initialized"),
|
|
||||||
new LogEvent(Severity.INFO,LOGGING_SERVLET_ID,"LoggingServlet(slf4j) GET requested"),
|
|
||||||
new LogEvent(Severity.DEBUG,LOGGING_SERVLET_ID,"LoggingServlet(java) initialized"),
|
|
||||||
new LogEvent(Severity.INFO,LOGGING_SERVLET_ID,"LoggingServlet(java) GET requested") };
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
expectedLogs = new LogEvent[]
|
|
||||||
{ new LogEvent(Severity.DEBUG,LOGGING_SERVLET_ID,"LoggingServlet(log4j) initialized"),
|
{ new LogEvent(Severity.DEBUG,LOGGING_SERVLET_ID,"LoggingServlet(log4j) initialized"),
|
||||||
new LogEvent(Severity.INFO,LOGGING_SERVLET_ID,"LoggingServlet(log4j) GET requested"),
|
new LogEvent(Severity.INFO,LOGGING_SERVLET_ID,"LoggingServlet(log4j) GET requested"),
|
||||||
new LogEvent(Severity.DEBUG,LOGGING_SERVLET_ID,"LoggingServlet(slf4j) initialized"),
|
new LogEvent(Severity.DEBUG,LOGGING_SERVLET_ID,"LoggingServlet(slf4j) initialized"),
|
||||||
|
@ -101,7 +82,6 @@ public class CentralizedLoggingTest extends TestCase
|
||||||
new LogEvent(Severity.INFO,LOGGING_SERVLET_ID,"LoggingServlet(commons-logging) GET requested"),
|
new LogEvent(Severity.INFO,LOGGING_SERVLET_ID,"LoggingServlet(commons-logging) GET requested"),
|
||||||
new LogEvent(Severity.DEBUG,LOGGING_SERVLET_ID,"LoggingServlet(java) initialized"),
|
new LogEvent(Severity.DEBUG,LOGGING_SERVLET_ID,"LoggingServlet(java) initialized"),
|
||||||
new LogEvent(Severity.INFO,LOGGING_SERVLET_ID,"LoggingServlet(java) GET requested") };
|
new LogEvent(Severity.INFO,LOGGING_SERVLET_ID,"LoggingServlet(java) GET requested") };
|
||||||
}
|
|
||||||
|
|
||||||
assertContainsLogEvents(testAppender,expectedLogs);
|
assertContainsLogEvents(testAppender,expectedLogs);
|
||||||
}
|
}
|
|
@ -13,7 +13,7 @@
|
||||||
//
|
//
|
||||||
// You may elect to redistribute this code under either of these licenses.
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
package org.eclipse.jetty.logging;
|
package org.eclipse.jetty.webapp.logging;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -23,8 +23,6 @@ import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.eclipse.jetty.logging.impl.CentralLoggerConfig;
|
import org.eclipse.jetty.logging.impl.CentralLoggerConfig;
|
||||||
import org.eclipse.jetty.logging.impl.Severity;
|
import org.eclipse.jetty.logging.impl.Severity;
|
||||||
import org.eclipse.jetty.logging.impl.TestAppender;
|
|
||||||
import org.eclipse.jetty.logging.impl.TestAppender.LogEvent;
|
|
||||||
import org.eclipse.jetty.server.Connector;
|
import org.eclipse.jetty.server.Connector;
|
||||||
import org.eclipse.jetty.server.Handler;
|
import org.eclipse.jetty.server.Handler;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
|
@ -32,6 +30,7 @@ import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||||
import org.eclipse.jetty.server.nio.SelectChannelConnector;
|
import org.eclipse.jetty.server.nio.SelectChannelConnector;
|
||||||
import org.eclipse.jetty.webapp.Configuration;
|
import org.eclipse.jetty.webapp.Configuration;
|
||||||
import org.eclipse.jetty.webapp.WebAppContext;
|
import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
|
import org.eclipse.jetty.webapp.logging.TestAppender.LogEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test centralized logging in an embedded scenario
|
* Test centralized logging in an embedded scenario
|
|
@ -0,0 +1,199 @@
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) Webtide LLC
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// All rights reserved. This program and the accompanying materials
|
||||||
|
// are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
// and Apache License v2.0 which accompanies this distribution.
|
||||||
|
//
|
||||||
|
// The Eclipse Public License is available at
|
||||||
|
// http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
//
|
||||||
|
// The Apache License v2.0 is available at
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||||
|
//
|
||||||
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
|
// ========================================================================
|
||||||
|
package org.eclipse.jetty.webapp.logging;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.util.IO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common utility methods for working with JUnit tests cases in a maven friendly way.
|
||||||
|
*/
|
||||||
|
public class MavenTestingUtils
|
||||||
|
{
|
||||||
|
private static File basedir;
|
||||||
|
private static File testResourcesDir;
|
||||||
|
private static File targetDir;
|
||||||
|
|
||||||
|
// private static Boolean surefireRunning;
|
||||||
|
|
||||||
|
public static File getBasedir()
|
||||||
|
{
|
||||||
|
if (basedir == null)
|
||||||
|
{
|
||||||
|
String cwd = System.getProperty("basedir");
|
||||||
|
|
||||||
|
if (cwd == null)
|
||||||
|
{
|
||||||
|
cwd = System.getProperty("user.dir");
|
||||||
|
}
|
||||||
|
|
||||||
|
basedir = new File(cwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return basedir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the directory to the /target directory for this project.
|
||||||
|
*
|
||||||
|
* @return the directory path to the target directory.
|
||||||
|
*/
|
||||||
|
public static File getTargetDir()
|
||||||
|
{
|
||||||
|
if (targetDir == null)
|
||||||
|
{
|
||||||
|
targetDir = new File(basedir,"target");
|
||||||
|
PathAssert.assertDirExists("Target Dir",targetDir);
|
||||||
|
}
|
||||||
|
return targetDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a {@link File} object for a path in the /target directory.
|
||||||
|
*
|
||||||
|
* @param path
|
||||||
|
* the path desired, no validation of existence is performed.
|
||||||
|
* @return the File to the path.
|
||||||
|
*/
|
||||||
|
public static File getTargetFile(String path)
|
||||||
|
{
|
||||||
|
return new File(getTargetDir(),path.replace("/",File.separator));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File getTargetTestingDir()
|
||||||
|
{
|
||||||
|
File dir = new File(getTargetDir(),"testing");
|
||||||
|
if (!dir.exists())
|
||||||
|
{
|
||||||
|
dir.mkdirs();
|
||||||
|
}
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static File getTargetTestingDir(TestCase test)
|
||||||
|
{
|
||||||
|
File dir = new File(getTargetDir(),"test-" + test.getName());
|
||||||
|
if (!dir.exists())
|
||||||
|
{
|
||||||
|
dir.mkdirs();
|
||||||
|
}
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a dir from the src/test/resource directory.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* the name of the path to get (it must exist as a dir)
|
||||||
|
* @return the dir in src/test/resource
|
||||||
|
*/
|
||||||
|
public static File getTestResourceDir(String name)
|
||||||
|
{
|
||||||
|
File dir = new File(getTestResourcesDir(),name);
|
||||||
|
PathAssert.assertDirExists("Test Resource Dir",dir);
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a file from the src/test/resource directory.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* the name of the path to get (it must exist as a file)
|
||||||
|
* @return the file in src/test/resource
|
||||||
|
*/
|
||||||
|
public static File getTestResourceFile(String name)
|
||||||
|
{
|
||||||
|
File file = new File(getTestResourcesDir(),name);
|
||||||
|
PathAssert.assertFileExists("Test Resource File",file);
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a path resource (File or Dir) from the src/test/resource directory.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* the name of the path to get (it must exist)
|
||||||
|
* @return the path in src/test/resource
|
||||||
|
*/
|
||||||
|
public static File getTestResourcePath(String name)
|
||||||
|
{
|
||||||
|
File path = new File(getTestResourcesDir(),name);
|
||||||
|
PathAssert.assertExists("Test Resource Path",path);
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the directory to the src/test/resource directory
|
||||||
|
*
|
||||||
|
* @return the directory {@link File} to the src/test/resources directory
|
||||||
|
*/
|
||||||
|
public static File getTestResourcesDir()
|
||||||
|
{
|
||||||
|
if (testResourcesDir == null)
|
||||||
|
{
|
||||||
|
testResourcesDir = new File(basedir,"src/test/resources".replace("/",File.separator));
|
||||||
|
PathAssert.assertDirExists("Test Resources Dir",testResourcesDir);
|
||||||
|
}
|
||||||
|
return testResourcesDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the contents of a file into a String and return it.
|
||||||
|
*
|
||||||
|
* @param file
|
||||||
|
* the file to read.
|
||||||
|
* @return the contents of the file.
|
||||||
|
* @throws IOException
|
||||||
|
* if unable to read the file.
|
||||||
|
*/
|
||||||
|
public static String readToString(File file) throws IOException
|
||||||
|
{
|
||||||
|
FileReader reader = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
reader = new FileReader(file);
|
||||||
|
return IO.toString(reader);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IO.close(reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
public static boolean isSurefireExecuting()
|
||||||
|
{
|
||||||
|
if (surefireRunning == null)
|
||||||
|
{
|
||||||
|
String val = System.getProperty("surefire.test.class.path");
|
||||||
|
if (val != null)
|
||||||
|
{
|
||||||
|
surefireRunning = Boolean.TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
surefireRunning = Boolean.FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return surefireRunning;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) Webtide LLC
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// All rights reserved. This program and the accompanying materials
|
||||||
|
// are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
// and Apache License v2.0 which accompanies this distribution.
|
||||||
|
//
|
||||||
|
// The Eclipse Public License is available at
|
||||||
|
// http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
//
|
||||||
|
// The Apache License v2.0 is available at
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||||
|
//
|
||||||
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
|
// ========================================================================
|
||||||
|
package org.eclipse.jetty.webapp.logging;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
public class PathAssert
|
||||||
|
{
|
||||||
|
public static void assertDirExists(String msg, File path)
|
||||||
|
{
|
||||||
|
assertExists(msg,path);
|
||||||
|
Assert.assertTrue(msg + " path should be a Dir : " + path.getAbsolutePath(),path.isDirectory());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void assertFileExists(String msg, File path)
|
||||||
|
{
|
||||||
|
assertExists(msg,path);
|
||||||
|
Assert.assertTrue(msg + " path should be a File : " + path.getAbsolutePath(),path.isFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void assertExists(String msg, File path)
|
||||||
|
{
|
||||||
|
Assert.assertTrue(msg + " path should exist: " + path.getAbsolutePath(),path.exists());
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,7 +13,7 @@
|
||||||
//
|
//
|
||||||
// You may elect to redistribute this code under either of these licenses.
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
package org.eclipse.jetty.logging;
|
package org.eclipse.jetty.webapp.logging;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
|
@ -0,0 +1,146 @@
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) Webtide LLC
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// All rights reserved. This program and the accompanying materials
|
||||||
|
// are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
// and Apache License v2.0 which accompanies this distribution.
|
||||||
|
//
|
||||||
|
// The Eclipse Public License is available at
|
||||||
|
// http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
//
|
||||||
|
// The Apache License v2.0 is available at
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0.txt
|
||||||
|
//
|
||||||
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
|
// ========================================================================
|
||||||
|
package org.eclipse.jetty.webapp.logging;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.logging.impl.Appender;
|
||||||
|
import org.eclipse.jetty.logging.impl.Severity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test Appender, records the logging events.
|
||||||
|
*/
|
||||||
|
public class TestAppender implements Appender
|
||||||
|
{
|
||||||
|
public static class LogEvent
|
||||||
|
{
|
||||||
|
String date;
|
||||||
|
Severity severity;
|
||||||
|
String name;
|
||||||
|
String message;
|
||||||
|
Throwable t;
|
||||||
|
|
||||||
|
public LogEvent(String date, Severity severity, String name, String message, Throwable t)
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
this.date = date;
|
||||||
|
this.severity = severity;
|
||||||
|
this.name = name;
|
||||||
|
this.message = message;
|
||||||
|
this.t = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LogEvent(Severity severity, String name, String message)
|
||||||
|
{
|
||||||
|
this(null,severity,name,message,null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuffer buf = new StringBuffer();
|
||||||
|
buf.append(severity.name()).append("|");
|
||||||
|
buf.append(name).append("|");
|
||||||
|
buf.append(message);
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<LogEvent> events = new ArrayList<LogEvent>();
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
public String getId()
|
||||||
|
{
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id)
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void append(String date, Severity severity, String name, String message, Throwable t)
|
||||||
|
{
|
||||||
|
if (name.equals("org.eclipse.jetty.util.log")) // standard jetty logger
|
||||||
|
{
|
||||||
|
if (t != null)
|
||||||
|
{
|
||||||
|
// Still interested in seeing throwables (HACK)
|
||||||
|
t.printStackTrace(System.err);
|
||||||
|
}
|
||||||
|
return; // skip storing it.
|
||||||
|
}
|
||||||
|
events.add(new LogEvent(date,severity,name,message,t));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() throws IOException
|
||||||
|
{
|
||||||
|
/* nothing to do here */
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean contains(LogEvent expectedEvent)
|
||||||
|
{
|
||||||
|
// System.out.println("Looking for: " + expectedEvent);
|
||||||
|
for (LogEvent event : events)
|
||||||
|
{
|
||||||
|
// System.out.println("Event: " + event);
|
||||||
|
if (!event.name.equals(expectedEvent.name))
|
||||||
|
{
|
||||||
|
continue; // not a match. skip.
|
||||||
|
}
|
||||||
|
if (!event.severity.equals(expectedEvent.severity))
|
||||||
|
{
|
||||||
|
continue; // not a match. skip.
|
||||||
|
}
|
||||||
|
if (event.message.equals(expectedEvent.message))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<LogEvent> getEvents()
|
||||||
|
{
|
||||||
|
return events;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void open() throws IOException
|
||||||
|
{
|
||||||
|
/* nothing to do here */
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset()
|
||||||
|
{
|
||||||
|
events.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProperty(String key, String value) throws Exception
|
||||||
|
{
|
||||||
|
/* nothing to do here */
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dump()
|
||||||
|
{
|
||||||
|
System.out.printf("Captured %s event(s)%n",events.size());
|
||||||
|
for (LogEvent event : events)
|
||||||
|
{
|
||||||
|
System.out.println(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,7 @@
|
||||||
// You may elect to redistribute this code under either of these licenses.
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
// ========================================================================
|
// ========================================================================
|
||||||
|
|
||||||
package org.eclipse.jetty.logging;
|
package org.eclipse.jetty.webapp.logging;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
|
@ -2,4 +2,4 @@ root.level=DEBUG
|
||||||
root.appenders=testing
|
root.appenders=testing
|
||||||
|
|
||||||
appender.console.class=org.eclipse.jetty.logging.impl.ConsoleAppender
|
appender.console.class=org.eclipse.jetty.logging.impl.ConsoleAppender
|
||||||
appender.testing.class=org.eclipse.jetty.logging.impl.TestAppender
|
appender.testing.class=org.eclipse.jetty.webapp.logging.TestAppender
|
1
pom.xml
1
pom.xml
|
@ -133,6 +133,7 @@
|
||||||
<module>jetty-servlet</module>
|
<module>jetty-servlet</module>
|
||||||
<module>jetty-webapp</module>
|
<module>jetty-webapp</module>
|
||||||
<module>jetty-webapp-verifier</module>
|
<module>jetty-webapp-verifier</module>
|
||||||
|
<module>jetty-webapp-logging</module>
|
||||||
<module>jetty-centralized-logging</module>
|
<module>jetty-centralized-logging</module>
|
||||||
<module>jetty-servlets</module>
|
<module>jetty-servlets</module>
|
||||||
<module>jetty-deploy</module>
|
<module>jetty-deploy</module>
|
||||||
|
|
Loading…
Reference in New Issue