1b5840353SAdam Hornáček /* 2b5840353SAdam Hornáček * CDDL HEADER START 3b5840353SAdam Hornáček * 4b5840353SAdam Hornáček * The contents of this file are subject to the terms of the 5b5840353SAdam Hornáček * Common Development and Distribution License (the "License"). 6b5840353SAdam Hornáček * You may not use this file except in compliance with the License. 7b5840353SAdam Hornáček * 8b5840353SAdam Hornáček * See LICENSE.txt included in this distribution for the specific 9b5840353SAdam Hornáček * language governing permissions and limitations under the License. 10b5840353SAdam Hornáček * 11b5840353SAdam Hornáček * When distributing Covered Code, include this CDDL HEADER in each 12b5840353SAdam Hornáček * file and include the License file at LICENSE.txt. 13b5840353SAdam Hornáček * If applicable, add the following below this CDDL HEADER, with the 14b5840353SAdam Hornáček * fields enclosed by brackets "[]" replaced with your own identifying 15b5840353SAdam Hornáček * information: Portions Copyright [yyyy] [name of copyright owner] 16b5840353SAdam Hornáček * 17b5840353SAdam Hornáček * CDDL HEADER END 18b5840353SAdam Hornáček */ 19b5840353SAdam Hornáček 20b5840353SAdam Hornáček /* 21b5840353SAdam Hornáček * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. 22b5840353SAdam Hornáček */ 239805b761SAdam Hornáček package org.opengrok.indexer.logger; 24b5840353SAdam Hornáček 259805b761SAdam Hornáček import org.opengrok.indexer.logger.formatter.ConsoleFormatter; 269805b761SAdam Hornáček import org.opengrok.indexer.logger.formatter.FileLogFormatter; 27b5840353SAdam Hornáček 28b5840353SAdam Hornáček import java.io.File; 29b5840353SAdam Hornáček import java.io.IOException; 30b5840353SAdam Hornáček import java.lang.reflect.InvocationTargetException; 31b5840353SAdam Hornáček import java.util.logging.ConsoleHandler; 32b5840353SAdam Hornáček import java.util.logging.FileHandler; 33b5840353SAdam Hornáček import java.util.logging.Formatter; 34b5840353SAdam Hornáček import java.util.logging.Handler; 35b5840353SAdam Hornáček import java.util.logging.Level; 36b5840353SAdam Hornáček import java.util.logging.LogManager; 37b5840353SAdam Hornáček import java.util.logging.Logger; 38b5840353SAdam Hornáček 39b5840353SAdam Hornáček /** 40b5840353SAdam Hornáček * Utilities to maintain logging. 41b5840353SAdam Hornáček */ 42b5840353SAdam Hornáček public class LoggerUtil { 43b5840353SAdam Hornáček 44b5840353SAdam Hornáček private static final Logger LOGGER = LoggerFactory.getLogger(LoggerUtil.class); 45b5840353SAdam Hornáček 46b5840353SAdam Hornáček public static final String BASE_LOGGER = "org.opengrok"; 47b5840353SAdam Hornáček private static final int DEFAULT_FILEHANDLER_LIMIT = 52428800; 48b5840353SAdam Hornáček private static final int DEFAULT_FILEHANDLER_COUNT = 3; 49b5840353SAdam Hornáček 50b5840353SAdam Hornáček private static volatile String loggerFile = null; 51b5840353SAdam Hornáček LoggerUtil()52*ff44f24aSAdam Hornáček private LoggerUtil() { 53*ff44f24aSAdam Hornáček } 54*ff44f24aSAdam Hornáček getBaseLogger()55b5840353SAdam Hornáček public static Logger getBaseLogger() { 56b5840353SAdam Hornáček return Logger.getLogger(BASE_LOGGER); 57b5840353SAdam Hornáček } 58b5840353SAdam Hornáček setBaseConsoleLogLevel(Level level)59b5840353SAdam Hornáček public static void setBaseConsoleLogLevel(Level level) { 60b5840353SAdam Hornáček setBaseLogLevel(ConsoleHandler.class, level); 61b5840353SAdam Hornáček } 62b5840353SAdam Hornáček getBaseConsoleLogLevel()63b5840353SAdam Hornáček public static Level getBaseConsoleLogLevel() { 64b5840353SAdam Hornáček return getBaseLogLevel(ConsoleHandler.class); 65b5840353SAdam Hornáček } 66b5840353SAdam Hornáček setBaseFileLogLevel(Level level)67b5840353SAdam Hornáček public static void setBaseFileLogLevel(Level level) { 68b5840353SAdam Hornáček setBaseLogLevel(FileHandler.class, level); 69b5840353SAdam Hornáček } 70b5840353SAdam Hornáček getBaseFileLogLevel()71b5840353SAdam Hornáček public static Level getBaseFileLogLevel() { 72b5840353SAdam Hornáček return getBaseLogLevel(FileHandler.class); 73b5840353SAdam Hornáček } 74b5840353SAdam Hornáček setBaseLogLevel(Class<? extends Handler> handlerClass, Level level)75b5840353SAdam Hornáček private static void setBaseLogLevel(Class<? extends Handler> handlerClass, Level level) { 76b5840353SAdam Hornáček for (Handler handler : getBaseLogger().getHandlers()) { 77b5840353SAdam Hornáček if (handlerClass.isInstance(handler)) { 78b5840353SAdam Hornáček handler.setLevel(level); 79b5840353SAdam Hornáček } 80b5840353SAdam Hornáček } 81b5840353SAdam Hornáček } 82b5840353SAdam Hornáček getBaseLogLevel(Class<? extends Handler> handlerClass)83b5840353SAdam Hornáček private static Level getBaseLogLevel(Class<? extends Handler> handlerClass) { 84b5840353SAdam Hornáček for (Handler handler : getBaseLogger().getHandlers()) { 85b5840353SAdam Hornáček if (handlerClass.isInstance(handler)) { 86b5840353SAdam Hornáček return handler.getLevel(); 87b5840353SAdam Hornáček } 88b5840353SAdam Hornáček } 89b5840353SAdam Hornáček return Level.OFF; 90b5840353SAdam Hornáček } 91b5840353SAdam Hornáček getFileHandlerPattern()92b5840353SAdam Hornáček public static String getFileHandlerPattern() { 93b5840353SAdam Hornáček return LogManager.getLogManager().getProperty("java.util.logging.FileHandler.pattern"); 94b5840353SAdam Hornáček } 95b5840353SAdam Hornáček setFileHandlerLogPath(String path)96b5840353SAdam Hornáček public static void setFileHandlerLogPath(String path) throws IOException { 97b5840353SAdam Hornáček if (path != null) { 98b5840353SAdam Hornáček File jlp = new File(path); 99b5840353SAdam Hornáček if (!jlp.exists() && !jlp.mkdirs()) { 100b5840353SAdam Hornáček throw new IOException("could not make logpath: " 101b5840353SAdam Hornáček + jlp.getAbsolutePath()); 102b5840353SAdam Hornáček } 103b5840353SAdam Hornáček } 104b5840353SAdam Hornáček 105b5840353SAdam Hornáček StringBuilder logfile = new StringBuilder(); 106b5840353SAdam Hornáček logfile.append(path == null ? "%t" : path); 107b5840353SAdam Hornáček logfile.append(File.separatorChar).append("opengrok%g.%u.log"); 108b5840353SAdam Hornáček 109b5840353SAdam Hornáček for (Handler handler : getBaseLogger().getHandlers()) { 110b5840353SAdam Hornáček if (handler instanceof FileHandler) { 111b5840353SAdam Hornáček FileHandler fileHandler = (FileHandler) handler; 112b5840353SAdam Hornáček FileHandler newFileHandler; 113b5840353SAdam Hornáček try { 114b5840353SAdam Hornáček int logFilesSizeLimit = loggerIntProperty("java.util.logging.FileHandler.limit", DEFAULT_FILEHANDLER_LIMIT); 115b5840353SAdam Hornáček int logFilesCount = loggerIntProperty("java.util.logging.FileHandler.count", DEFAULT_FILEHANDLER_COUNT); 116b5840353SAdam Hornáček newFileHandler = new FileHandler(logfile.toString(), logFilesSizeLimit, logFilesCount); 117b5840353SAdam Hornáček } catch (IOException e) { 118b5840353SAdam Hornáček LOGGER.log(Level.WARNING, "Cannot create new logger FileHandler: " + logfile.toString(), e); 119b5840353SAdam Hornáček return; 120b5840353SAdam Hornáček } 121b5840353SAdam Hornáček String formatter = LogManager.getLogManager().getProperty("java.util.logging.FileHandler.formatter"); 122b5840353SAdam Hornáček newFileHandler.setLevel(fileHandler.getLevel()); 123b5840353SAdam Hornáček try { 124b5840353SAdam Hornáček newFileHandler.setFormatter((Formatter) Class.forName(formatter).getDeclaredConstructor().newInstance()); 125b5840353SAdam Hornáček } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | NoSuchMethodException 126b5840353SAdam Hornáček | InvocationTargetException e) { 127b5840353SAdam Hornáček newFileHandler.setFormatter(new FileLogFormatter()); 128b5840353SAdam Hornáček } 129b5840353SAdam Hornáček getBaseLogger().addHandler(newFileHandler); 130b5840353SAdam Hornáček getBaseLogger().removeHandler(fileHandler); 131b5840353SAdam Hornáček loggerFile = logfile.toString(); 132b5840353SAdam Hornáček } 133b5840353SAdam Hornáček } 134b5840353SAdam Hornáček } 135b5840353SAdam Hornáček getFileHandlerLogPath()136b5840353SAdam Hornáček public static String getFileHandlerLogPath() { 137b5840353SAdam Hornáček return loggerFile != null ? loggerFile : LogManager.getLogManager().getProperty("java.util.logging.FileHandler.pattern"); 138b5840353SAdam Hornáček } 139b5840353SAdam Hornáček loggerIntProperty(String name, int def)140b5840353SAdam Hornáček private static int loggerIntProperty(String name, int def) { 141b5840353SAdam Hornáček String val = LogManager.getLogManager().getProperty(name); 142b5840353SAdam Hornáček if (val == null) { 143b5840353SAdam Hornáček return def; 144b5840353SAdam Hornáček } 145b5840353SAdam Hornáček try { 146b5840353SAdam Hornáček return Integer.parseInt(val); 147b5840353SAdam Hornáček } catch (NumberFormatException e) { 148b5840353SAdam Hornáček return def; 149b5840353SAdam Hornáček } 150b5840353SAdam Hornáček } 151b5840353SAdam Hornáček initLogger(String logpath, Level filelevel, Level consolelevel)152b5840353SAdam Hornáček public static String initLogger(String logpath, Level filelevel, Level consolelevel) throws IOException { 153b5840353SAdam Hornáček if (logpath != null) { 154b5840353SAdam Hornáček File jlp = new File(logpath); 155b5840353SAdam Hornáček if (!jlp.exists() && !jlp.mkdirs()) { 156b5840353SAdam Hornáček throw new RuntimeException("could not make logpath: " 157b5840353SAdam Hornáček + jlp.getAbsolutePath()); 158b5840353SAdam Hornáček } 159b5840353SAdam Hornáček if (!jlp.canWrite() && !Level.OFF.equals(filelevel)) { 160b5840353SAdam Hornáček throw new IOException("logpath not writeable " + jlp.getAbsolutePath()); 161b5840353SAdam Hornáček } 162b5840353SAdam Hornáček } 163b5840353SAdam Hornáček 164b5840353SAdam Hornáček Logger.getGlobal().setLevel(Level.OFF); 165b5840353SAdam Hornáček getBaseLogger().setLevel(Level.ALL); 166b5840353SAdam Hornáček StringBuilder logfile = new StringBuilder(); 167b5840353SAdam Hornáček logfile.append(logpath == null ? "%t" : logpath); 168b5840353SAdam Hornáček logfile.append(File.separatorChar).append("opengrok%g.%u.log"); 169b5840353SAdam Hornáček try { 170b5840353SAdam Hornáček FileHandler fh = new FileHandler(logfile.toString(), 171b5840353SAdam Hornáček loggerIntProperty("java.util.logging.FileHandler.limit", DEFAULT_FILEHANDLER_LIMIT), 172b5840353SAdam Hornáček loggerIntProperty("java.util.logging.FileHandler.count", DEFAULT_FILEHANDLER_COUNT)); 173b5840353SAdam Hornáček 174b5840353SAdam Hornáček fh.setLevel(filelevel); 175b5840353SAdam Hornáček String formatter = LogManager.getLogManager().getProperty("java.util.logging.FileHandler.formatter"); 176b5840353SAdam Hornáček try { 177b5840353SAdam Hornáček fh.setFormatter((Formatter) Class.forName(formatter).getDeclaredConstructor().newInstance()); 178b5840353SAdam Hornáček } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | NoSuchMethodException 179b5840353SAdam Hornáček | InvocationTargetException e) { 180b5840353SAdam Hornáček fh.setFormatter(new FileLogFormatter()); 181b5840353SAdam Hornáček } 182b5840353SAdam Hornáček 183b5840353SAdam Hornáček getBaseLogger().addHandler(fh); 184b5840353SAdam Hornáček loggerFile = logfile.toString(); 185b5840353SAdam Hornáček 186b5840353SAdam Hornáček ConsoleHandler ch = new ConsoleHandler(); 187b5840353SAdam Hornáček ch.setLevel(consolelevel); 188b5840353SAdam Hornáček ch.setFormatter(new ConsoleFormatter()); 189b5840353SAdam Hornáček getBaseLogger().addHandler(ch); 190b5840353SAdam Hornáček 191b5840353SAdam Hornáček } catch (IOException | SecurityException ex1) { 192b5840353SAdam Hornáček LOGGER.log(Level.SEVERE, "Exception logging", ex1); 193b5840353SAdam Hornáček throw new IOException("Exception setting up logging " + ex1); 194b5840353SAdam Hornáček } 195b5840353SAdam Hornáček return logpath; 196b5840353SAdam Hornáček } 197b5840353SAdam Hornáček } 198