001: package Shared.Logging;
002:
003: import java.io.IOException;
004: import java.util.ArrayList;
005: import Shared.Logging.Internal.*;
006:
007: /**
008: * My simple log package.
009: * Just call one of the static methods:
010: * Trace(), Info(), Warn() and Error().
011: *
012: * Additionally, one can set the log level by a call to the
013: * static method SetLogLevel() and pass one of the static ints:
014: * TraceLevel, InfoLevel, WarnLevel, ErrorLevel, or
015: * NoLogLevel, which turns out logging.
016: */
017: public class Log {
018: // Log levels:
019: // If the log level is set to NoLogLevel, logging is turned off.
020: public static final int TraceLevel = 0;
021: public static final int InfoLevel = 1;
022: public static final int WarnLevel = 2;
023: public static final int ErrorLevel = 3;
024: public static final int NoLogLevel = 4;
025:
026: private static Log LogManager = null;
027: private static int LogLevel = 0; // LogLevel default is trace.
028:
029: private static String BasisFileName = "log";
030:
031: private static boolean EnableSocketLogger = false;
032: private static boolean EnableFileLogger = false;
033: private static String Host;
034: private static int Port;
035:
036: private static String LogIdentifier = ""; // must not be null
037:
038: // The identification string, which must be sent by SocketLoggers
039: // to SocketLogReceivers as first data.
040: // The socket loggers will close their socket, if this is not
041: // received as first data
042: public static final String SocketLoggerIdentification = "qoifds598762308alfdshwlrekh";
043:
044: private ArrayList<GenericLogger> loggers = new ArrayList<GenericLogger>();
045:
046: /**
047: * Default values for the file logger:
048: */
049: private static int NumberOfFiles = 20; // 20 files
050: private static int FileSizeLimitInBytes = 1000000; // 1MB per file
051:
052: /**
053: * Private constructor
054: */
055: private Log() {
056:
057: // append loggers:
058: this .loggers.add(new ConsoleLogger(LogIdentifier));
059:
060: if (EnableSocketLogger) {
061: this .loggers
062: .add(new SocketLogger(LogIdentifier, Host, Port));
063: }
064:
065: if (EnableFileLogger) {
066: String basisTargetFileName = BasisFileName;
067: String targetFileEnding = "txt";
068: String basisTargetDirectoryPath = System
069: .getProperty("user.dir");
070: try {
071: FileLogger fileLogger = new FileLogger(LogIdentifier,
072: basisTargetFileName, targetFileEnding,
073: basisTargetDirectoryPath, NumberOfFiles,
074: FileSizeLimitInBytes);
075: this .loggers.add(fileLogger);
076: } catch (IOException ioe) {
077: System.out
078: .println("Log: Unable to create the file logger:");
079: ioe.printStackTrace();
080: }
081: }
082:
083: // Add a shutdown hook to close open streams.
084: try {
085: Runtime.getRuntime().addShutdownHook(new ShutdownTask());
086: } catch (IllegalStateException e) {
087: // If the VM is already shutting down,
088: // We do not need to register shutdownHook.
089: }
090: } // Constructor
091:
092: /**
093: * Sets the log identifier which is written out on the beginning of
094: * each log textline, before the loglevel text.
095: */
096: public void updateLogIdentifier() {
097: // set it in all loggers:
098: for (int i = 0; i < loggers.size(); i++) {
099: loggers.get(i).setLogIdentifier(LogIdentifier);
100: }
101: }
102:
103: /**
104: * Sets the number of files for the file logger.
105: * To be called, before Log is used for logging.
106: */
107: public static void SetNumberOfFiles(int numberOfFiles) {
108: NumberOfFiles = numberOfFiles;
109: }
110:
111: /**
112: * Sets the file size for the file logger.
113: * To be called, before Log is used for logging.
114: */
115: public static void SetFileSizeLimitInBytes(int fileSizeLimitInBytes) {
116: FileSizeLimitInBytes = fileSizeLimitInBytes;
117: }
118:
119: /**
120: * Sets the basis file name.
121: * To be called, before Log is used for logging.
122: */
123: public static void SetBasisFileName(String basisFileName) {
124: BasisFileName = basisFileName;
125: }
126:
127: /**
128: * Enables socket logging to host, port.
129: * To be called, before Log is used for logging.
130: */
131: public static void EnableSocketLogger(String host, int port) {
132: EnableSocketLogger = true;
133: Host = host;
134: Port = port;
135: }
136:
137: /**
138: * Enables file logging.
139: * To be called, before Log is used for logging.
140: */
141: public static void EnableFileLogger() {
142: EnableFileLogger = true;
143: }
144:
145: private class ShutdownTask extends Thread {
146: public void run() {
147: for (int i = 0; i < loggers.size(); i++) {
148: loggers.get(i).terminate();
149: }
150: }
151: }
152:
153: public synchronized void publish(int level, String message) {
154: String levelName;
155: switch (level) {
156: case TraceLevel:
157: levelName = "Trace";
158: break;
159: case InfoLevel:
160: levelName = "Info";
161: break;
162: case WarnLevel:
163: levelName = "Warn";
164: break;
165: case ErrorLevel:
166: levelName = "Error";
167: break;
168: case NoLogLevel:
169: levelName = "NoLog";
170: break;
171: default:
172: levelName = "undefined";
173: }
174: for (int i = 0; i < this .loggers.size(); i++) {
175: this .loggers.get(i).publish(levelName, message);
176: }
177: }
178:
179: public synchronized void publish(int level, Throwable throwable) {
180: String levelName;
181: switch (level) {
182: case TraceLevel:
183: levelName = "Trace";
184: break;
185: case InfoLevel:
186: levelName = "Info";
187: break;
188: case WarnLevel:
189: levelName = "Warn";
190: break;
191: case ErrorLevel:
192: levelName = "Error";
193: break;
194: case NoLogLevel:
195: levelName = "NoLog";
196: break;
197: default:
198: levelName = "undefined";
199: }
200: for (int i = 0; i < this .loggers.size(); i++) {
201: this .loggers.get(i).publish(levelName, throwable);
202: }
203: }
204:
205: public synchronized void publishDirectly(String message) {
206: for (int i = 0; i < this .loggers.size(); i++) {
207: this .loggers.get(i).publishDirectly(message);
208: }
209: }
210:
211: /* ---------------- public static methods ------------------ */
212:
213: public static void SetLogLevel(int newLogLevel) {
214: LogLevel = newLogLevel;
215: }
216:
217: /**
218: * This static method can be called anytime to set a log identifier.
219: * The passed identifier is written out on the beginning of
220: * each log textline, before the loglevel text.
221: */
222: public static void SetLogIdentifier(String identifier) {
223: // Don't allow the LogIdentifier to become null
224: if (identifier != null) {
225: LogIdentifier = identifier.trim();
226: } else {
227: LogIdentifier = "";
228: }
229: // If the LogManager instance already exists, update all loggers:
230: if (LogManager != null) {
231: LogManager.updateLogIdentifier();
232: }
233: }
234:
235: public static void Trace(String message) {
236: if (LogLevel <= TraceLevel) {
237: if (LogManager == null)
238: LogManager = new Log();
239: LogManager.publish(TraceLevel, message);
240: }
241: }
242:
243: /**
244: * This is a special mode: It just outputs the
245: * passed message directly without formatting it.
246: */
247: public static void DirectOutput(String message) {
248: if (LogManager == null)
249: LogManager = new Log();
250: LogManager.publishDirectly(message);
251: }
252:
253: public static void Info(String message) {
254: if (LogLevel <= InfoLevel) {
255: if (LogManager == null)
256: LogManager = new Log();
257: LogManager.publish(InfoLevel, message);
258: }
259: }
260:
261: public static void Info(Throwable throwable) {
262: if (LogLevel <= InfoLevel) {
263: if (LogManager == null)
264: LogManager = new Log();
265: LogManager.publish(InfoLevel, throwable);
266: }
267: }
268:
269: public static void Warn(String message) {
270: if (LogLevel <= WarnLevel) {
271: if (LogManager == null)
272: LogManager = new Log();
273: LogManager.publish(WarnLevel, message);
274: }
275: }
276:
277: public static void Warn(Throwable throwable) {
278: if (LogLevel <= WarnLevel) {
279: if (LogManager == null)
280: LogManager = new Log();
281: LogManager.publish(WarnLevel, throwable);
282: }
283: }
284:
285: public static void Error(String message) {
286: if (LogLevel <= ErrorLevel) {
287: if (LogManager == null)
288: LogManager = new Log();
289: LogManager.publish(ErrorLevel, message);
290: }
291: }
292:
293: public static void Error(Throwable throwable) {
294: if (LogLevel <= ErrorLevel) {
295: if (LogManager == null)
296: LogManager = new Log();
297: LogManager.publish(ErrorLevel, throwable);
298: }
299: }
300:
301: } // LogInitializer
|