/*
 * Autopsy Forensic Browser
 *
 * Copyright 2012-2014 Basis Technology Corp.
 * Contact: carrier <at> sleuthkit <dot> org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.sleuthkit.autopsy.coreutils;

import java.io.IOException;
import java.util.logging.*;

/**
 * Custom Autopsy logger wrapper over java.util.logging.Logger with default file
 * streams logging to autopsy.log (general high level messages),
 * autopsy_traces.log (also including exception traces).
 * In development build, those are also redirected to console / messages log.
 *
 * Contains a utility method to log user actions to autopsy_actions.log via noteAction()
 * 
 * Use like java.util.logging.Logger API, get a
 * org.sleuthkit.autopsy.coreutils.Logger handle using factory method
 * org.sleuthkit.autopsy.coreutils.Logger.getLogger(String name) passing
 * component/module/class name.
 *
 * If logging behavior is to be customized, you can add or remove handlers or
 * filters from the provided Logger object.
 */
public class Logger extends java.util.logging.Logger {

    private static final String LOG_ENCODING = PlatformUtil.getLogFileEncoding();
    private static final String LOG_DIR = PlatformUtil.getLogDirectory();
    static final int LOG_SIZE = 0; // in bytes, zero is unlimited
    static final int LOG_FILE_COUNT = 10;
    
    //File Handlers which point to the output logs
    private static  final FileHandler traces = initTraces();
    private static  final FileHandler normal = initNormal();
    private static final Handler console = new java.util.logging.ConsoleHandler();
    private static final java.util.logging.Logger actionsLogger = initActionsLogger();
   

    /**
     * Main messages log file name
     */
    public static final String messagesLog = "autopsy.log"; //NON-NLS
    /**
     * Detailed exception trace log file name
     */
    public static final String tracesLog = "autopsy_traces.log"; //NON-NLS
    
    /**
     * Action logger file name
     */
    public static final String actionsLog = "autopsy_actions.log"; //NON-NLS

    /**
     * Static blocks to get around compile errors such as "variable might not
     * have been initialized
   *
     */
    //<editor-fold defaultstate="visible" desc="static block initializers">
    private static FileHandler initTraces() {

        try {

            FileHandler f = new FileHandler(LOG_DIR + tracesLog, LOG_SIZE, LOG_FILE_COUNT);
            f.setEncoding(LOG_ENCODING);
            f.setFormatter(new SimpleFormatter());
            return f;
        } catch (IOException e) {
            throw new RuntimeException("Error initializing traces logger", e); //NON-NLS
        }
    }

    private static FileHandler initNormal() {
        try {
            FileHandler f = new FileHandler(LOG_DIR + messagesLog, LOG_SIZE, LOG_FILE_COUNT);
            f.setEncoding(LOG_ENCODING);
            f.setFormatter(new SimpleFormatter());
            return f;
        } catch (IOException e) {
            throw new RuntimeException("Error initializing normal logger", e); //NON-NLS
        }
    }
    
    private static java.util.logging.Logger initActionsLogger() {
        try {
            FileHandler f = new FileHandler(LOG_DIR + actionsLog, LOG_SIZE, LOG_FILE_COUNT);
            f.setEncoding(LOG_ENCODING);
            f.setFormatter(new SimpleFormatter());
            java.util.logging.Logger _actionsLogger = java.util.logging.Logger.getLogger("Actions"); //NON-NLS
            _actionsLogger.setUseParentHandlers(false);
            _actionsLogger.addHandler(f);
            _actionsLogger.addHandler(console);
            return _actionsLogger;
        } catch (IOException e) {
            throw new RuntimeException("Error initializing actions logger", e); //NON-NLS
        }
    }

    //</editor-fold>
    private Logger(java.util.logging.Logger log) {
        super(log.getName(), log.getResourceBundleName());
        //do forward to messages, so that IDE window shows them
        if (Version.getBuildType() == Version.Type.DEVELOPMENT) {
            addHandler(console);
        }
        setUseParentHandlers(false); //do not forward to parent logger, sharing static handlers anyway
        //addHandler(new AutopsyExceptionHandler());
        addHandler(normal);
        addHandler(traces);
    }

    /**
     * Log an action to autopsy_actions.log
     * @param actionClass class where user triggered action occurs
     */
    public static void noteAction(Class<?> actionClass) {
        actionsLogger.log(Level.INFO, "Action performed: {0}", actionClass.getName()); //NON-NLS
    }

    /**
     * Factory method to retrieve a org.sleuthkit.autopsy.coreutils.Logger
     * instance The logger logs by default to autopsy.log and
     * autopsy_traces.log. Add/remove handlers if the desired behavior should be
     * different.
     *
     * @param name ID for the logger or empty string for a root logger
     * @return org.sleuthkit.autopsy.coreutils.Logger instance
     */
    public static Logger getLogger(String name) {
        Logger l = new Logger(java.util.logging.Logger.getLogger(name));
        return l;
    }

    /**
     * Factory method to retrieve a org.sleuthkit.autopsy.coreutils.Logger
     * instance
     *
     * @param name ID for the logger or empty string for a root logger
     * @param resourceBundleName bundle name associated with the logger
     * @return org.sleuthkit.autopsy.coreutils.Logger instance
     */
    public static Logger getLogger(String name, String resourceBundleName) {
        return new Logger(Logger.getLogger(name, resourceBundleName));
    }

    @Override
    public void log(Level level, String message, Throwable thrown) {
        super.log(level, "{0}\nException:  {1}", new Object[]{message, thrown.toString()}); //NON-NLS
        removeHandler(normal);
        super.log(level, message, thrown);
        addHandler(normal);
    }

    @Override
    public void throwing(String sourceClass, String sourceMethod, Throwable thrown) {
        removeHandler(normal);
        super.throwing(sourceClass, sourceMethod, thrown);
        addHandler(normal);
    }
}

@@ -985,19 +985,16 @@
 traces).
-%0A *
  In deve
@@ -1007,16 +1007,19 @@
 t build,
+%0A *
  those a
@@ -1142,16 +1142,19 @@
 .log via
+%0A *
  noteAct
@@ -1161,17 +1161,16 @@
 ion()%0A *
- 
 %0A * Use 
@@ -1834,21 +1834,16 @@
 T = 10;%0A
-    %0A
     //Fi
@@ -1896,33 +1896,32 @@
  private static 
- 
 final FileHandle
@@ -1964,17 +1964,16 @@
  static 
- 
 final Fi
@@ -2179,13 +2179,8 @@
 ();%0A
-   %0A%0A
     
@@ -2433,21 +2433,16 @@
 NON-NLS%0A
-    %0A
     /**%0A
@@ -2676,16 +2676,18 @@
 ized%0A   
+  
 *%0A     *
@@ -3579,20 +3579,16 @@
 %7D%0A    %7D%0A
-    
 %0A    pri
@@ -4853,16 +4853,23 @@
 ons.log%0A
+     *%0A
      * @

Apply NetBeans IDE formatting to Logger class