1. /*
  2. * @(#)TraceImplementation.java 1.17 03/12/19
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.jmx.trace;
  8. import java.io.FileOutputStream;
  9. import java.io.IOException;
  10. import java.io.PrintWriter;
  11. /**
  12. * Example implementation of the {@link TraceDestination} interface.
  13. * <br>
  14. * This implementation sends log records to a file (specified by the value of the
  15. * <code>com.sun.jmx.trace.file</code> system property) or to the system
  16. * console if no file is specified.
  17. * <br>
  18. * The log level is specified by the value of system property
  19. * <code>com.sun.jmx.trace.level</code>, which can be : <code>DEBUG</code>,
  20. * <code>TRACE</code>, <code>ERROR</code>. If no trace level is specified, the
  21. * default is <code>ERROR</code>.
  22. * <br>
  23. * Note that this implementation does not provide any filtering based on the log
  24. * types. More precisely, the implementation of method {@link #isSelected} only
  25. * checks the provided log level.
  26. *
  27. * @since 1.5
  28. */
  29. public class TraceImplementation implements TraceDestination
  30. {
  31. // output stream
  32. //
  33. private PrintWriter out;
  34. // log level
  35. //
  36. private int level;
  37. static TraceImplementation newDestination(int level)
  38. {
  39. try {
  40. final TraceImplementation impl = new TraceImplementation();
  41. impl.level = level;
  42. return impl;
  43. } catch (IOException x) {
  44. return null;
  45. }
  46. }
  47. /**
  48. * Registers a new instance of class {@link TraceImplementation} as the
  49. * trace destination in class {@link Trace}.
  50. *
  51. * @exception IOException
  52. * may be thrown when creating the new log file based on the
  53. * value of system property <code>com.sun.jmx.trace.file</code>
  54. * @see Trace#setDestination
  55. */
  56. public static void init() throws IOException
  57. {
  58. Trace.setDestination(new TraceImplementation());
  59. }
  60. /**
  61. * Registers a new instance of class {@link TraceImplementation} as the
  62. * trace destination in class {@link Trace}.
  63. *
  64. * @param level Initial trace level (see {@link TraceTags})
  65. * @exception IOException
  66. * may be thrown when creating the new log file based on the
  67. * value of system property <code>com.sun.jmx.trace.file</code>
  68. * @see Trace#setDestination
  69. */
  70. public static void init(int level) throws IOException
  71. {
  72. final TraceImplementation impl = new TraceImplementation();
  73. impl.level = level;
  74. Trace.setDestination(impl);
  75. }
  76. /**
  77. * Constructor.
  78. * @exception IOException
  79. * may be thrown when creating the new log file based on the
  80. * value of system property <code>com.sun.jmx.trace.file</code>
  81. */
  82. public TraceImplementation() throws IOException
  83. {
  84. String filename;
  85. if ((filename = System.getProperty("com.sun.jmx.trace.file")) != null)
  86. {
  87. // Output sent to the specified log file
  88. //
  89. this.out = new PrintWriter(new FileOutputStream(filename), true);
  90. }
  91. else
  92. {
  93. // Output sent to the system console
  94. //
  95. this.out = new PrintWriter(System.err, true);
  96. }
  97. String level;
  98. if ((level = System.getProperty("com.sun.jmx.trace.level")) != null)
  99. {
  100. // Read log level from value of system property
  101. //
  102. if (level.equals("DEBUG"))
  103. {
  104. this.level = TraceTags.LEVEL_DEBUG;
  105. }
  106. else if (level.equals("TRACE"))
  107. {
  108. this.level = TraceTags.LEVEL_TRACE;
  109. }
  110. else
  111. {
  112. this.level = TraceTags.LEVEL_ERROR;
  113. }
  114. }
  115. else
  116. {
  117. // Log level defaults to ERROR
  118. //
  119. this.level = TraceTags.LEVEL_ERROR;
  120. }
  121. }
  122. /**
  123. * Only tests whether the provided log level will generate some output if
  124. * used as an argument to {@link #send(int, int, String, String, Throwable)}
  125. * or {@link #send(int, int, String, String, String)}
  126. *
  127. * @see TraceDestination#isSelected
  128. */
  129. public boolean isSelected(int level, int type)
  130. {
  131. return (level <= this.level);
  132. }
  133. /**
  134. * @see TraceDestination#send(int, int, String, String, String)
  135. */
  136. public boolean send(int level,
  137. int type,
  138. String className,
  139. String methodName,
  140. String info)
  141. {
  142. if (isSelected(level, type))
  143. {
  144. out.println(((className!=null)?"Class: " + className:"")+
  145. ((methodName!=null)?"\nMethod: " + methodName:"") +
  146. "\n\tlevel: " + getLevel(level) +
  147. "\n\ttype: " + getType(type) +
  148. "\n\tmessage: " + info);
  149. //out.flush();
  150. return true;
  151. }
  152. return false;
  153. }
  154. /**
  155. * @see TraceDestination#send(int, int, String, String, Throwable)
  156. */
  157. public boolean send(int level,
  158. int type,
  159. String className,
  160. String methodName,
  161. Throwable exception)
  162. {
  163. final boolean result = send(level, type, className, methodName,
  164. exception.toString());
  165. if (result)
  166. exception.printStackTrace(out);
  167. return result;
  168. }
  169. /**
  170. * Not implemented.
  171. *
  172. * @see TraceDestination#reset
  173. **/
  174. public void reset() throws IOException
  175. {
  176. }
  177. /**
  178. * Return the string representation of a trace type, as defined in
  179. * {@link TraceTags}
  180. */
  181. private static String getType(int type) {
  182. switch (type) {
  183. case TraceTags.INFO_MBEANSERVER:
  184. return "INFO_MBEANSERVER";
  185. case TraceTags.INFO_ADAPTOR_SNMP:
  186. return "INFO_ADAPTOR_SNMP";
  187. case TraceTags.INFO_SNMP:
  188. return "INFO_SNMP";
  189. case TraceTags.INFO_MLET:
  190. return "INFO_MLET";
  191. case TraceTags.INFO_MONITOR:
  192. return "INFO_MONITOR";
  193. case TraceTags.INFO_TIMER:
  194. return "INFO_TIMER";
  195. case TraceTags.INFO_MISC:
  196. return "INFO_MISC";
  197. case TraceTags.INFO_NOTIFICATION:
  198. return "INFO_NOTIFICATION";
  199. case TraceTags.INFO_RELATION:
  200. return "INFO_RELATION";
  201. case TraceTags.INFO_MODELMBEAN:
  202. return "INFO_MODELMBEAN";
  203. default:
  204. return "UNKNOWN_TRACE_TYPE";
  205. }
  206. }
  207. /**
  208. * Return the string representation of a trace level, as defined in
  209. * {@link TraceTags}
  210. */
  211. private static String getLevel(int level) {
  212. switch (level) {
  213. case TraceTags.LEVEL_ERROR:
  214. return "LEVEL_ERROR";
  215. case TraceTags.LEVEL_TRACE:
  216. return "LEVEL_TRACE";
  217. case TraceTags.LEVEL_DEBUG:
  218. return "LEVEL_DEBUG";
  219. default :
  220. return "UNKNOWN_TRACE_LEVEL";
  221. }
  222. }
  223. }