KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > h2 > message > TraceSystem


1 /*
2  * Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
3  * Initial Developer: H2 Group
4  */

5 package org.h2.message;
6
7 import java.io.FileWriter JavaDoc;
8 import java.io.IOException JavaDoc;
9 import java.io.PrintWriter JavaDoc;
10 import java.sql.DriverManager JavaDoc;
11 import java.sql.SQLException JavaDoc;
12 import java.text.SimpleDateFormat JavaDoc;
13 import java.util.Date JavaDoc;
14 import java.util.HashMap JavaDoc;
15
16 import org.h2.engine.Constants;
17 import org.h2.util.FileUtils;
18
19 /**
20  * It is possible to write after close was called, but that means for each write the
21  * log file will be opened and closed again (which is slower).
22  *
23  * @author Thomas
24  */

25 public class TraceSystem {
26     public static final int OFF = 0, ERROR = 1, INFO = 2, DEBUG = 3;
27
28     // TODO log total and free memory from time to time
29

30     // max file size is currently 64 MB,
31
// and then there could be a .old file of the same size
32
private static final int DEFAULT_MAX_FILE_SIZE = 64 * 1024 * 1024;
33     public static final int DEFAULT_TRACE_LEVEL_SYSTEM_OUT = OFF;
34     public static final int DEFAULT_TRACE_LEVEL_FILE = ERROR;
35     private static final int CHECK_FILE_TIME = 4000;
36     private int levelSystemOut = DEFAULT_TRACE_LEVEL_SYSTEM_OUT;
37     private int levelFile = DEFAULT_TRACE_LEVEL_FILE;
38     private int maxFileSize = DEFAULT_MAX_FILE_SIZE;
39     private String JavaDoc fileName;
40     private long lastCheck;
41     private HashMap JavaDoc traces;
42     private SimpleDateFormat JavaDoc dateFormat;
43     private FileWriter JavaDoc fileWriter;
44     private PrintWriter JavaDoc printWriter;
45     private static final int CHECK_SIZE_EACH_WRITES = 128;
46     private int checkSize;
47     private boolean closed;
48     
49     public static void traceThrowable(Throwable JavaDoc e) {
50         PrintWriter JavaDoc writer = DriverManager.getLogWriter();
51         if(writer != null) {
52             e.printStackTrace(writer);
53         }
54     }
55
56     public TraceSystem(String JavaDoc fileName) {
57         this.fileName = fileName;
58         traces = new HashMap JavaDoc();
59         dateFormat = new SimpleDateFormat JavaDoc("MM-dd HH:mm:ss ");
60         if(fileName != null) {
61             try {
62                 openWriter();
63             } catch(Exception JavaDoc e) {
64                 logWritingError(e);
65             }
66         }
67     }
68
69     public Trace getTrace(String JavaDoc module) {
70         Trace t = (Trace) traces.get(module);
71         if (t == null) {
72             t = new Trace(this, module);
73             traces.put(module, t);
74         }
75         return t;
76     }
77
78     public boolean isEnabled(int level) {
79         int max = Math.max(levelSystemOut, levelFile);
80         return level <= max;
81     }
82
83     public void setFileName(String JavaDoc name) {
84         this.fileName = name;
85     }
86
87     public void setMaxFileSize(int max) {
88         this.maxFileSize = max;
89     }
90
91     public int getMaxFileSize() {
92         return maxFileSize;
93     }
94
95     public void setLevelSystemOut(int l) {
96         levelSystemOut = l;
97     }
98
99     public int getLevelFile() {
100         return levelFile;
101     }
102
103     public int getLevelSystemOut() {
104         return levelSystemOut;
105     }
106
107     public void setLevelFile(int l) {
108         levelFile = l;
109     }
110
111     private String JavaDoc format(String JavaDoc module, String JavaDoc s) {
112         return dateFormat.format(new Date JavaDoc()) + module + ": " + s;
113     }
114
115     void write(int l, String JavaDoc module, String JavaDoc s, Throwable JavaDoc t) {
116         if (l <= levelSystemOut) {
117             System.out.println(format(module, s));
118             if (t != null && levelSystemOut == DEBUG) {
119                 t.printStackTrace();
120             }
121         }
122         if (fileName != null) {
123             if (l > levelFile) {
124                 long time = System.currentTimeMillis();
125                 if (time > lastCheck + CHECK_FILE_TIME) {
126                     String JavaDoc checkFile = fileName + Constants.SUFFIX_TRACE_START_FILE;
127                     lastCheck = time;
128                     if (FileUtils.exists(checkFile)) {
129                         levelFile = DEBUG;
130                         try {
131                             FileUtils.delete(checkFile);
132                         } catch (Exception JavaDoc e) {
133                             // the file may be read only
134
}
135                     }
136                 }
137             }
138             if (l <= levelFile) {
139                 writeFile(format(module, s), t);
140             }
141         }
142     }
143
144     private synchronized void writeFile(String JavaDoc s, Throwable JavaDoc t) {
145         try {
146             if(checkSize++ >= CHECK_SIZE_EACH_WRITES) {
147                 checkSize = 0;
148                 closeWriter();
149                 if (maxFileSize > 0 && FileUtils.length(fileName) > maxFileSize) {
150                     String JavaDoc old = fileName + ".old";
151                     if (FileUtils.exists(old)) {
152                         FileUtils.delete(old);
153                     }
154                     FileUtils.rename(fileName, old);
155                 }
156             }
157             if(!openWriter()) {
158                 return;
159             }
160             printWriter.println(s);
161             if (t != null) {
162                 t.printStackTrace(printWriter);
163             }
164             printWriter.flush();
165             if(closed) {
166                 closeWriter();
167             }
168         } catch (Exception JavaDoc e) {
169             logWritingError(e);
170         }
171     }
172     
173     private void logWritingError(Exception JavaDoc e) {
174         // TODO translate trace messages
175
SQLException JavaDoc se = Message.getSQLException(Message.LOG_FILE_ERROR_1, new String JavaDoc[] { fileName }, e);
176         // print this error only once
177
fileName = null;
178         System.out.println(se);
179         se.printStackTrace();
180     }
181     
182     private boolean openWriter() throws IOException JavaDoc {
183         if(printWriter == null) {
184             try {
185                 FileUtils.createDirs(fileName);
186                 if(FileUtils.exists(fileName) && FileUtils.isReadOnly(fileName)) {
187                     // read only database: don't log error if the trace file can't be opened
188
return false;
189                 }
190                 fileWriter = FileUtils.openFileWriter(fileName, true);
191                 printWriter = new PrintWriter JavaDoc(fileWriter, true);
192             } catch(SQLException JavaDoc e) {
193                 return false;
194             }
195         }
196         return true;
197     }
198     
199     private synchronized void closeWriter() {
200         if(printWriter != null) {
201             printWriter.flush();
202             printWriter.close();
203             printWriter = null;
204         }
205         if(fileWriter != null) {
206             try {
207                 fileWriter.close();
208             } catch(IOException JavaDoc e) {
209                 // ignore exception
210
}
211             fileWriter = null;
212         }
213     }
214     
215     public void close() {
216         closeWriter();
217         closed = true;
218     }
219     
220     protected void finalize() {
221         if(!Constants.RUN_FINALIZERS) {
222             return;
223         }
224         close();
225     }
226
227 }
228
Popular Tags