- From: Stefan Speidel <Speidel@tp-cad.com>
- Date: Wed, 1 Jul 1998 06:36:16 -0400 (EDT)
- To: "www-jigsaw@w3.org" <www-jigsaw@w3.org>
- Message-ID: <359A1165.DD5FBA5E@tp-cad.com>
Hi, the Logger in Jigsaw2beta1 logs the month July with 'Jui', but it must be 'Jul'. I corrected it. Here are the .class and .java files -- ###################################################################### ### ### ### Stefan Speidel mailto:Speidel@tp-cad.com ### ### TP-CAD GmbH, Ettlingen mailto:company@tp-cad.com ### ### http://www.tp-cad.com ### ######################################################################
// CommonLogger.java
// $Id: CommonLogger.java,v 1.22 1998/01/22 14:01:04 bmahe Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html
// Aenderung Jui auf Jul, SP 31.06.98
package org.w3c.jigsaw.http ;
import java.io.* ;
import java.util.Date ;
import org.w3c.jigsaw.daemon.*;
import org.w3c.jigsaw.auth.AuthFilter;
import org.w3c.util.*;
/**
* The CommonLogger class implements the abstract Logger class.
* The resulting log will conform to the
* <a href="http://www.w3.org/hypertext/WWW/Daemon/User/Config/Logging.html#common-logfile-format">common log format</a>).
* @see org.w3c.jigsaw.core.Logger
*/
/**
public class CommonLogger extends Logger implements PropertyMonitoring {
private static final String monthnames[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jui", "Aug", "Sep", "Oct", "Nov", "Dec"
};
*/
public class CommonLogger extends Logger implements PropertyMonitoring {
private static final String monthnames[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
/**
* Name of the property indicating the log file.
* This property indicates the name of the log file to use.
* <p>This property defaults to the <code>log</code> file in the server
* log directory.
*/
public static final
String LOGNAME_P = "org.w3c.jigsaw.logger.logname" ;
/**
* Name of the property indicating the error log file.
* This property indicates the name of the error log file to use.
* <p>This property defaults to the <code>errlog</code> file in the
* server log directory.
*/
public static final
String ERRLOGNAME_P = "org.w3c.jigsaw.logger.errlogname" ;
/**
* Name of the property indicating the server trace file.
* This property indicates the name of the trace file to use.
* <p>This property defaults to the <code>trace</code> file in the
* server log directory.
*/
public static final
String TRACELOGNAME_P = "org.w3c.jigsaw.logger.tracelogname";
/**
* Name of the property indicating the buffer size for the logger.
* This buffer size applies only the the log file, not to the error
* log file, or the trace log file. It can be set to zero if you want
* no buffering.
* <p>This property default to <strong>4096</strong>.
*/
public static final
String BUFSIZE_P = "org.w3c.jigsaw.logger.bufferSize";
private byte msgbuf[] = null ;
protected RandomAccessFile log = null ;
protected RandomAccessFile errlog = null ;
protected RandomAccessFile trace = null ;
protected httpd server = null ;
protected ObservableProperties props = null ;
protected String logdir = "logs" ;
protected int bufsize = 8192;
protected int bufptr = 0;
protected byte buffer[] = null;
/**
* Property monitoring for the logger.
* The logger allows you to dynamically (typically through the property
* setter) change the names of the file to which it logs error, access
* and traces.
* @param name The name of the property that has changed.
* @return A boolean, <strong>true</strong> if the change was made,
* <strong>false</strong> otherwise.
*/
public boolean propertyChanged (String name) {
if ( name.equals(LOGNAME_P) ) {
try {
openLogFile () ;
} catch (Exception e) {
e.printStackTrace() ;
return false ;
}
return true ;
} else if ( name.equals(ERRLOGNAME_P) ) {
try {
openErrorLogFile() ;
} catch (Exception e) {
e.printStackTrace() ;
return false ;
}
return true ;
} else if ( name.equals(TRACELOGNAME_P) ) {
try {
openTraceFile() ;
} catch (Exception e) {
e.printStackTrace() ;
return false ;
}
return true ;
} else if ( name.equals(BUFSIZE_P) ) {
synchronized (this) {
bufsize = props.getInteger(name, bufsize);
// Reset buffer before resizing:
if ( bufptr > 0 ) {
try {
log.write(buffer, 0, bufptr);
bufptr = 0;
} catch (IOException ex) {
}
}
// Set new buffer:
buffer = (bufsize > 0) ? new byte[bufsize] : null;
return true;
}
} else {
return true ;
}
}
/**
* Output the given message to the given RandomAccessFile.
* This method makes its best effort to avoid one byte writes (which you
* get when writing the string as a whole). It first copies the string
* bytes into a private byte array, and than, write them all at once.
* @param f The RandomAccessFile to write to, which should be one of
* log, errlog or trace.
* @param msg The message to be written.
* @exception IOException If writing to the output failed.
*/
protected synchronized void output (RandomAccessFile f, String msg)
throws IOException
{
int len = msg.length() ;
if ( len > msgbuf.length )
msgbuf = new byte[len] ;
msg.getBytes (0, len, msgbuf, 0) ;
f.write (msgbuf, 0, len) ;
}
protected synchronized void appendLogBuffer(String msg)
throws IOException
{
int msglen = msg.length();
if ( bufptr + msglen > buffer.length ) {
// Flush the buffer:
log.write(buffer, 0, bufptr);
bufptr = 0;
// Check for messages greater then buffer:
if ( msglen > buffer.length ) {
byte huge[] = new byte[msglen];
msg.getBytes(0, msglen, huge, 0);
log.write(huge, 0, msglen);
return;
}
} else {
// Append that message to buffer:
msg.getBytes(0, msglen, buffer, bufptr);
bufptr += msglen;
}
}
protected void logmsg (String msg) {
if ( log != null ) {
try {
if ( buffer == null ) {
output (log, msg) ;
} else {
appendLogBuffer(msg);
}
} catch (IOException e) {
throw new HTTPRuntimeException (this,"logmsg",e.getMessage()) ;
}
}
}
protected void errlogmsg (String msg) {
if ( errlog != null ) {
try {
output (errlog, msg) ;
} catch (IOException e) {
throw new HTTPRuntimeException (this
, "errlogmsg"
, e.getMessage()) ;
}
}
}
protected void tracemsg (String msg) {
if ( trace != null ) {
try {
output (trace, msg) ;
} catch (IOException e) {
throw new HTTPRuntimeException (this
, "tracemsg"
, e.getMessage()) ;
}
}
}
/**
* Log the given HTTP transaction.
* This is shamelessly slow.
*/
public void log (Request request, Reply reply, int nbytes, long duration) {
Client client = request.getClient() ;
String entry = null ;
long date = reply.getDate();
Date now = (date < 0) ? new Date() : new Date(date);
String user = (String) request.getState(AuthFilter.STATE_AUTHUSER);
entry = client.getInetAddress().getHostAddress()
+ " " + "-" // user name
+ " " + ((user == null ) ? "-" : user) // auth user name
+ ((now.getDate() < 10) ? " [0" : " [")
+ (now.getDate() // current date
+ "/" + monthnames[now.getMonth()]
+ "/" + (now.getYear() + 1900)
+ ((now.getHours() < 10)
? (":0" + now.getHours())
: (":" + now.getHours()))
+ ((now.getMinutes() < 10)
? (":0" + now.getMinutes())
: (":" + now.getMinutes()))
+ ((now.getSeconds() < 10)
? (":0" + now.getSeconds())
: (":" + now.getSeconds()))
+ ((now.getTimezoneOffset() < 0)
? " " + (now.getTimezoneOffset() / 60)
: " +" + (now.getTimezoneOffset() / 60))
+ "]")
+ " \"" + request.getMethod() // request line
+ " " + request.getURL()
+ " " + request.getVersion()
+ "\" " + reply.getStatus() // reply status
+ " " + nbytes // # of emited bytes
+ "\n" ;
logmsg (entry) ;
}
public void log(String msg) {
logmsg(msg);
}
public void errlog (Client client, String msg) {
errlogmsg (client + ": " + msg + "\n") ;
}
public void errlog (String msg) {
errlogmsg (msg + "\n") ;
}
public void trace (Client client, String msg) {
tracemsg (client + ": " + msg + "\n") ;
}
public void trace (String msg) {
tracemsg (msg + "\n") ;
}
/**
* Get the name for the file indicated by the provided property.
* This method first looks for a property value. If none is found, it
* than constructs a default filename from the server root, by
* using the provided default name.
* <p>This method shall either succeed in getting a filename, or throw
* a runtime exception.
* @param propname The name of the property.
* @param def The default file name to use.
* @exception HTTPRuntimeException If no file name could be deduced from
* the provided set of properties.
*/
protected String getFilename (String propname, String def) {
String filename = props.getString (propname, null) ;
if ( filename == null ) {
File root_dir = server.getRootDirectory();
if ( root_dir == null ) {
String msg = "unable to build a default value for the \""
+ propname + "\" value." ;
throw new HTTPRuntimeException (this.getClass().getName()
, "getFilename"
, msg) ;
}
File flogdir = new File(root_dir, logdir) ;
return (new File(flogdir, def)).getAbsolutePath() ;
} else {
return filename ;
}
}
/**
* Open this logger log file.
*/
protected void openLogFile () {
String logname = getFilename(LOGNAME_P, "log") ;
try {
RandomAccessFile old = log ;
log = new RandomAccessFile (logname, "rw") ;
log.seek (log.length()) ;
if ( old != null )
old.close () ;
} catch (IOException e) {
throw new HTTPRuntimeException (this.getClass().getName()
, "openLogFile"
, "unable to open "+logname);
}
}
/**
* Open this logger error log file.
*/
protected void openErrorLogFile () {
String errlogname = getFilename (ERRLOGNAME_P, "errlog") ;
try {
RandomAccessFile old = errlog ;
errlog = new RandomAccessFile (errlogname, "rw") ;
errlog.seek (errlog.length()) ;
if ( old != null )
old.close() ;
} catch (IOException e) {
throw new HTTPRuntimeException (this.getClass().getName()
, "openErrorLogFile"
, "unable to open "+errlogname);
}
}
/**
* Open this logger trace file.
*/
protected void openTraceFile () {
String tracename = getFilename (TRACELOGNAME_P, "traces");
try {
RandomAccessFile old = trace ;
trace = new RandomAccessFile (tracename, "rw") ;
trace.seek (trace.length()) ;
if ( old != null )
old.close() ;
} catch (IOException e) {
throw new HTTPRuntimeException (this.getClass().getName()
, "openTraceFile"
, "unable to open "+tracename);
}
}
/**
* Save all pending data to stable storage.
*/
public synchronized void sync() {
try {
if ((buffer != null) && (bufptr > 0)) {
log.write(buffer, 0, bufptr);
bufptr = 0;
}
} catch (IOException ex) {
server.errlog(getClass().getName()
+ ": IO exception in method sync \""
+ ex.getMessage() + "\".");
}
}
/**
* Shutdown this logger.
*/
public synchronized void shutdown () {
server.getProperties().unregisterObserver (this) ;
try {
// Flush any pending output:
if ((buffer != null) && (bufptr > 0)) {
log.write(buffer, 0, bufptr);
bufptr = 0;
}
log.close() ;
log = null ;
errlog.close() ;
errlog = null ;
trace.close() ;
trace = null ;
} catch (IOException ex) {
server.errlog(getClass().getName()
+ ": IO exception in method shutdown \""
+ ex.getMessage() + "\".");
}
}
/**
* Initialize this logger for the given server.
* This method gets the server properties describe above to
* initialize its various log files.
* @param server The server to which thiss logger should initialize.
*/
public void initialize (httpd server) {
this.server = server ;
this.props = server.getProperties() ;
// Register for property changes:
props.registerObserver (this) ;
// Open the various logs:
openLogFile () ;
openErrorLogFile() ;
openTraceFile() ;
// Setup the log buffer is possible:
if ((bufsize = props.getInteger(BUFSIZE_P, bufsize)) > 0 )
buffer = new byte[bufsize];
return ;
}
/**
* Construct a new Logger instance.
*/
CommonLogger () {
this.msgbuf = new byte[128] ;
}
}
Attachments
- application/x-java-vm/java-beans attachment: CommonLogger.class
Received on Wednesday, 1 July 1998 07:42:31 UTC