Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

Logger.java 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /*
  2. * Copyright (c) 2006-2008 Chris Smith, Shane Mc Cormack, Gregory Holmes
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. * SOFTWARE.
  21. */
  22. package com.dmdirc.logger;
  23. import com.dmdirc.Main;
  24. import com.dmdirc.config.IdentityManager;
  25. import java.io.File;
  26. import java.io.FileNotFoundException;
  27. import java.io.FileOutputStream;
  28. import java.io.IOException;
  29. import java.io.OutputStream;
  30. import java.io.PrintWriter;
  31. import java.util.Date;
  32. /**
  33. * Logger class for the application.
  34. */
  35. public final class Logger {
  36. /** ProgramError folder. */
  37. private static File errorDir;
  38. /** Prevent instantiation of a new instance of Logger. */
  39. private Logger() {
  40. //Ignore
  41. }
  42. /**
  43. * Called when a user correctable error occurs.
  44. *
  45. * @param level Severity of the error
  46. * @param message Brief error description
  47. */
  48. public static void userError(final ErrorLevel level,
  49. final String message) {
  50. userError(level, message, "");
  51. }
  52. /**
  53. * Called when a user correctable error occurs.
  54. *
  55. * @param level Severity of the error
  56. * @param message Brief error description
  57. * @param details Verbose description of the error
  58. */
  59. public static void userError(final ErrorLevel level,
  60. final String message, final String details) {
  61. error(level, message, new String[]{"\n", details, }, false);
  62. }
  63. /**
  64. * Called when a user correctable error occurs.
  65. *
  66. * @param level Severity of the error
  67. * @param message Brief error description
  68. * @param exception Throwable cause for the error
  69. */
  70. public static void userError(final ErrorLevel level,
  71. final String message, final Throwable exception) {
  72. error(level, message, new String[0], false);
  73. }
  74. /**
  75. * Called when a non user correctable error occurs, the error will be
  76. * logged and optionally sent to the developers.
  77. *
  78. * @param level Severity of the error
  79. * @param message Brief error description
  80. * @param exception Cause of error
  81. */
  82. public static void appError(final ErrorLevel level,
  83. final String message, final Throwable exception) {
  84. error(level, message, exceptionToStringArray(exception), true);
  85. }
  86. /**
  87. * Handles an error in the program.
  88. *
  89. * @param level Severity of the error
  90. * @param message Brief error description
  91. * @param exception Cause of error
  92. * @param sendable Whether the error is sendable
  93. */
  94. private static void error(final ErrorLevel level,
  95. final String message, final String[] exception,
  96. final boolean sendable) {
  97. final ProgramError error = createError(level, message, exception);
  98. final boolean report =
  99. IdentityManager.getGlobalConfig().getOptionBool("general", "submitErrors", false)
  100. & !IdentityManager.getGlobalConfig().getOptionBool("temp", "noerrorreporting", false);
  101. if (!sendable) {
  102. error.setReportStatus(ErrorReportStatus.NOT_APPLICABLE);
  103. error.setFixedStatus(ErrorFixedStatus.UNREPORTED);
  104. }
  105. if (sendable && report) {
  106. ErrorManager.getErrorManager().sendError(error);
  107. }
  108. if (level == ErrorLevel.FATAL && !report) {
  109. error.setReportStatus(ErrorReportStatus.FINISHED);
  110. }
  111. ErrorManager.getErrorManager().addError(error);
  112. }
  113. /**
  114. * Creates a new ProgramError from the supplied information, and writes
  115. * the error to a file.
  116. *
  117. * @param level Error level
  118. * @param message Error message
  119. * @param trace Error cause
  120. *
  121. * @return ProgramError encapsulating the supplied information
  122. */
  123. private static ProgramError createError(final ErrorLevel level,
  124. final String message, final String[] trace) {
  125. final ProgramError error = new ProgramError(
  126. ErrorManager.getErrorManager().getNextErrorID(), level, message,
  127. trace, new Date(System.currentTimeMillis()));
  128. writeError(error);
  129. return error;
  130. }
  131. /**
  132. * Writes the specified error to a file.
  133. *
  134. * @param error ProgramError to write to a file.
  135. */
  136. private static void writeError(final ProgramError error) {
  137. final PrintWriter out = new PrintWriter(createNewErrorFile(error), true);
  138. out.println("Date:" + error.getDate());
  139. out.println("Level: " + error.getLevel());
  140. out.println("Description: " + error.getMessage());
  141. out.println("Details:");
  142. final String[] trace = error.getTrace();
  143. for (String traceLine : trace) {
  144. out.println('\t' + traceLine);
  145. }
  146. out.close();
  147. }
  148. /**
  149. * Creates a new file for an error and returns the output stream.
  150. *
  151. * @param error Error to create file for
  152. *
  153. * @return BufferedOutputStream to write to the error file
  154. */
  155. @SuppressWarnings("PMD.SystemPrintln")
  156. private static synchronized OutputStream createNewErrorFile(final ProgramError error) {
  157. if (errorDir == null || !errorDir.exists()) {
  158. errorDir = new File(Main.getConfigDir() + "errors");
  159. if (!errorDir.exists()) {
  160. errorDir.mkdirs();
  161. }
  162. }
  163. final String logName = error.getDate().getTime() + "-" + error.getLevel();
  164. final File errorFile = new File(errorDir, logName + ".log");
  165. if (errorFile.exists()) {
  166. boolean rename = false;
  167. int i = 0;
  168. while (!rename) {
  169. i++;
  170. rename = errorFile.renameTo(new File(errorDir, logName + "-" + i + ".log"));
  171. }
  172. }
  173. try {
  174. errorFile.createNewFile();
  175. } catch (IOException ex) {
  176. System.err.println("Error creating new file: ");
  177. ex.printStackTrace(System.err);
  178. return new NullOutputStream();
  179. }
  180. try {
  181. return new FileOutputStream(errorFile);
  182. } catch (FileNotFoundException ex) {
  183. System.err.println("Error creating new stream: ");
  184. ex.printStackTrace(System.err);
  185. return new NullOutputStream();
  186. }
  187. }
  188. /**
  189. * Converts an exception into a string array.
  190. *
  191. * @param throwable Exception to convert
  192. *
  193. * @return Exception string array
  194. */
  195. private static String[] exceptionToStringArray(final Throwable throwable) {
  196. String[] trace;
  197. if (throwable == null) {
  198. trace = new String[0];
  199. } else {
  200. final StackTraceElement[] traceElements = throwable.getStackTrace();
  201. trace = new String[traceElements.length + 1];
  202. trace[0] = throwable.toString();
  203. for (int i = 0; i < traceElements.length; i++) {
  204. trace[i + 1] = traceElements[i].toString();
  205. }
  206. if (throwable.getCause() != null) {
  207. final String[] causeTrace = exceptionToStringArray(throwable.getCause());
  208. final String[] newTrace = new String[trace.length + causeTrace.length];
  209. trace[0] = "\nWhich caused: " + trace[0];
  210. System.arraycopy(causeTrace, 0, newTrace, 0, causeTrace.length);
  211. System.arraycopy(trace, 0, newTrace, causeTrace.length, trace.length);
  212. trace = newTrace;
  213. }
  214. }
  215. return trace;
  216. }
  217. }