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