1
2
3
4
5 package org.astrogrid.log;
6
7 import org.apache.commons.logging.*;
8
9 import java.io.IOException;
10 import java.io.OutputStream;
11 import java.util.Date;
12
13 /***
14 * A covenience singleton, providing easy to use access to logging facilities,
15 * for example:
16 * <pre>
17 * Log.logError("Could not do task xxx");
18 * or
19 * Log.logError("Could not do task xxxx",exception);
20 * </pre>
21 * if you have an exception to log.
22 * <p>
23 * trace code can be logged as follows:
24 * <pre>
25 * Log.trace("Starting xxx...");
26 * </pre>
27 * and turned on/off by:
28 * <pre>
29 * Log.traceOn();
30 * or
31 * Log.traceOff();
32 * </pre>
33 * <p>
34 * Assertion-style checks can be made as follows:
35 * <pre>
36 * Log.affirm(condition that should be true, "Message if it is not");
37 * </pre>
38 * ('assert' has become a keyword in JDK 1.4)
39 *
40 * The purpose of this class is to act as a 'wrapper' around whatever
41 * implentation of error, trace & userMessage logging the astrogrid project settles
42 * on. If and when the project switches from using one to another, this class
43 * will be rewritten to route messages to the new system.
44 * <p>
45 * The methods are all static, so that routines that need to report errors do not
46 * need to be concerned about tracking log instances. So it is <i>easier</i> for the programmer
47 * to use this rather than System,out.println etc, as this will also print exceptions and log it
48 * all to file if required.
49 * <p>
50 * <b>Note</b> that this is not some abstracted/factoried class. Its
51 * purpose is to reduce the work of porting; therefore it is not an implementation
52 * of some generalised abstract interface. An implementation of an interface, with highly generalised
53 * methods, would tend to break at runtime, the last place you want a logging
54 * system to break. However if this class is rewritten, and something forgotten
55 * or a method not written correctly, the project will break at compile time.
56 * </p>
57 * In particular this applies to the <code>getImplementation()</code> method. This returns
58 * the actual implementation, so that we can carry out such tasks as setting
59 * up dialog boxes, file logging, etc at the beginning of an application, using
60 * the facilities available for that particular implementation. We do not want
61 * this wrapper to imply that such facilities are available when they are not.
62 * <p>
63 * This static wrapper assumes errors will be logged to the console by default, and there
64 * is also an option for specifying a file to log to. Any more complex requirements
65 * should refer to the implementation using <code>getImplementation()</code>
66 * <p>
67 * This implementation uses the commons-logging package from apache, itself a wrapper
68 * for plugin logging implementations. It exists as a stop-gap measure for code
69 * that still needs to be converted to use commons-logging. It's also a bit easier
70 * to use as it requires no class instances and provides some handy methods for
71 * doing things like logging to file or console...
72 * <p>
73 * Error types. There are two types of errors; alarms and errors. Errors apply
74 * to problems with code; alarms to 'expected' problems with the system. For example, if
75 * the sofware is monitoring equipment and the equipment fails, then an alarm should
76 * be raised. Similarly there are two levels of trace; trace for reporting routing
77 * through code, debug for reporting extra information about state (eg fine failed connection
78 * details).
79 * <P>
80 * @author : M Hill
81 *
82 */
83
84 public class Log
85 {
86 public static boolean traceOn = true;
87
88 private static org.apache.commons.logging.Log
89 logger = LogFactory.getLog( "Application wide" );
90
91
92 /***
93 * A simple static method implementing an assertion check. Named
94 * affirm to avoid JDK 1.4s warnings about using assert. Throws an
95 * implementation-specific assertion (runtime) exception if the condition
96 * is not true
97 */
98 public static void affirm(boolean assertion, String errorMessage)
99 {
100 if (!assertion)
101 {
102 throw new AssertionError(errorMessage);
103 }
104 }
105
106 /*** Convenience method for logging alarms */
107 public static void logAlarm( String userMessage )
108 {
109 logger.error(userMessage);
110 }
111
112 /*** Convenience method for logging alarms */
113 public static void logAlarm(String userMessage, String detailMessage )
114 {
115 logger.error(userMessage+"\n"+detailMessage);
116 }
117
118 /*** Convenience method for logging warnings */
119 public static void logWarning( String userMessage )
120 {
121 logger.warn(userMessage);
122 }
123
124 /*** Convenience method for logging info messages */
125 public static void logInfo( String userMessage )
126 {
127 logger.info(userMessage);
128 }
129
130 /*** Convenience method for logging info messages */
131 public static void logInfo(String userMessage, String usefulInfo )
132 {
133 logger.info(userMessage+"\n"+usefulInfo);
134 }
135
136 /*** Convenience method for logging program errors */
137 public static void logError( String userMessage )
138 {
139 logger.error(userMessage);
140 }
141
142 /*** Convenience method for logging program errors */
143 public static void logError( String userMessage, Throwable th )
144 {
145 logger.error(userMessage, th);
146 }
147
148 /*** Convenience method for logging program errors */
149 public static void logError( String userMessage, String usefulInfo, Throwable th )
150 {
151 logger.error(userMessage+"\n"+usefulInfo, th);
152 }
153
154 /*** Convenience method for logging assertion-style debugging info
155 * and trace output. */
156 public static void logDebug( String userMessage )
157 {
158 logger.debug(userMessage);
159 }
160
161 /*** Convenience method for logging assertion-style debugging info.
162 * For example, if a connection fails, the user will be notified
163 * but you might use this to add more detailed technical
164 * information.*/
165 public static void logDebug( String userMessage, Throwable th )
166 {
167 logger.debug(userMessage, th);
168 }
169
170 /*** Convenience method for adding trace code that can be distributed like
171 * other log messages. */
172 public static void trace( String userMessage )
173 {
174 if (traceOn)
175 {
176 logger.trace(userMessage);
177 }
178 }
179
180 /*** Switch trace on - ie allow trace messages to be logged */
181 public static void traceOn() { setLevelFinest(); traceOn = true; }
182
183 /*** Switch trace off - ie stop trace messages from being logged */
184 public static void traceOff() { traceOn = false; }
185
186 /*** Not strictly necessary, but makes sure that trace code can be logged,
187 * and writes out a 'starting' message to the log, which can be very
188 * useful when trawling through large log files
189 */
190 public static void starting(String msg)
191 {
192 traceOn();
193
194 trace("Logging Started "+new Date()+" "+msg+"...");
195 }
196
197 /*** Makes sure the logging system will log trace code */
198 public static void setLevelFinest()
199 {
200 }
201
202 /*** Direct output to file (as well)
203 */
204 public static void logToFile(String filename) throws IOException
205 {
206
207
208
209 }
210
211 /***
212 * Direct output to stream (as well) in simple format
213 */
214 public static void logToStream(OutputStream out) throws IOException
215 {
216
217 }
218
219 /***
220 * Direct output to stream (as well) in XML format
221 */
222 public static void logXmlToStream(OutputStream out) throws IOException
223 {
224
225 }
226
227 /***
228 * Direct output to console (as well). This is a bit messy for the
229 * built-in logger, which has its own way of outputting to the console
230 * that we need to remove/change
231 */
232 public static void logToConsole() throws IOException
233 {
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260 }
261
262 /***
263 * Returns implementation - this allows applications to do what they need
264 * with the logger, while still letting 99% of the code do its stuff through
265 * the standard methods above. Hopefully giving us the best of all worlds...
266 * <p>Note that this returns the correct class, not some abstract Object,
267 * so that code using it is correctly checked at compile time
268 *
269 public static Logger getImplementation()
270 {
271 return LogFactory.getLog("lklk").
272 //return logger;
273 }
274 */
275
276 /***
277 * Test harness
278 */
279 public static void main(String[] args) throws Exception
280 {
281 Log.trace("Testing Log wrapper...");
282 Log.logError("This is a program error with a runtime exception",new RuntimeException("An example runtime exception"));
283 Log.logAlarm("This is a user alarm","Don't worry about it");
284 Log.logInfo("This is a bit of info that might be routed to a status line");
285 Log.trace("...done basic test");
286
287 }
288
289 }
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321