Can I get a vote on the following patches. They give the ability for
turbine to write to multiple log files while still retaining the use of
the default "logfile=" entry for those who need it. These patches also
include changes to the TurbineResources.properties file and the
getting_started.html.
********************* BEGIN PATCHES
************************************************
Index: conf/TurbineResources.properties
===================================================================
RCS file:
/products/cvs/turbine/turbine/conf/TurbineResources.properties,v
retrieving revision 1.52
diff -u -r1.52 TurbineResources.properties
--- conf/TurbineResources.properties 2000/06/05 15:44:56 1.52
+++ conf/TurbineResources.properties 2000/06/28 02:33:52
@@ -204,6 +204,15 @@
#
#logfile=/usr/home/logs/turbine.txt
+# The following allows for the creation of multiple logs within
turbine.
+# Be sure that each turbine.logs entry has a corresponding
turbine.log.[logname] entry.
+#
+# Example:
+# turbine.logs=database
+# turbine.logs=security
+# turbine.log.security=/turbine/logs/turbine-security.log
+# turbine.log.database=/turbine/logs/turbine-security.log
+
# Supplies Turbine with information about the database schema, which
can simplify any
# required Peer classes.
# Default: org.apache.turbine.util.db.map.TurbineMapBuilder
Index: docs/getting_started.html
===================================================================
RCS file: /products/cvs/turbine/turbine/docs/getting_started.html,v
retrieving revision 1.11
diff -u -r1.11 getting_started.html
--- docs/getting_started.html 2000/05/29 20:10:37 1.11
+++ docs/getting_started.html 2000/06/28 03:05:44
@@ -408,21 +408,48 @@
to the <a href="http://java.apache.org/main/mail.html">mailing list</a>
and express your interest there.
<p><b>Log - org.apache.turbine.util.Log</b>
-<p>This is a great class for doing simple debugging to a log file. Like
+<p>This is a great class for doing simple debugging to a log file or
for creating
+audit logs for your Turbine application. Like
many of the classes in Turbine, it is Singleton based so that it can be
called from anywhere in your code without having to pass references
around.
-To use the Log class, you must edit your
<i>TurbineResources.properties</i>
-file and specify a location for the log file. Then, you must actually
create
-the log file and on a unix system, make it writeable by the UID (user
ID)
-that the JVM is running as. We did this so that it is easy to turn off
-logging...simply remove the file. We also had an issue between the
different
-versions of the JDK (1.1 vs. 1.2) and the way that it creates new
files.
-<p>To use this class, simply add code like this:
-<blockquote><tt><font size=+1>Log.note ( "this is an error"
);</font></tt>
-<br><tt><font size=+1>or</font></tt>
-<br><tt><font size=+1>Log.error ( exception );</font></tt></blockquote>
-If you use Log.error() and pass in an exception, the stack trace will
be
-included in the log file. This is especially important for debugging
purposes.
+<BR>
+There are two ways to use the Log utility. <BR>
+A. You can create log entries in the default Turbine log file by doing
the following:<BR>
+ <OL>
+ <LI> Edit your <i>TurbineResources.properties</i>file and
specify a location for
+ your logfile like this:<BR>
+ logfile=/turbine/logs/turbine.log
+ <LI>Then, you must actually create
+ the log file and on a unix system, make it writeable by
the UID (user ID)
+ that the JVM is running as. We did this so that it is
easy to turn off
+ logging...simply remove the file. We also had an issue
between the different
+ versions of the JDK (1.1 vs. 1.2) and the way that it
creates new files.
+ <LI>Then add some code like this to your Turbine app:<BR>
+ Log.note ( "this is an error" );<BR>
+ or<BR>
+ Log.error ( exception );
+ <LI>If you use Log.error() and pass in an exception, the stack
trace will be
+ included in the log file. This is especially important
for debugging purposes.
+ </OL>
+B. You can create multiple logs for different uses within your Turbine
application
+by doing the following:<BR>
+ <OL>
+ <LI>Edit your <i>TurbineResources.properties</i>file and add
the following lines:<BR>
+ <UL>
+ turbine.logs=database<BR>
+ turbine.logs=security<BR>
+
turbine.log.security=/path/to/logs/turbine-security.log<BR>
+
turbine.log.database=/path/to/logs/turbine-database.log<BR>
+ </UL>
+ <LI>Create the log files in the location that you specified and
make sure that
+ the UID that the JVM is running as has write access to
the file(s).
+ <LI>Then add some code like this to your Turbine
application:<BR>
+ <UL>
+ Log.note("security","This is a test of the
turbine-security.log");<BR>
+ Log.note("database","This is a test of the
turbine-databsae.log");<BR>
+ </UL>
+ </OL>
+
<p>Of course this class should be extended and improved. Suggestions
and
code are welcome. Please subscribe to the
<a href="http://java.apache.org/main/mail.html">mailing
@@ -732,10 +759,10 @@
file.</li>
<li>
-Configure Turbine to user the WebMacroSite Service. The Scheduler
interface is implemented
+Configure Turbine to user the WebMacroSite Service. The Scheduler
interface is implemented
using WebMacro (see WebMacroSite Service below). You don't however,
need to use WebMacro to use the Scheduler.
-<li>
+<li>
Once the Scheduler UI is configured, Go to http://myurl/Turbine and
login.
<li>
Index: src/java/org/apache/turbine/util/Log.java
===================================================================
RCS file:
/products/cvs/turbine/turbine/src/java/org/apache/turbine/util/Log.java,v
retrieving revision 1.8
diff -u -r1.8 Log.java
--- src/java/org/apache/turbine/util/Log.java 2000/04/16 20:10:32 1.8
+++ src/java/org/apache/turbine/util/Log.java 2000/06/28 03:14:08
@@ -56,21 +56,22 @@
*
*/
-// Java Core Classes
+// Java Core Classes
import java.util.Date;
+import java.util.Vector;
import java.io.*;
import org.apache.turbine.services.resources.*;
/**
- * This is a utility class that is used for logging events. Entries
are
- * allowed in 3 levels - Notice, Warning, Error.
- * Methods are also available to log exceptions, which are always
logged
+ * This is a utility class that is used for logging events. Entries
are
+ * allowed in 3 levels - Notice, Warning, Error.
+ * Methods are also available to log exceptions, which are always
logged
* at the Error level.
*<p>
- * The path to a writable file must be given in
TurbineResources.properties
- * for the log to be written. If the file does not already exist, then
the
- * file will be created. If the path is invalid, then the file will not
be
+ * The path to a writable file must be given in
TurbineResources.properties
+ * for the log to be written. If the file does not already exist, then
the
+ * file will be created. If the path is invalid, then the file will not
be
* created and nothing will happen.
*<p>
* To use this class outside of Turbine, all you need to do is set the
path
@@ -82,16 +83,18 @@
*
* @author John D. McNally
* @author Jon S. Stevens <a
href="mailto:[EMAIL PROTECTED]">[EMAIL PROTECTED]</a>
+ * @author John Thorhauer
*/
-public class Log
-{
+public class Log
+{
private static String lf = System.getProperty("line.separator",
"\n");
-
+
// true if filename is valid and writeable
private static boolean isValid = true;
- // filename for log file
+ // filename for log file
private static FileWriter logfile = null;
-
+ // array to hold multiple FileWriter objects
+ private static Object logfiles[][];
// Levels - Notice, Warning, Error
private static final String NOTICE = "NOTICE ";
private static final String WARNING = "WARNING";
@@ -101,27 +104,59 @@
{
init();
}
-
+
/**
- * points Log file at the given path/filename.
- */
+ * checks to see if log variables are set up properly and
+ * the initializes the log(s)
+ */
private static void init()
{
try
{
String logFileString =
TurbineResources.getString("logfile", null);
- if (logFileString == null)
+ Vector turbineLogs =
TurbineResources.getVector("turbine.logs");
+
+ if (logFileString == null && turbineLogs.isEmpty())
{
throw new Exception (
- "The logfile= property in the TurbineResources.properties
file is null or could not be found.\n" +
- "Please make sure that you have properly defined the path
to the TurbineResources.properties file\n" +
- "and you have called
\"TurbineResourceService.setPropertiesFileName(\"/path/to/TurbineResources.properties\");\"
in your code.\n" +
- "If you are using this class with the Turbine Servlet, this
should have been called for you already.\n" +
- "If you are getting this error using the Turbine Servlet,
the path to the properties file or\n" +
- "the path to the logfile was not defined correctly. Please
refer to the INSTALL \n" +
- "document for instructions on how to do this.\n");
+ "The logfile= property and the turbine.logs= property
in the TurbineResources.properties file are null \n" +
+ "or could not be found. At least one of these
properties must be defined in the TurbineResources.properties file. \n"
+
+ "Please make sure that you have properly defined the
path to the TurbineResources.properties file\n" +
+ "and you have called
\"TurbineResourceService.setPropertiesFileName(\"/path/to/TurbineResources.properties\");\"
in your code.\n" +
+ "If you are using this class with the Turbine Servlet,
this should have been called for you already.\n" +
+ "If you are getting this error using the Turbine
Servlet, the path to the properties file or\n" +
+ "the path to the logfile or the logcount was not
defined correctly. Please refer to the INSTALL \n" +
+ "document for instructions on how to do this.\n");
+ }
+
+ if (logFileString != null)
+ {
+ logfile = new FileWriter( logFileString, true );
+ }
+
+ // if there are turbine.logs defined then set up an array
of FileWriters
+ // for use in the method Log.note(logname,text) etc
+ if (!turbineLogs.isEmpty())
+ {
+ logfiles= new Object[turbineLogs.size()][2];
+ for (int i=0;i<turbineLogs.size();i++)
+ {
+ if (TurbineResources.getString("turbine.log." +
(String)turbineLogs.elementAt(i),null) == null)
+ {
+ throw new Exception(
+ "There is an error in the
TurbineResources.properties file. \n" +
+ "The turbine.log." + (String)turbineLogs.get(i)
+ "= entry could not be found for the \n" +
+ "corresponding turbine.logs=" +
(String)turbineLogs.get(i) + " entry. \n" +
+ "Be sure that each turbine.logs= entry has a
corresponding turbine.log.[logname]= \n" +
+ "in the TurbineResources.properties file. \n" +
+ "Please refer to the comments in the
TurbineResources.properties file \n" +
+ "or the user documentation for more information
on how to properly \n" +
+ "implement logging in a Turbine application.
\n");
+ }
+ logfiles[i][0]= (String)turbineLogs.get(i);
+ logfiles[i][1]= (FileWriter) new
FileWriter(TurbineResources.getString("turbine.log." +
(String)turbineLogs.get(i),null),true);
+ }
}
- logfile = new FileWriter( logFileString, true );
}
catch (Exception e)
{
@@ -133,64 +168,108 @@
isValid = false;
}
}
-
+
/*
* Makes a log entry at the NOTICE level
*
* @returns true if entry was entered, false otherwise
- */
- public static boolean note(String description)
- {
+ */
+ public static boolean note(String description)
+ {
return log(NOTICE, description);
}
/*
+ * Specifies the log to print to and
+ * makes a log entry at the NOTICE level
+ *
+ * @returns true if entry was entered, false otherwise
+ */
+ public static boolean note(String logname, String description)
+ {
+ return log(NOTICE, logname, description, null);
+ }
+ /*
* Makes a log entry at the WARNING level
*
* @returns true if entry was entered, false otherwise
- */
- public static boolean warn(String description)
- {
+ */
+ public static boolean warn(String description)
+ {
return log(WARNING, description);
}
/*
+ * Specifies the log to print to and
+ * makes a log entry at the WARNING level
+ *
+ * @returns true if entry was entered, false otherwise
+ */
+ public static boolean warn(String logname, String description)
+ {
+ return log(WARNING, logname, description, null);
+ }
+ /*
* Makes a log entry at the ERROR level
*
* @returns true if entry was entered, false otherwise
- */
- public static boolean error(String description)
- {
+ */
+ public static boolean error(String description)
+ {
+ System.out.print("Error=" + description + "\n");
return log(ERROR, description);
- }
+
+ }
/*
+ * Specifies the log to print to and
+ * makes a log entry at the ERROR level
+ *
+ * @returns true if entry was entered, false otherwise
+ */
+ public static boolean error(String logname, String description)
+ {
+ return log(ERROR, logname, description, null);
+ }
+ /*
* Makes a log entry at the ERROR level
*
* @returns true if entry was entered, false otherwise
- */
- public static boolean error(String description, Throwable t)
+ */
+ public static boolean error(String description, Throwable t)
{
return log(ERROR, description, t);
- }
+ }
/*
+ * Specifies the log to print to and
+ * makes a log entry at the ERROR level
+ *
+ * @returns true if entry was entered, false otherwise
+ */
+ public static boolean error(String logname, String description,
Throwable t)
+ {
+ return log(ERROR, logname, description, t);
+ }
+ /*
* Makes a log entry at the ERROR level
*
* @returns true if entry was entered, false otherwise
- */
- public static boolean error(Throwable t)
+ */
+ public static boolean error(Throwable t)
{
return log(ERROR, "", t);
- }
+ }
+
private static boolean log(String level, String description)
{
return log(level, description, null);
}
+
private static boolean log(String level, String description,
Throwable t)
{
if ( isValid )
- {
+ {
Date date = new Date();
StringBuffer logEntry = new StringBuffer();
logEntry.append ( "[" );
- logEntry.append ( date.toString() );
+ logEntry.append ( date.toString() );
logEntry.append ( "] -- " );
logEntry.append ( level );
logEntry.append ( " -- " );
@@ -222,19 +301,90 @@
return false;
}
}
- return true;
+ return true;
}
- return false;
+ return false;
}
-
+
+ /**
+ * Creates a log entry in the log passed in as logname
+ */
+ private static boolean log(String level, String logname, String
description, Throwable t)
+ {
+ boolean foundLog = false;
+ int i = 0;
+ int activeLogNumber = 0;
+ for (i=0;i<logfiles.length;i++)
+ {
+ if (logfiles[i][0].equals(logname))
+ {
+ activeLogNumber = i;
+ foundLog=true;
+ break;
+ }
+ }
+ if (foundLog)
+ {
+ Date date = new Date();
+ StringBuffer logEntry = new StringBuffer();
+ logEntry.append ( "[" );
+ logEntry.append ( date.toString() );
+ logEntry.append ( "] -- " );
+ logEntry.append ( level );
+ logEntry.append ( " -- " );
+ logEntry.append ( description );
+ logEntry.append ( lf );
+ if (t != null)
+ {
+ ByteArrayOutputStream ostr = new
ByteArrayOutputStream();
+ PrintWriter out = new PrintWriter(ostr,true);
+ out.write(logEntry.toString());
+ out.write("\tException: ");
+ out.write(t.toString());
+ out.write(lf+"\tStack Trace follows:"+lf+"\t");
+ t.printStackTrace(out);
+ logEntry = new StringBuffer( ostr.toString() );
+ }
+ synchronized( (FileWriter)logfiles[activeLogNumber][1] )
+ {
+ try
+ {
+ ((FileWriter)logfiles[activeLogNumber][1]).write(
logEntry.toString(), 0, logEntry.length());
+ ((FileWriter)logfiles[activeLogNumber][1]).flush();
+ }
+ catch(IOException ioe)
+ {
+ // ignore, skip log, should not occur since we have
checked file
+ // but catching the exception allows Log to be used
elsewhere in
+ // catch blocks.
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
/**
- Attempt to close the log file when the class is GC'd
+ Attempt to close the log files when the class is GC'd
*/
public void destroy()
{
try
{
- logfile.close();
+ if (logfile != null)
+ {
+ logfile.close();
+ }
+ if (logfiles.length>0)
+ {
+ for (int i=0;i<logfiles.length;i++)
+ {
+ if(logfiles[i][1] != null)
+ {
+ ((FileWriter)logfiles[i][1]).close();
+ }
+ }
+ }
}
catch (Exception e)
{}
************************ END PATCHES
****************************************
Thanks,
John
--
********************************
** John Thorhauer
** [EMAIL PROTECTED]
********************************
------------------------------------------------------------
To subscribe: [EMAIL PROTECTED]
To unsubscribe: [EMAIL PROTECTED]
Search: <http://www.mail-archive.com/turbine%40list.working-dogs.com/>
Problems?: [EMAIL PROTECTED]