1 /*
2 * Autopsy Forensic Browser
3 *
4 * Copyright 2012-2015 Basis Technology Corp.
5 * Contact: carrier <at> sleuthkit <dot> org
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19 package org.sleuthkit.autopsy.coreutils;
20
21 import java.io.IOException;
22 import java.nio.file.Paths;
23 import java.util.logging.FileHandler;
24 import java.util.logging.Formatter;
25 import java.util.logging.Handler;
26 import java.sql.Timestamp;
27 import java.util.Date;
28 import java.util.HashMap;
29 import java.util.Map;
30 import java.util.logging.LogRecord;
31
37
39 private static final int LOG_SIZE = 0;
// In bytes, zero is unlimited
44 private static final Handler
consoleHandler =
new java.util.logging.ConsoleHandler();
47
57 String logFilePath = Paths.get(logDirectory, LOG_WITHOUT_STACK_TRACES).toString();
58 try {
59 FileHandler fileHandler = new FileHandler(logFilePath, LOG_SIZE, LOG_FILE_COUNT);
60 fileHandler.setEncoding(LOG_ENCODING);
61 fileHandler.setFormatter(new Formatter() {
62 @Override
63 public String format(LogRecord record) {
64 return (new Date(record.getMillis())).toString() + " "
65 + record.getSourceClassName() + " "
66 + record.getSourceMethodName() + "\n"
67 + record.getLevel() + ": "
68 + this.formatMessage(record) + "\n";
69 }
70 });
71 return fileHandler;
72 } catch (IOException ex) {
73 throw new RuntimeException(String.format("Error initializing file handler for %s", logFilePath), ex); //NON-NLS
74 }
75 }
76
86 String logFilePath = Paths.get(logDirectory, LOG_WITH_STACK_TRACES).toString();
87 try {
88 FileHandler fileHandler = new FileHandler(logFilePath, LOG_SIZE, LOG_FILE_COUNT);
89 fileHandler.setEncoding(LOG_ENCODING);
90 fileHandler.setFormatter(new Formatter() {
91 @Override
92 public String format(LogRecord record) {
93 Throwable thrown = record.getThrown();
94 String stackTrace = ""; //NON-NLS
95 while (thrown != null) {
96 stackTrace += thrown.toString() + "\n";
97 for (StackTraceElement traceElem : record.getThrown().getStackTrace()) {
98 stackTrace += "\t" + traceElem.toString() + "\n"; //NON-NLS
99 }
100 thrown = thrown.getCause();
101 }
102 return (new Timestamp(record.getMillis())).toString() + " " //NON-NLS
103 + record.getSourceClassName() + " " //NON-NLS
104 + record.getSourceMethodName() + "\n" //NON-NLS
105 + record.getLevel() + ": " //NON-NLS
106 + this.formatMessage(record) + "\n" //NON-NLS
107 + stackTrace;
108 }
109 });
110 return fileHandler;
111 } catch (IOException ex) {
112 throw new RuntimeException(String.format("Error initializing file handler for %s", logFilePath), ex); //NON-NLS
113 }
114 }
115
122 /*
123 * Create file handlers for the new directory and swap them into all of
124 * the existing loggers using thread-safe Logger methods. The new
125 * handlers are added before the old handlers so that no messages will
126 * be lost, but this makes it possible for log messages to be written
127 * via the old handlers if logging calls are interleaved with the
128 * add/remove handler calls (currently, the base class handlers
129 * collection is a CopyOnWriteArrayList).
130 */
133 for (
Logger logger : namesToLoggers.values()) {
134 logger.addHandler(newUserFriendlyHandler);
135 logger.addHandler(newDeveloperFriendlyHandler);
136 logger.removeHandler(userFriendlyHandler);
137 logger.removeHandler(userFriendlyHandler);
138 }
139
140 /*
141 * Close the old file handlers and save references to the new handlers
142 * so they can be added to any new loggers. This swap is why this method
143 * and the two overloads of getLogger() are synchronized, serializing
144 * access to userFriendlyHandler and developerFriendlyHandler.
145 */
146 userFriendlyHandler.close();
147 userFriendlyHandler = newUserFriendlyHandler;
148 developerFriendlyHandler.close();
149 developerFriendlyHandler = newDeveloperFriendlyHandler;
150 }
151
163 }
164
179 if (!namesToLoggers.containsKey(name)) {
181 logger.addHandler(userFriendlyHandler);
182 logger.addHandler(developerFriendlyHandler);
183 namesToLoggers.put(name, logger);
184 }
185 return namesToLoggers.get(name);
186 }
187
198 private Logger(String name, String resourceBundleName) {
199 super(name, resourceBundleName);
200 super.setUseParentHandlers(false);
202 super.addHandler(consoleHandler);
203 }
204 }
205 }
static Version.Type getBuildType()
static final int LOG_SIZE
static final String LOG_WITHOUT_STACK_TRACES
synchronized static void setLogDirectory(String directoryPath)
Logger(String name, String resourceBundleName)
static final int LOG_FILE_COUNT
static FileHandler userFriendlyHandler
static final String LOG_ENCODING
static FileHandler developerFriendlyHandler
static final Handler consoleHandler
static FileHandler createFileHandlerWithTraces(String logDirectory)
static final Map< String, Logger > namesToLoggers
synchronized static Logger getLogger(String name)
static final String LOG_WITH_STACK_TRACES
synchronized static Logger getLogger(String name, String resourceBundleName)
static FileHandler createFileHandlerWithoutTraces(String logDirectory)