1 /*--------------------------------------------------------------------------
2 * Copyright 2007 Taro L. Saito
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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 //--------------------------------------
24 //--------------------------------------
25 package org.xerial.util.log;
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;
37 import org.xerial.util.StringUtil;
47 private static String[] logPrefix = { "", // ALL
48 "\033[0;32m", // TRACE
52 "\033[1;35m", // ERROR
53 "\033[1;31m", // FATAL
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;
64 private static TreeMap<String, Logger> _loggerHolder = new TreeMap<String, Logger>();
65 private static Logger _rootLogger = new Logger();
69 _rootLogger.setLogLevel(LogLevel.INFO);
70 _rootLogger.setOutputWriter(new OutputStreamWriter(System.err));
71 _rootLogger._loggerFullName = "root";
72 _rootLogger._loggerShortName = "root";
74 String logLevel = System.getProperty("xerial.loglevel");
77 _rootLogger.setLogLevel(logLevel);
81 logLevel = System.getProperty("loglevel");
84 _rootLogger.setLogLevel(logLevel);
88 String useColor = System.getProperty("log.color");
90 _rootLogger._emitEscapeSequence = Boolean.parseBoolean(useColor);
92 String loggerConfigFile = System.getProperty("log.config");
93 if (loggerConfigFile != null)
97 Logger.configure(loggerConfigFile);
115 private Logger(String fullTypeName)
117 _loggerFullName = fullTypeName;
118 String[] packageList = _loggerFullName.split("\\.");
119 _loggerShortName = packageList[packageList.length - 1];
120 if (packageList.length == 1)
121 _parentLogger = _rootLogger;
124 String parentPackageName = concatinate(packageList, packageList.length - 1);
125 _parentLogger = getLogger(parentPackageName);
129 private String concatinate(String[] packageList, int upTo)
131 StringBuilder builder = new StringBuilder();
132 for (int i = 0; i < upTo - 1; i++)
134 builder.append(packageList[i]);
137 builder.append(packageList[upTo - 1]);
138 return builder.toString();
141 public static Logger getLogger(Class< ? > c)
143 return getLogger(c.getName());
146 public static Logger getLogger(Class< ? > c, String suffix)
148 if (suffix == null || suffix.length() <= 0)
151 return getLogger(String.format("%s-%s", c.getName(), suffix));
154 public static Logger getLogger(Package p)
156 return getLogger(p.getName());
159 public static synchronized Logger getLogger(String fullTypeName)
161 if (fullTypeName == null)
164 if (_loggerHolder.containsKey(fullTypeName))
165 return _loggerHolder.get(fullTypeName);
168 Logger newLogger = new Logger(fullTypeName);
169 _loggerHolder.put(fullTypeName, newLogger);
170 newLogger._emitEscapeSequence = _rootLogger._emitEscapeSequence;
175 public static Logger getRootLogger()
180 public static void configure(String configFile) throws IOException
182 configure(new BufferedReader(new FileReader(configFile)));
185 public static void configure(Reader configurationFileReader) throws IOException
187 Properties configProperties = new Properties();
189 StringBuilder sb = new StringBuilder();
191 while ((ch = configurationFileReader.read()) > 0)
193 sb.append((char) ch);
195 ByteArrayInputStream bs = new ByteArrayInputStream(sb.toString().getBytes());
196 configProperties.load(bs);
198 for (Object key : configProperties.keySet())
200 String[] lhs = ((String) key).split("#");
201 String loggerName = lhs[0];
202 String value = configProperties.getProperty(key.toString());
203 Logger logger = getLogger(loggerName);
206 logger.setLogLevel(value);
208 else if (lhs.length > 1)
210 // packageName:parameter = value configuration
211 String parameter = lhs[1];
212 if (parameter.equals("color"))
214 logger.setColor(Boolean.parseBoolean(value));
218 System.err.println("unknown configuration parameter: " + parameter);
223 System.err.println("Error in the logger configuration file: " + key);
228 public String getLoggerName()
230 return _loggerFullName;
233 public void setLogLevel(LogLevel logLevel)
235 this._threshold = logLevel;
238 public void setLogLevel(String logLevel)
240 for (LogLevel l : LogLevel.values())
242 if (l.name().equalsIgnoreCase(logLevel))
249 warn("unknown log level: " + logLevel);
252 public LogLevel getLogLevel()
257 public void setOutputWriter(Writer writer)
262 public boolean trace(Object message)
264 log(LogLevel.TRACE, message);
268 public boolean debug(Object message)
270 log(LogLevel.DEBUG, message);
274 public boolean info(Object message)
276 log(LogLevel.INFO, message);
280 public boolean warn(Object message)
282 log(LogLevel.WARN, message);
286 public boolean error(Object message)
288 log(LogLevel.ERROR, message);
292 public boolean fatal(Object message)
294 log(LogLevel.FATAL, message);
299 * Use colored console outputs using escape sequences
304 public void setColor(boolean enable)
306 _emitEscapeSequence = enable;
310 * @return true when escape sequence is used to output the log
312 public boolean isColorEnabled()
314 return _emitEscapeSequence;
317 public boolean isDebugEnabled()
319 return isEnabled(LogLevel.DEBUG);
322 public boolean isTraceEnabled()
324 return isEnabled(LogLevel.TRACE);
327 public boolean isInfoEnabled()
329 return isEnabled(LogLevel.INFO);
332 public boolean isWarnEnabled()
334 return isEnabled(LogLevel.WARN);
337 public boolean isErrorEnabled()
339 return isEnabled(LogLevel.ERROR);
342 public boolean isFatalEnalbed()
344 return isEnabled(LogLevel.FATAL);
347 public boolean isEnabled(LogLevel logLevel)
349 if (_threshold == LogLevel.UNSPECIFIED)
351 Logger parent = this;
352 while ((parent = parent._parentLogger) != null)
354 if (parent.getLogLevel() == LogLevel.UNSPECIFIED)
357 _threshold = parent.getLogLevel();
360 if (_threshold == LogLevel.UNSPECIFIED)
363 return _threshold.ordinal() <= logLevel.ordinal();
366 private Writer getWriter()
372 if (_parentLogger != null)
373 return _parentLogger.getWriter();
379 private void log(LogLevel logLevel, Object message)
381 if (!isEnabled(logLevel))
384 Writer logOut = getWriter();
386 return; // no output is specified
390 if (_emitEscapeSequence)
391 logOut.write(logPrefix[logLevel.ordinal()]);
392 logOut.write("[" + _loggerShortName + "]\t");
394 logOut.write(message.toString());
395 if (_emitEscapeSequence)
396 logOut.write("\033[0m");
397 logOut.write(StringUtil.newline());
400 catch (IOException e)