package com.javaranch.common ; import java.io.*; import java.util.*; import java.awt.*; import java.text.*; /** ErrorLog is a simple way of handling warnings and errors in your programs.
Rather than having 20 lines of error handling for each occurance of an error, you can have just one. When the time comes to handle your errors a different way, you don't have to find a thousand error locations and rewrite the handling: just change the ErrorLog initialization.
To use ErrorLog, create a log instance:
ErrorLog log = new ErrorLog();
and then when the error occurs:
log.add( "file " + fileName + " corrupted at byte " + pos );
The time and date will be added to your message and written to System.err.
Example:
ErrorLog log = new ErrorLog();
log.setLogFile( "errors.txt" ); // turn on text file logging
...
log.add( "file " + fileName + " corrupted at byte " + pos );
// this error message is sent to the console and copied to the file "errors.txt"
...
// end of the program
log.setLogFileOff();
Note that a "file flush" is performed after each error message is processed.
This is in case your program is prematurely terminated: the file will still contain
all of the messages you sent (instead of having them in a buffer in memory waiting for
the file to be closed). Note also that setLogFileOff() does not have to be called when your program finishes, although it is good programming practice. In other words, you will not lose any data from your file if you do not call setLogFileOff().
INTERNAL LOGGING
Example:
ErrorLog log = new ErrorLog();
log.setInternalLog( true ); // turn on internal logging
...
log.add( "file " + fileName + " corrupted at byte " + pos );
// this error message is stored in Errors and copied to the console
...
//When you are ready to extract the log:
String[] errors = log.getList();
DIALOG DISPLAY
Example:
ErrorLog log = new ErrorLog();
...
log.addAndDisplay( myPanel , "file " + fileName + " corrupted" );
// this error message is written to the console and instantly
// appears in a Dialog
If you have different levels of severity you wish to keep track of, you can create different ErrorLog
objects:
ErrorLog errors = new ErrorLog();
ErrorLog warnings = new ErrorLog();
ErrorLog suggestions = new ErrorLog();
...
errors.add( "file " + fileName + " corrupted at byte " + pos );
...
warnings.add( "employee " + empName + " found twice - could be a duplicate" );
...
if ( password.length() < 5 )
{
Copyright (c) 1998-2000 Paul Wheaton
You are welcome to do whatever you want to with this source file provided that you maintain this comment fragment (between the dashed lines). Modify it, change the package name, change the class name ... personal or business use ... sell it, share it ... add a copyright for the portions you add ...
My goal in giving this away and maintaining the copyright is to hopefully direct developers back to JavaRanch.
The original source can be found at JavaRanch
- - - - - - - - - - - - - - - - -
@author Paul Wheaton */ public class ErrorLog implements Serializable { // contains all of the error strings that occurred while error logging is turned on. If // this is null, error logging is currently off. private Vector errors = null ; // if errors are to be directed to a file, f specifies the file. If f is null // then this feature is currently turned off. private transient TextFileOut f = null ; // should errors be sent to the console? private boolean logToConsole = true ; // the number of errors that this object has encountered so far private int count = 0 ; /** Create an ErrorLog object where errors are sent to System.err */ public ErrorLog() { // nothing to do } /** Create an ErrorLog object where errors are sent to a text file.
If the text file already exists, it will first be deleted. If the text file does not already exist, it will be created.
This constructor defaults to console logging off. If you want both console logging and file logging, call this constructor and then call setConsole( true );
@param fileName The name of the file that will be created and store future error messages.
@exception IOException thrown for any IO errors encountered while creating the file.
*/ public ErrorLog( String fileName ) throws IOException { logToConsole = false ; setLogFile( fileName ) ; } /** Tell the ErrorLog object that all future error messages are to be copied to a text file.
If the text file already exists, it will first be deleted. If the text file does not already exist, it will be created.
@param fileName The name of the file that will be created and store future error messages.
@exception IOException thrown for any IO errors encountered while creating the file.
*/ public void setLogFile( String fileName ) throws IOException { if ( f != null ) { setLogFileOff(); } f = new TextFileOut( fileName ); } /** Tell the ErrorLog object that all future error messages are to be copied to a text file.
If the text file already exists, new messages will be appended to the end. If the text file does not already exist, it will be created.
@param fileName The name of the file that will store future error messages.
@exception IOException thrown for any IO errors encountered while creating/opening the file.
*/ public void appendLogFile( String fileName ) throws IOException { if ( f != null ) { setLogFileOff(); } f = new TextFileOut( fileName , true ); } /** returns the current local date and time.
@return a string containing the current local date and time.
*/ private static String nowStr() { SimpleDateFormat f = new SimpleDateFormat("yyyy.MM.dd EEE hh:mm:ss"); return f.format( new Date() ); } // add a string to the errors vector if it is not null. private void addToErrors( String s ) { if ( errors != null ) { errors.addElement( s ); if ( errors.size() > 5000 ) { int numToKeep = 3000 ; for( int i = 0 ; i < numToKeep ; i++ ) { errors.setElementAt( errors.elementAt( i + ( errors.size() - numToKeep ) ) , i ); } errors.setSize( numToKeep ); } } } // handle an internal error. In case of any problems within this class, // they need to be passed along without stopping the program. private void InternalError( String s ) { s = nowStr() + " " + s ; addToErrors( s ); // send message to console whether they want it or not System.err.println( s ); } /** Tell the ErrorLog object that no further errors are to be copied to a text file.
This method also properly closes the log file.
*/ public void setLogFileOff() { if ( f != null ) { try { f.close(); } catch ( IOException e ) { InternalError( "could not properly close log file" ); } f = null ; } } /** Test to see if this ErrorLog object currently copies error messages to a text file.
@return true if all messages are copied to a text file.
false if no messages are copied to a text file.
*/ public boolean isFileLogOn() { return ( f != null ) ; } /** Tell the ErrorLog object to start/stop copying error messages to the console.
@param on true: start sending messages to the console. false: stop sending messages to the console.
*/ public void setConsole( boolean on ) // if true, all errors are copied to STDERR { logToConsole = on ; } /** Test to see if this ErrorLog object currently copies error messages to the console.
@return true if all messages are copied to the console.
false if no messages are copied to the console.
*/ public boolean isConsoleLogOn() { return logToConsole ; } /** Add an error message to the ErrorLog object.
"message" has a time/date stamp added to it.
If internal logging is on, the message is appended to the internal collection of error messages.
If console logging is on, the message is copied to the console.
If file logging is on, the message is copied to the log file.
@param message this can be any text you want.
*/ public void add( String message ) { String s = nowStr() + " " + message ; addToErrors( s ); if ( logToConsole ) { System.err.println( s ); } if ( f != null ) { try { f.writeLine( s ); f.flush(); } catch ( IOException e ) { InternalError( "error occured while writing to log file" ); } } count++; } /** Add an error message to the ErrorLog object and display that mesage to the user in a Dialog.
"message" has a time/date stamp added to it.
A diolog box is created and the message is displayed in that dialog.
If internal logging is on, the message is appended to the internal collection of error messages.
If console logging is on, the message is copied to the console.
If file logging is on, the message is copied to the log file.
@param c any AWT or JFC component. It will be used to find an AWT Frame which is required for all Dialogs.
@param message this can be any text you want. */ public void addAndDisplay( Component c , String message ) { add( message ); GUI.tellUser( c , message ); } /** Get the number of errors that this object has encountered.
@return the number of error that this object has encountered.
*/ public int numErrors() { return count ; } /** Get a list of all error messages that have been passed in to the ErrorLog object.
@return an array of strings which represent the error messages that were passed to the ErrorLog object. Each message includes a date and time stamp. If errors are not currently stored in this object, null is returned.
*/ public String[] getList() { String[] s = null ; if ( errors != null ) { s = new String[ errors.size() ]; errors.copyInto( s ); } return s ; } /** Tell the ErrorLog object to start/stop copying error messages to an internal buffer.
@param on true start copying messages to the internal buffer. false stop copying messages to the internal buffer. */ public void setInternalLog( boolean on ) { if ( on ) { if ( errors == null ) { errors = new Vector(); } } else { errors = null ; } } /** Test to see if this ErrorLog object currently copies error messages to an internal buffer.
@return true if all messages are copied to the internal buffer.
false if no messages are copied to the internal buffer.
*/ public boolean isInternalLogOn() { return ( errors != null ) ; } /** Provided for testing purposes only.
*/ public static void unitTest( TestLog log ) { // xxx need tests } }