001/*
002 * Syncany, www.syncany.org
003 * Copyright (C) 2011-2016 Philipp C. Heckel <philipp.heckel@gmail.com> 
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU General Public License as published by
007 * the Free Software Foundation, either version 3 of the License, or
008 * (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU General Public License for more details.
014 *
015 * You should have received a copy of the GNU General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018package org.syncany.config;
019
020import java.io.InputStream;
021import java.util.Enumeration;
022import java.util.concurrent.atomic.AtomicBoolean;
023import java.util.logging.Handler;
024import java.util.logging.Level;
025import java.util.logging.LogManager;
026import java.util.logging.Logger;
027
028/**
029 * The logging class offers convenience functions to initialize and update the
030 * application's log options. 
031 * 
032 * <p>In particular, it can load the log properties either from a resource or a
033 * local file on the file system (<code>logging.properties</code>. If a local file is
034 * present, it is preferred over the JAR resource.
035 * 
036 * <p>To initialize logging, the {@link #init()} method can be called in the 
037 * <code>static</code> block of a class, e.g.
038 * 
039 * <pre>
040 *   static {
041 *     Logging.init();
042 *   }
043 * </pre>
044 *  
045 * @author Philipp C. Heckel (philipp.heckel@gmail.com)
046 */
047public class Logging {
048        private static final String LOG_PROPERTIES_JAR_RESOURCE = "/" + Logging.class.getPackage().getName().replace(".", "/") + "/logging.properties"; 
049        private static AtomicBoolean loggingInitialized = new AtomicBoolean(false);
050        
051        public synchronized static void init() {
052                if (loggingInitialized.get()) {
053                        return;
054                }
055
056                // Turn off unwanted loggers (evil libraries and such) 
057                disableUnwantedLoggers();               
058                                
059                // Load logging.properties
060        try {
061                // Use file if exists, else use file embedded in JAR
062                InputStream logConfigInputStream = Config.class.getResourceAsStream(LOG_PROPERTIES_JAR_RESOURCE);
063                
064            if (logConfigInputStream != null) {
065                LogManager.getLogManager().readConfiguration(logConfigInputStream);
066            }
067            
068            loggingInitialized.set(true);
069        }
070        catch (Exception e) {
071            Logger.getAnonymousLogger().severe("Could not load logging.properties file from resource "+LOG_PROPERTIES_JAR_RESOURCE);
072            Logger.getAnonymousLogger().severe(e.getMessage());
073            
074            e.printStackTrace();
075        }               
076        }       
077        
078        private static void disableUnwantedLoggers() {
079                System.setProperty("hsqldb.reconfig_logging", "false");
080                
081                if (Logger.getLogger("sun.awt.X11.timeoutTask.XToolkit") != null) {
082                        Logger.getLogger("sun.awt.X11.timeoutTask.XToolkit").setLevel(Level.OFF);
083                }
084        }
085
086        public static void setGlobalLogLevel(Level targetLogLevel) {
087                for (Enumeration<String> loggerNames = LogManager.getLogManager().getLoggerNames(); loggerNames.hasMoreElements(); ) {
088            String loggerName = loggerNames.nextElement();
089            Logger logger = LogManager.getLogManager().getLogger(loggerName);
090            
091            if (logger != null) {
092                logger.setLevel(targetLogLevel);
093            }
094                }       
095                
096                for (Handler handler : Logger.getLogger("").getHandlers()) {
097                        handler.setLevel(targetLogLevel);
098                }
099                
100                Logger.getLogger("").setLevel(targetLogLevel);          
101                
102                // Make sure the unwanted loggers stay quiet
103                disableUnwantedLoggers();
104        }
105        
106        public static void addGlobalHandler(Handler targetHandler) {
107                Logger.getLogger("").addHandler(targetHandler);
108        }
109                
110        public static void disableLogging() {
111                LogManager.getLogManager().reset();
112                
113                setGlobalLogLevel(Level.OFF);
114                
115                while (Logger.getLogger("").getHandlers().length > 0) {
116                        Logger.getLogger("").removeHandler(Logger.getLogger("").getHandlers()[0]);
117                }
118        }       
119}