xref: /OpenGrok/opengrok-indexer/src/main/java/org/opengrok/indexer/logger/LoggerUtil.java (revision 0e4c55544f8ea0a68e8bae37b0e502097e008ec1)
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