123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- /*
- * Copyright (c) 2006-2008 Chris Smith, Shane Mc Cormack, Gregory Holmes
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
- package com.dmdirc.logger;
-
- import com.dmdirc.Main;
- import com.dmdirc.config.IdentityManager;
-
- import java.io.File;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.io.PrintWriter;
- import java.util.Date;
-
- /**
- * Logger class for the application.
- */
- public final class Logger {
-
- /** ProgramError folder. */
- private static File errorDir;
-
- /** Prevent instantiation of a new instance of Logger. */
- private Logger() {
- //Ignore
- }
-
- /**
- * Called when a user correctable error occurs.
- *
- * @param level Severity of the error
- * @param message Brief error description
- */
- public static void userError(final ErrorLevel level,
- final String message) {
- userError(level, message, "");
- }
-
- /**
- * Called when a user correctable error occurs.
- *
- * @param level Severity of the error
- * @param message Brief error description
- * @param details Verbose description of the error
- */
- public static void userError(final ErrorLevel level,
- final String message, final String details) {
- error(level, message, new String[]{"\n", details, }, false);
- }
-
- /**
- * Called when a user correctable error occurs.
- *
- * @param level Severity of the error
- * @param message Brief error description
- * @param exception Throwable cause for the error
- */
- public static void userError(final ErrorLevel level,
- final String message, final Throwable exception) {
- error(level, message, new String[0], false);
- }
-
- /**
- * Called when a non user correctable error occurs, the error will be
- * logged and optionally sent to the developers.
- *
- * @param level Severity of the error
- * @param message Brief error description
- * @param exception Cause of error
- */
- public static void appError(final ErrorLevel level,
- final String message, final Throwable exception) {
- error(level, message, exceptionToStringArray(exception), true);
- }
-
- /**
- * Handles an error in the program.
- *
- * @param level Severity of the error
- * @param message Brief error description
- * @param exception Cause of error
- * @param sendable Whether the error is sendable
- */
- private static void error(final ErrorLevel level,
- final String message, final String[] exception,
- final boolean sendable) {
- final ProgramError error = createError(level, message, exception);
- final boolean report =
- IdentityManager.getGlobalConfig().getOptionBool("general", "submitErrors", false)
- & !IdentityManager.getGlobalConfig().getOptionBool("temp", "noerrorreporting", false);
-
- if (!sendable) {
- error.setReportStatus(ErrorReportStatus.NOT_APPLICABLE);
- error.setFixedStatus(ErrorFixedStatus.UNREPORTED);
- }
-
- if (sendable && report) {
- ErrorManager.getErrorManager().sendError(error);
- }
-
- if (level == ErrorLevel.FATAL && !report) {
- error.setReportStatus(ErrorReportStatus.FINISHED);
- }
-
- ErrorManager.getErrorManager().addError(error);
- }
-
- /**
- * Creates a new ProgramError from the supplied information, and writes
- * the error to a file.
- *
- * @param level Error level
- * @param message Error message
- * @param trace Error cause
- *
- * @return ProgramError encapsulating the supplied information
- */
- private static ProgramError createError(final ErrorLevel level,
- final String message, final String[] trace) {
- final ProgramError error = new ProgramError(
- ErrorManager.getErrorManager().getNextErrorID(), level, message,
- trace, new Date(System.currentTimeMillis()));
-
- writeError(error);
-
- return error;
- }
-
- /**
- * Writes the specified error to a file.
- *
- * @param error ProgramError to write to a file.
- */
- private static void writeError(final ProgramError error) {
- final PrintWriter out = new PrintWriter(createNewErrorFile(error), true);
- out.println("Date:" + error.getDate());
- out.println("Level: " + error.getLevel());
- out.println("Description: " + error.getMessage());
- out.println("Details:");
- final String[] trace = error.getTrace();
- for (String traceLine : trace) {
- out.println('\t' + traceLine);
- }
- out.close();
- }
-
- /**
- * Creates a new file for an error and returns the output stream.
- *
- * @param error Error to create file for
- *
- * @return BufferedOutputStream to write to the error file
- */
- @SuppressWarnings("PMD.SystemPrintln")
- private static synchronized OutputStream createNewErrorFile(final ProgramError error) {
- if (errorDir == null || !errorDir.exists()) {
- errorDir = new File(Main.getConfigDir() + "errors");
- if (!errorDir.exists()) {
- errorDir.mkdirs();
- }
- }
- final String logName = error.getDate().getTime() + "-" + error.getLevel();
-
-
- final File errorFile = new File(errorDir, logName + ".log");
-
- if (errorFile.exists()) {
- boolean rename = false;
- int i = 0;
- while (!rename) {
- i++;
- rename = errorFile.renameTo(new File(errorDir, logName + "-" + i + ".log"));
- }
- }
- try {
- errorFile.createNewFile();
- } catch (IOException ex) {
- System.err.println("Error creating new file: ");
- ex.printStackTrace(System.err);
- return new NullOutputStream();
- }
-
- try {
- return new FileOutputStream(errorFile);
- } catch (FileNotFoundException ex) {
- System.err.println("Error creating new stream: ");
- ex.printStackTrace(System.err);
- return new NullOutputStream();
- }
- }
-
- /**
- * Converts an exception into a string array.
- *
- * @param throwable Exception to convert
- *
- * @return Exception string array
- */
- private static String[] exceptionToStringArray(final Throwable throwable) {
- String[] trace;
-
- if (throwable == null) {
- trace = new String[0];
- } else {
- final StackTraceElement[] traceElements = throwable.getStackTrace();
- trace = new String[traceElements.length + 1];
-
- trace[0] = throwable.toString();
-
- for (int i = 0; i < traceElements.length; i++) {
- trace[i + 1] = traceElements[i].toString();
- }
-
- if (throwable.getCause() != null) {
- final String[] causeTrace = exceptionToStringArray(throwable.getCause());
- final String[] newTrace = new String[trace.length + causeTrace.length];
- trace[0] = "\nWhich caused: " + trace[0];
-
- System.arraycopy(causeTrace, 0, newTrace, 0, causeTrace.length);
- System.arraycopy(trace, 0, newTrace, causeTrace.length, trace.length);
-
- trace = newTrace;
- }
- }
-
- return trace;
- }
-
- }
|