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.12
Committed: Wed Feb 5 16:43:47 2003 UTC (21 years, 3 months ago) by tdb
Branch: MAIN
Changes since 1.11: +4 -4 lines
Log Message:
Changed the server to use the external util package. Quite a minor change,
but does affect a lot of files.

File Contents

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