ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/server/uk/org/iscream/cms/server/core/loggers/FileLogger.java
Revision: 1.8
Committed: Wed Mar 14 23:25:29 2001 UTC (23 years, 2 months ago) by tdb
Branch: MAIN
CVS Tags: PROJECT_COMPLETION
Changes since 1.7: +7 -7 lines
Log Message:
The whole server package structure has been changed.
Old Package: uk.ac.ukc.iscream.*
New Package: uk.org.iscream.*

File Contents

# User Rev Content
1 tdb 1.1 //---PACKAGE DECLARATION---
2 tdb 1.8 package uk.org.iscream.core.loggers;
3 tdb 1.1
4     //---IMPORTS---
5 tdb 1.8 import uk.org.iscream.util.*;
6     import uk.org.iscream.core.*;
7 tdb 1.1 import java.util.Date;
8     import java.text.DateFormat;
9     import java.util.Locale;
10     import java.io.BufferedWriter;
11     import java.io.File;
12     import java.io.FileWriter;
13     import java.io.IOException;
14    
15     /**
16     * The FileLogger is an implementation of the LoggerImpl defined
17     * in the associated interface. It provides quite extensive features to allow
18     * logging ot a text file.
19     *
20 tdb 1.5 * @author $Author: tdb1 $
21 tdb 1.8 * @version $Id: FileLogger.java,v 1.7 2001/02/25 20:49:20 tdb1 Exp $
22 tdb 1.1 */
23 tdb 1.4 public class FileLogger implements LoggerImpl {
24 tdb 1.1
25     //---FINAL ATTRIBUTES---
26    
27     /**
28     * The current CVS revision of this class
29     */
30 tdb 1.8 public final String REVISION = "$Revision: 1.7 $";
31 tdb 1.1
32     //---STATIC METHODS---
33    
34     //---CONSTRUCTORS---
35    
36     /**
37     * Creates a new FileLogger.
38     *
39     * The constructor checks that writing will be ok, then sets up the
40     * writer. It makes use of the fileCheck() method found later on to
41     * ensure writing will be ok, and throws an IOException if there is
42     * a problem. Errors at this stage cannot be logged because the
43     * logging mechanism has not be setup completely, so any problems
44     * are printed to the screen in the same format used for logging.
45     *
46     * @throws IOException if there is a problem with the file check.
47     */
48     public FileLogger() throws IOException{
49 tdb 1.8 filename = System.getProperty("uk.org.iscream.LoggerClass.FileLogger.filename");
50 tdb 1.1 // Perform file check to make sure writing is ok
51     if(!fileCheck()){
52     // Have to system.out.println errors because logging mechanism failed !
53 tdb 1.6 System.out.println(FormatName.formatLogLine(this.toString(), Logger.FATAL, "File check failed, construction terminated"));
54 tdb 1.1 throw new IOException("File check failed, unable to create FileLog");
55     }
56     try{
57     // Setup the writer
58     writer = new BufferedWriter(new FileWriter(filename, true));
59     // File is now open
60     open = true;
61     }
62     catch(IOException e){
63 tdb 1.6 System.out.println(FormatName.formatLogLine(this.toString(), Logger.FATAL, "Attempt to setup writer failed - " + e.getMessage()));
64 tdb 1.1 }
65     // Put an initial line into the log
66 ajm 1.3 write(toString(), Logger.SYSINIT, "started");
67 tdb 1.1 }
68    
69     //---PUBLIC METHODS---
70    
71 tdb 1.7 /**
72     * The write() method takes a line of text, pre-formatted
73     * and outputs it using a method defined by the actual
74     * implementation. The verbosity is given in case the
75     * implementation wishes to utilise it in the layout -
76     * eg. a different colour or font.
77 tdb 1.1 *
78 tdb 1.7 * This instance writes the line to a file.
79     *
80     * @param line A line of formatted text to be logged
81     * @param verbosity the verbosity of this message
82     */
83 tdb 1.6 public synchronized void write(String line, int verbosity) {
84     // Check to make sure file is open
85     if(open){
86     // Produce a nicely formatted line for the logfile
87     try{
88     // We have to synchronize here due to problems with two write()'s being called before a newLine()
89     synchronized(writer){
90     // Attempt to write the line
91     writer.write(line);
92     // Best to use newLine() as it will use the correct platform encoding
93     writer.newLine();
94     }
95     // Make sure the line is written immeidiately
96     writer.flush();
97     }
98     catch(IOException e){
99     // We'd best log the error
100     System.out.println(FormatName.formatLogLine(this.toString(), Logger.FATAL, "Writing to logfile failed - " + e.getMessage()));
101     // As it's an IOException we should suspend logging
102     open = false;
103     }
104     }
105     else{
106     // If file is not open we should print this to the screen
107     System.out.println(FormatName.formatLogLine(this.toString(), Logger.FATAL, "Write failed - file not open"));
108     }
109 tdb 1.1 }
110    
111     /**
112     * The clear() method erases the contents of the logfile. It does
113     * this in a very clumsy way - by closing the writer and opening a
114     * new one which is set not to append. This results in the logfile
115     * being overwritten, which effectively erases it.
116     */
117     public void clear(){
118     // Check file is open
119     if(open){
120 ajm 1.3 write(toString(), Logger.SYSMSG, "Attempting to clear logfile");
121 tdb 1.1 try{
122     // Close appending writer
123     open = false;
124     writer.close();
125     // Open a non-appending writer
126     writer = new BufferedWriter(new FileWriter(filename));
127     open = true;
128     }
129     catch(IOException e){
130     // We'd best log the error
131 ajm 1.3 write(toString(), Logger.ERROR, "Attempt to clear logfile failed - "+e.getMessage());
132 tdb 1.1 // As it's an IOException we should suspend logging
133     open = false;
134     }
135     }
136     else{
137     // If file is not open we should print this to the screen
138 tdb 1.6 System.out.println(FormatName.formatLogLine(this.toString(), Logger.FATAL, "Clearing failed - file not open"));
139 tdb 1.1 }
140     }
141    
142     /**
143     * The close() method closes the logfile and no more data can be written.
144     * If writing is attempted after close() has been called an error will be
145     * generated. The open() method can be used to reopen or open a new file.
146     */
147     public void close(){
148     // Check to see if a file is open
149     if(open){
150 ajm 1.3 write(toString(), Logger.SYSMSG, "Attempting to terminate logging");
151 tdb 1.1 try{
152     open = false;
153     writer.close();
154     }
155     catch(IOException e){
156 ajm 1.3 write(toString(), Logger.ERROR, "Attempt to close logfile failed - " + e.getMessage());
157 tdb 1.1 // As it's an IOException we should suspend logging
158     open = false;
159     }
160     }
161     else{
162     // If file is not open we should print this to the screen
163 tdb 1.6 System.out.println(FormatName.formatLogLine(this.toString(), Logger.FATAL, "Close failed - file not open"));
164 tdb 1.1 }
165     }
166    
167     /**
168     * The open() method opens a new file after the close() method has
169     * been called on the FileLog. This enables the user to easily change
170     * the file to which the log is being written. An error is generated
171     * if a file is already open.
172     *
173     * @param filename The new file to write to.
174     * @throws IOException if the file cannot be written to.
175     */
176     public void open(String filename) throws IOException{
177     // Check to see if a file is open
178     if(open){
179     // If file is already open then we should log that this went wrong
180 ajm 1.3 write(this.toString(), Logger.WARNING, "Open failed - a file is already open");
181 tdb 1.1 }
182     else{
183     this.filename = filename;
184     if(!fileCheck()) {
185     // Have to system.out.println errors because logging mechanism failed !
186 tdb 1.6 System.out.println(FormatName.formatLogLine(this.toString(), Logger.FATAL, "File check failed, construction terminated"));
187 tdb 1.1 throw new IOException("File check failed, unable to create FileLog");
188     }
189     try{
190     // Setup the writer
191     writer = new BufferedWriter(new FileWriter(filename, true));
192     // File is now open
193     open = true;
194     }
195     catch(IOException e){
196 tdb 1.6 System.out.println(FormatName.formatLogLine(this.toString(), Logger.FATAL, "Attempt to open writer failed - " + e.getMessage()));
197 tdb 1.1 }
198     }
199     }
200    
201     /**
202     * The suspend() method halts writing to the file by setting the open
203     * boolean to false, and thus blocking the write() method. A line is
204     * written to the logfile beforehand to note that writing has been
205     * suspended.
206     */
207     public void suspend(){
208     // Check to see if a file is open
209     if(open){
210     // Make a note of the fact that writing has been suspended
211 ajm 1.3 write(toString(), Logger.SYSMSG, "Writing suspended");
212 tdb 1.1 // Make sure writing not permitted
213     open=false;
214     }
215     else{
216     // If file is not open we should print this to the screen
217 tdb 1.6 System.out.println(FormatName.formatLogLine(this.toString(), Logger.FATAL, "Suspend failed - file not open"));
218 tdb 1.1 }
219     }
220    
221     /**
222     * The resume() method resumes writing to the file by setting the open
223     * boolean to true. A line is written to the logfile to signify this
224     * event occuring.
225     */
226     public void resume(){
227     // Check to see if a file is open
228     if(open){
229     // If file is open we should print this to the screen
230 tdb 1.6 System.out.println(FormatName.formatLogLine(this.toString(), Logger.FATAL, "Resume failed - file open"));
231 tdb 1.1 }
232     else{
233     // Permit writing again
234     open=true;
235     // Make a note of the fact that writing has been resumed
236 ajm 1.3 write(toString(), Logger.SYSMSG, "Writing resumed");
237 tdb 1.1 }
238     }
239    
240     /**
241     * Overrides the {@link java.lang.Object#toString() Object.toString()}
242     * method to provide clean logging (every class should have this).
243     *
244 tdb 1.8 * This uses the uk.org.iscream.util.FormatName class
245 ajm 1.3 * to format the toString()
246     *
247 tdb 1.1 * @return the name of this class and its CVS revision
248     */
249     public String toString() {
250 ajm 1.3 return FormatName.getName(
251     _name,
252     getClass().getName(),
253     REVISION);
254 tdb 1.1 }
255    
256     //---PRIVATE METHODS---
257    
258     /**
259     * The fileCheck() method is used to ensure that writing is ok. It
260     * performs so basic checks to make sure that if the file exists
261     * it can be written to, and if not a new file is created. A boolean
262     * result is returned to signify success or failure.
263     *
264     * @return A boolean value signify whether the test was sucessful.
265     */
266     private boolean fileCheck(){
267     boolean fileOK = false;
268     try{
269     File file = new File(filename);
270    
271     // File already exists
272     if(file.exists()) {
273     /* Only want success if it is a file (not a directory)
274     * and can be written to.
275     */
276     if(file.isFile() && file.canWrite()) {
277     fileOK = true;
278     }
279     }
280     // Create a new file and suceed
281     else{
282     file.createNewFile();
283     fileOK = true;
284     }
285     }
286     catch(IOException e){
287 tdb 1.6 System.out.println(FormatName.formatLogLine(this.toString(), Logger.FATAL, "File check failed - "+e.getMessage()));
288 tdb 1.1 }
289    
290     return fileOK;
291     }
292    
293 tdb 1.7 /**
294     * This method is provided if this class wishes to log
295     * a message itself.
296     *
297     * @param source A String representation of the source
298     * @param verbosity the verbosity of this message
299     * @param message The message to log
300     */
301 tdb 1.6 private void write(String source, int verbosity, String message) {
302     write(FormatName.formatLogLine(source, verbosity, message), verbosity);
303     }
304    
305 tdb 1.1 //---ACCESSOR/MUTATOR METHODS---
306    
307     //---ATTRIBUTES---
308    
309     /**
310     * The filename of the currently open, or last open, file.
311     */
312     private String filename;
313    
314     /**
315     * A reference to the writer being used.
316     */
317     private BufferedWriter writer;
318    
319     /**
320     * A boolean signifying whether a file is open or not.
321     */
322     private boolean open = false;
323 ajm 1.3
324     /**
325     * This is the friendly identifier of the
326     * component this class is running in.
327     * eg, a Filter may be called "filter1",
328     * If this class does not have an owning
329     * component, a name from the configuration
330     * can be placed here. This name could also
331     * be changed to null for utility classes.
332     */
333     private String _name = Core.NAME;
334 tdb 1.1
335     //---STATIC ATTRIBUTES---
336    
337     }