PageRenderTime 38ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/cc.creativecomputing/src/cc/creativecomputing/util/logging/CCLog.java

http://creativecomputing.googlecode.com/
Java | 326 lines | 205 code | 53 blank | 68 comment | 30 complexity | 2c6adb64f255eb3b9d220e5265cbaf79 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.1
  1. package cc.creativecomputing.util.logging;
  2. import java.io.IOException;
  3. import java.io.PrintWriter;
  4. import java.io.StringWriter;
  5. import java.net.InetAddress;
  6. import java.net.UnknownHostException;
  7. import java.text.SimpleDateFormat;
  8. import java.util.Date;
  9. import java.util.HashMap;
  10. import java.util.logging.FileHandler;
  11. import java.util.logging.Formatter;
  12. import java.util.logging.Level;
  13. import java.util.logging.Logger;
  14. import java.util.logging.SimpleFormatter;
  15. import java.util.logging.SocketHandler;
  16. import java.util.logging.XMLFormatter;
  17. /**
  18. * <p>This is a little wrapper around java.util.logging to create a more convenient
  19. * way to log application states to stderr, stdout and/or a logfile. Usage sample:</p>
  20. * <blockquote><pre>CCLog.warn("what is wrong here?!");</pre></blockquote>
  21. *
  22. * The logger can be configured using environment variables. Default logging to the console
  23. * is always active and cannot be disabled. The logging is enabled while calling CCLog.[warn,error,info]("")
  24. * for the first time.
  25. *
  26. * Available Environment Variables are:
  27. * CC_LOG_HANDLERS=[FILE,TCP] - enable additional handlers. Multiple values allowed
  28. * Note about TCP: the receiver needs to be up and running before the application starts.
  29. * Otherwise an exception will be thrown. There is no reconnection in case of connection
  30. * loss, simple because it takes to long.
  31. *
  32. * Configure console output:
  33. * CC_LOG_CONSOLE_FORMAT=[CCSimpleLogFormatter,SimpleFormatter,XMLFormatter] - choose one.
  34. * CC_LOG_CONSOLE_VERBOSITY=[SEVERE,WARNING,INFO,CONFIG,FINE,FINER,FINEST] - set verbosity level. Default is INFO
  35. *
  36. * Configure file output:
  37. * CC_LOG_FILE_FORMAT=[CCSimpleLogFormatter,SimpleFormatter,XMLFormatter] - choose one.
  38. * CC_LOG_FILE_VERBOSITY=[SEVERE,WARNING,INFO,CONFIG,FINE,FINER,FINEST] - set verbosity level. Default is INFO
  39. * CC_LOG_FILE_PATH=[path to write the logfile to] - Default is "log/"
  40. *
  41. * Configure TCP output:
  42. * CC_LOG_TCP_FORMAT=[CCSimpleLogFormatter,SimpleFormatter,XMLFormatter] - choose one.
  43. * CC_LOG_TCP_VERBOSITY=[SEVERE,WARNING,INFO,CONFIG,FINE,FINER,FINEST] - set verbosity level. Default is INFO
  44. * CC_LOG_TCP_HOST=[hostname] - set the hostname to send the log data to. Default is "127.0.0.1"
  45. * CC_LOG_TCP_PORT=[port] - set the port to send the data to. Default is "6767"
  46. *
  47. * @example cc.creativecomputing.demo.logging;
  48. * @author sebastian heymann
  49. * @nosuperclasses
  50. */
  51. // TODO: Timing the whole thing would be interesting.
  52. // TODO: add more logging functions for FINE, FINER, FINEST.
  53. // TODO: add AC_LOG_MODULE_VERBOSITY style per file verbosity settings.
  54. public class CCLog {
  55. private static HashMap<String, Logger> ourLoggers = new HashMap<String, Logger>();
  56. private static FileHandler ourFileHandler = null;
  57. private static SocketHandler ourTCPHandler = null;
  58. private static boolean ourInitialized = false;
  59. private static String HANDLERS = getEnv("CC_LOG_HANDLERS", "FILE");
  60. private static String CONSOLE_FORMAT = getFormatter("CC_LOG_CONSOLE_FORMAT", "CCSimpleLogFormatter");
  61. private static Level CONSOLE_VERBOSITY = getLevel("CC_LOG_CONSOLE_VERBOSITY", "INFO");
  62. private static String FILE_FORMAT = getFormatter("CC_LOG_FILE_FORMAT", "CCSimpleLogFormatter");
  63. private static Level FILE_VERBOSITY = getLevel("CC_LOG_FILE_VERBOSITY", "INFO");
  64. private static String FILE_PATH = getEnv("CC_LOG_FILE_PATH", "log/");
  65. private static String TCP_FORMAT = getFormatter("CC_LOG_TCP_FORMAT", "CCSimpleLogFormatter");
  66. private static Level TCP_VERBOSITY = getLevel("CC_LOG_TCP_VERBOSITY", "INFO");
  67. private static String TCP_HOST = getEnv("CC_LOG_TCP_HOST", "127.0.0.1");
  68. private static String TCP_PORT = getEnv("CC_LOG_TCP_PORT", "6767");
  69. private static Level getLevel(String theVar, String theDefault) {
  70. String myLevel = getEnv(theVar, theDefault);
  71. Level myNewLevel = Level.INFO;
  72. try {
  73. myNewLevel = Level.parse(myLevel);
  74. } catch (NullPointerException ex) {
  75. return Level.parse(theDefault);
  76. } catch (IllegalArgumentException ex) {
  77. return Level.parse(theDefault);
  78. }
  79. return myNewLevel;
  80. }
  81. private static String getFormatter(String theVar, String theDefault) {
  82. String myFormatter = getEnv(theVar, theDefault);
  83. if (myFormatter == "CCSimpleLogFormatter" ||
  84. myFormatter == "XMLFormatter" ||
  85. myFormatter == "SimpleFormatter")
  86. {
  87. return myFormatter;
  88. }
  89. return theDefault;
  90. }
  91. private static String getEnv(String theVariableName, String theDefaultValue) {
  92. String myValue = System.getenv(theVariableName);
  93. if (myValue == null) {
  94. return theDefaultValue;
  95. }
  96. return myValue;
  97. }
  98. private static Logger getLogger(String loggerName) {
  99. if (!ourInitialized) {
  100. initialize();
  101. }
  102. if (ourLoggers.containsKey(loggerName)) {
  103. return ourLoggers.get(loggerName);
  104. }
  105. Logger myLogger = Logger.getLogger(loggerName);
  106. setConfiguration(myLogger);
  107. ourLoggers.put(loggerName, myLogger);
  108. return myLogger;
  109. }
  110. private static String getFilename() {
  111. String myFilename = "";
  112. // hostname part
  113. try {
  114. InetAddress addr = InetAddress.getLocalHost();
  115. // Get hostname
  116. String hostname = addr.getHostName();
  117. myFilename = hostname;
  118. } catch (UnknownHostException e) {
  119. myFilename = "default";
  120. }
  121. myFilename += "-";
  122. // date part
  123. Date myDate = new Date();
  124. SimpleDateFormat myDateFormat = new SimpleDateFormat("yyyy-MM-dd_kk-mm-ss");
  125. StringBuilder myDateString = new StringBuilder(myDateFormat.format(myDate));
  126. myFilename += myDateString;
  127. // ending
  128. myFilename += ".txt";
  129. return FILE_PATH+myFilename;
  130. }
  131. private static Formatter createFormatter(String theName) {
  132. if (theName == "XMLFormatter")
  133. return new XMLFormatter();
  134. if (theName == "SimpleFormatter")
  135. return new SimpleFormatter();
  136. return new CCSimpleLogFormatter();
  137. }
  138. private static void initialize() {
  139. if (ourFileHandler == null && HANDLERS.contains("FILE")) {
  140. String myLogFilename = getFilename();
  141. try {
  142. ourFileHandler = new FileHandler(myLogFilename);
  143. ourFileHandler.setLevel(FILE_VERBOSITY);
  144. ourFileHandler.setFormatter(createFormatter(FILE_FORMAT));
  145. CCLog.info("logging to file: " + myLogFilename);
  146. } catch (SecurityException e) {
  147. e.printStackTrace();
  148. } catch (IOException e) {
  149. e.printStackTrace();
  150. }
  151. }
  152. if (ourTCPHandler == null && HANDLERS.contains("TCP")) {
  153. try {
  154. ourTCPHandler = new SocketHandler(TCP_HOST, Integer.parseInt(TCP_PORT));
  155. ourTCPHandler.setLevel(TCP_VERBOSITY);
  156. ourTCPHandler.setFormatter(createFormatter(TCP_FORMAT));
  157. CCLog.info("logging to socket: " + TCP_HOST + ":" + TCP_PORT);
  158. } catch (IllegalArgumentException e) {
  159. e.printStackTrace();
  160. } catch (IOException e) {
  161. e.printStackTrace();
  162. }
  163. }
  164. // register CCLogExceptionHandler as default.
  165. CCLogExceptionHandler.register();
  166. Logger logger = Logger.getLogger ("");
  167. if (logger.getHandlers ().length > 0) {
  168. logger.removeHandler (logger.getHandlers ()[0]);
  169. }
  170. // configure default logger
  171. setConfiguration(logger);
  172. ourInitialized = true;
  173. }
  174. private static void setConfiguration(Logger theLogger) {
  175. CCStandardOutHandler myDefaultHandler = new CCStandardOutHandler();
  176. myDefaultHandler.setFormatter(createFormatter(CONSOLE_FORMAT));
  177. theLogger.addHandler(myDefaultHandler);
  178. theLogger.setLevel(CONSOLE_VERBOSITY);
  179. if (ourFileHandler != null) {
  180. theLogger.addHandler(ourFileHandler);
  181. }
  182. if (ourTCPHandler != null) {
  183. theLogger.addHandler(ourTCPHandler);
  184. }
  185. // ignore default parent handler
  186. theLogger.setUseParentHandlers(false);
  187. }
  188. private static void log(Level theLevel, Throwable theMessage) {
  189. final Throwable myT = new Throwable();
  190. final StackTraceElement myMethodCaller = myT.getStackTrace()[2];
  191. Logger myLogger = getLogger(myMethodCaller.getClassName());
  192. String myClass = myMethodCaller.getClassName();
  193. String myMethod = myMethodCaller.getMethodName();
  194. String myBundle = myMethodCaller.getClass().getPackage().toString();
  195. String myException = throwableToString(theMessage);
  196. myLogger.logrb(theLevel, myClass, myMethod, myBundle, myException);
  197. }
  198. private static String throwableToString(Throwable e) {
  199. try {
  200. StringWriter sw = new StringWriter();
  201. PrintWriter pw = new PrintWriter(sw);
  202. e.printStackTrace(pw);
  203. return sw.toString();
  204. } catch(Exception e2) {
  205. e2.printStackTrace();
  206. return "throwableToString error";
  207. }
  208. }
  209. private static void log(Level theLevel, String theMessage) {
  210. final Throwable myT = new Throwable();
  211. final StackTraceElement myMethodCaller = myT.getStackTrace()[2];
  212. Logger myLogger = getLogger(myMethodCaller.getClassName());
  213. String myClass = myMethodCaller.getClassName();
  214. String myMethod = myMethodCaller.getMethodName();
  215. String myBundle = myMethodCaller.getClass().getPackage().toString();
  216. int myLineNumber = myMethodCaller.getLineNumber();
  217. myLogger.logrb(theLevel, myClass + " Line:" + myLineNumber, myMethod, myBundle, theMessage);
  218. }
  219. /**
  220. * Log an exception with WARNING level.
  221. * @param theMessage the message to be logged
  222. */
  223. public static void warn(Throwable theMessage) {
  224. log(Level.WARNING, theMessage);
  225. }
  226. /**
  227. * Log an exception with ERROR level.
  228. * @param theMessage the message to be logged
  229. */
  230. public static void error(Throwable theMessage) {
  231. log(Level.SEVERE, theMessage);
  232. }
  233. /**
  234. * Log an exception with INFO level.
  235. * @param theMessage the message to be logged
  236. */
  237. public static void info(Throwable theMessage) {
  238. log(Level.INFO, theMessage);
  239. }
  240. /**
  241. * Log a message with WARNING level.
  242. * @param theMessage the message to be logged
  243. */
  244. public static void warn(Object theMessage) {
  245. if (theMessage == null) {
  246. log(Level.WARNING, "null");
  247. return;
  248. }
  249. log(Level.WARNING, theMessage.toString());
  250. }
  251. /**
  252. * Log a message with ERROR level.
  253. * @param theMessage the message to be logged
  254. */
  255. public static void error(Object theMessage) {
  256. if (theMessage == null) {
  257. log(Level.SEVERE, "null");
  258. return;
  259. }
  260. log(Level.SEVERE, theMessage.toString());
  261. }
  262. /**
  263. * Log a message with INFO level.
  264. * @param theMessage the message to be logged
  265. */
  266. public static void info(Object theMessage) {
  267. if (theMessage == null) {
  268. log(Level.INFO, "null");
  269. return;
  270. }
  271. log(Level.INFO, theMessage.toString());
  272. }
  273. }