OSDN Git Service

Renamed Cell as TupleElement
[xerial/xerial-core.git] / src / main / java / org / xerial / util / log / Logger.java
1 /*--------------------------------------------------------------------------
2  *  Copyright 2007 Taro L. Saito
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  *--------------------------------------------------------------------------*/
16 //--------------------------------------
17 // XerialJ Project
18 //
19 // Logger.java
20 // Since: Jul 9, 2007
21 //
22 // $URL$ 
23 // $Author$
24 //--------------------------------------
25 package org.xerial.util.log;
26
27 import java.io.BufferedReader;
28 import java.io.ByteArrayInputStream;
29 import java.io.FileReader;
30 import java.io.IOException;
31 import java.io.OutputStreamWriter;
32 import java.io.Reader;
33 import java.io.Writer;
34 import java.util.Properties;
35 import java.util.TreeMap;
36
37 import org.xerial.util.StringUtil;
38
39 /**
40  * Logger
41  * 
42  * @author leo
43  * 
44  */
45 public class Logger
46 {
47     private static String[] logPrefix = { "", // ALL
48             "\033[0;32m", // TRACE
49             "", // DEBUG
50             "\033[1;36m", // INFO
51             "\033[1;33m", // WARN
52             "\033[1;35m", // ERROR
53             "\033[1;31m", // FATAL
54             "", // OFF
55             "", };
56
57     private Writer _out = null;
58     private LogLevel _threshold = LogLevel.UNSPECIFIED;
59     private String _loggerFullName = "";
60     private String _loggerShortName = "";
61     private Logger _parentLogger = null;
62     private boolean _emitEscapeSequence = false;
63
64     private static TreeMap<String, Logger> _loggerHolder = new TreeMap<String, Logger>();
65     private static Logger _rootLogger = new Logger();
66
67     static
68     {
69         _rootLogger.setLogLevel(LogLevel.INFO);
70         _rootLogger.setOutputWriter(new OutputStreamWriter(System.err));
71         _rootLogger._loggerFullName = "root";
72         _rootLogger._loggerShortName = "root";
73
74         String logLevel = System.getProperty("xerial.loglevel");
75         if (logLevel != null)
76         {
77             _rootLogger.setLogLevel(logLevel);
78         }
79         else
80         {
81             logLevel = System.getProperty("loglevel");
82             if (logLevel != null)
83             {
84                 _rootLogger.setLogLevel(logLevel);
85             }
86         }
87
88         String useColor = System.getProperty("log.color");
89         if (useColor != null)
90             _rootLogger._emitEscapeSequence = Boolean.parseBoolean(useColor);
91
92         String loggerConfigFile = System.getProperty("log.config");
93         if (loggerConfigFile != null)
94         {
95             try
96             {
97                 Logger.configure(loggerConfigFile);
98             }
99             catch (IOException e)
100             {
101                 e.printStackTrace();
102             }
103         }
104
105     }
106
107     /**
108      * hide constructor
109      */
110     private Logger()
111     {
112
113     }
114
115     private Logger(String fullTypeName)
116     {
117         _loggerFullName = fullTypeName;
118         String[] packageList = _loggerFullName.split("\\.");
119         _loggerShortName = packageList[packageList.length - 1];
120         if (packageList.length == 1)
121             _parentLogger = _rootLogger;
122         else
123         {
124             String parentPackageName = concatinate(packageList, packageList.length - 1);
125             _parentLogger = getLogger(parentPackageName);
126         }
127     }
128
129     private String concatinate(String[] packageList, int upTo)
130     {
131         StringBuilder builder = new StringBuilder();
132         for (int i = 0; i < upTo - 1; i++)
133         {
134             builder.append(packageList[i]);
135             builder.append(".");
136         }
137         builder.append(packageList[upTo - 1]);
138         return builder.toString();
139     }
140
141     public static Logger getLogger(Class< ? > c)
142     {
143         return getLogger(c.getName());
144     }
145
146     public static Logger getLogger(Class< ? > c, String suffix)
147     {
148         if (suffix == null || suffix.length() <= 0)
149             return getLogger(c);
150         else
151             return getLogger(String.format("%s-%s", c.getName(), suffix));
152     }
153
154     public static Logger getLogger(Package p)
155     {
156         return getLogger(p.getName());
157     }
158
159     public static synchronized Logger getLogger(String fullTypeName)
160     {
161         if (fullTypeName == null)
162             return _rootLogger;
163
164         if (_loggerHolder.containsKey(fullTypeName))
165             return _loggerHolder.get(fullTypeName);
166         else
167         {
168             Logger newLogger = new Logger(fullTypeName);
169             _loggerHolder.put(fullTypeName, newLogger);
170             newLogger._emitEscapeSequence = _rootLogger._emitEscapeSequence;
171             return newLogger;
172         }
173     }
174
175     public static Logger getRootLogger()
176     {
177         return _rootLogger;
178     }
179
180     public static void configure(String configFile) throws IOException
181     {
182         configure(new BufferedReader(new FileReader(configFile)));
183     }
184
185     public static void configure(Reader configurationFileReader) throws IOException
186     {
187         Properties configProperties = new Properties();
188
189         StringBuilder sb = new StringBuilder();
190         int ch;
191         while ((ch = configurationFileReader.read()) > 0)
192         {
193             sb.append((char) ch);
194         }
195         ByteArrayInputStream bs = new ByteArrayInputStream(sb.toString().getBytes());
196         configProperties.load(bs);
197
198         for (Object key : configProperties.keySet())
199         {
200             String[] lhs = ((String) key).split("#");
201             String loggerName = lhs[0];
202             String value = configProperties.getProperty(key.toString());
203             Logger logger = getLogger(loggerName);
204             if (lhs.length <= 1)
205             {
206                 logger.setLogLevel(value);
207             }
208             else if (lhs.length > 1)
209             {
210                 // packageName:parameter = value configuration
211                 String parameter = lhs[1];
212                 if (parameter.equals("color"))
213                 {
214                     logger.setColor(Boolean.parseBoolean(value));
215                 }
216                 else
217                 {
218                     System.err.println("unknown configuration parameter: " + parameter);
219                 }
220             }
221             else
222             {
223                 System.err.println("Error in the logger configuration file: " + key);
224             }
225         }
226     }
227
228     public String getLoggerName()
229     {
230         return _loggerFullName;
231     }
232
233     public void setLogLevel(LogLevel logLevel)
234     {
235         this._threshold = logLevel;
236     }
237
238     public void setLogLevel(String logLevel)
239     {
240         for (LogLevel l : LogLevel.values())
241         {
242             if (l.name().equalsIgnoreCase(logLevel))
243             {
244                 setLogLevel(l);
245                 return;
246             }
247         }
248
249         warn("unknown log level: " + logLevel);
250     }
251
252     public LogLevel getLogLevel()
253     {
254         return _threshold;
255     }
256
257     public void setOutputWriter(Writer writer)
258     {
259         this._out = writer;
260     }
261
262     public boolean trace(Object message)
263     {
264         log(LogLevel.TRACE, message);
265         return true;
266     }
267
268     public boolean debug(Object message)
269     {
270         log(LogLevel.DEBUG, message);
271         return true;
272     }
273
274     public boolean info(Object message)
275     {
276         log(LogLevel.INFO, message);
277         return true;
278     }
279
280     public boolean warn(Object message)
281     {
282         log(LogLevel.WARN, message);
283         return true;
284     }
285
286     public boolean error(Object message)
287     {
288         log(LogLevel.ERROR, message);
289         return true;
290     }
291
292     public boolean fatal(Object message)
293     {
294         log(LogLevel.FATAL, message);
295         return true;
296     }
297
298     /**
299      * Use colored console outputs using escape sequences
300      * 
301      * @param enable
302      * @return
303      */
304     public void setColor(boolean enable)
305     {
306         _emitEscapeSequence = enable;
307     }
308
309     /**
310      * @return true when escape sequence is used to output the log
311      */
312     public boolean isColorEnabled()
313     {
314         return _emitEscapeSequence;
315     }
316
317     public boolean isDebugEnabled()
318     {
319         return isEnabled(LogLevel.DEBUG);
320     }
321
322     public boolean isTraceEnabled()
323     {
324         return isEnabled(LogLevel.TRACE);
325     }
326
327     public boolean isInfoEnabled()
328     {
329         return isEnabled(LogLevel.INFO);
330     }
331
332     public boolean isWarnEnabled()
333     {
334         return isEnabled(LogLevel.WARN);
335     }
336
337     public boolean isErrorEnabled()
338     {
339         return isEnabled(LogLevel.ERROR);
340     }
341
342     public boolean isFatalEnalbed()
343     {
344         return isEnabled(LogLevel.FATAL);
345     }
346
347     public boolean isEnabled(LogLevel logLevel)
348     {
349         if (_threshold == LogLevel.UNSPECIFIED)
350         {
351             Logger parent = this;
352             while ((parent = parent._parentLogger) != null)
353             {
354                 if (parent.getLogLevel() == LogLevel.UNSPECIFIED)
355                     continue;
356
357                 _threshold = parent.getLogLevel();
358                 break;
359             }
360             if (_threshold == LogLevel.UNSPECIFIED)
361                 return false;
362         }
363         return _threshold.ordinal() <= logLevel.ordinal();
364     }
365
366     private Writer getWriter()
367     {
368         if (_out != null)
369             return _out;
370         else
371         {
372             if (_parentLogger != null)
373                 return _parentLogger.getWriter();
374             else
375                 return null;
376         }
377     }
378
379     private void log(LogLevel logLevel, Object message)
380     {
381         if (!isEnabled(logLevel))
382             return;
383
384         Writer logOut = getWriter();
385         if (logOut == null)
386             return; // no output is specified
387
388         try
389         {
390             if (_emitEscapeSequence)
391                 logOut.write(logPrefix[logLevel.ordinal()]);
392             logOut.write("[" + _loggerShortName + "]\t");
393             if (message != null)
394                 logOut.write(message.toString());
395             if (_emitEscapeSequence)
396                 logOut.write("\033[0m");
397             logOut.write(StringUtil.newline());
398             logOut.flush();
399         }
400         catch (IOException e)
401         {
402             e.printStackTrace();
403         }
404     }
405 }