Package io.osv.jul

Source Code of io.osv.jul.LogManagerWrapper$LogManagerInitializer

package io.osv.jul;

import io.osv.Context;
import io.osv.util.LazilyInitialized;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;

public class LogManagerWrapper {
    private final LazilyInitialized<LogManager> managerHolder;
    private final Context context;

    private boolean configMayHaveChanged;
    private Logger rootLogger;

    public LogManagerWrapper(final Context context) {
        this.context = context;

        managerHolder = new LazilyInitialized<>(new Callable<LogManager>() {
            @Override
            public LogManager call() throws Exception {
                String clazzName = context.getProperty("java.util.logging.manager");
                if (clazzName == null || clazzName.equals(IsolatingLogManager.class.getName())) {
                    return new DefaultLogManager();
                }

                Class<?> clazz = context.getSystemClassLoader().loadClass(clazzName);
                return (LogManager) clazz.newInstance();
            }
        }, new LogManagerInitializer());
    }

    public LogManager getManager() {
        return managerHolder.get();
    }

    public void reconfigureRootHandlers() {
        LogManager manager = getManager();

        //noinspection SynchronizationOnLocalVariableOrMethodParameter
        synchronized (manager) {
            String handlers = manager.getProperty("handlers");
            if (handlers == null) {
                return;
            }

            for (String handlerName : handlers.split(",")) {
                try {
                    Class clazz = context.getSystemClassLoader().loadClass(handlerName);
                    Handler handler = (Handler) clazz.newInstance();

                    String handlerLevel = manager.getProperty(handlerName + ".level");
                    if (handlerLevel != null) {
                        Level level = Level.parse(handlerLevel);
                        if (level == null) {
                            System.err.println("Failed to parse level: \"" + handlerLevel + "\" for handler " + handlerName);
                        } else {
                            handler.setLevel(level);
                        }
                    }

                    rootLogger.addHandler(handler);
                } catch (Exception e) {
                    System.err.println("Failed to load handler: " + handlerName);
                    e.printStackTrace();
                }
            }
        }
    }

    private class LogManagerInitializer implements LazilyInitialized.Initializer<LogManager> {
        @Override
        public void initialize(final LogManager manager) throws IOException {
            // We need to assign the root logger similarly as is performed in LogManger's static block.
            // The instantiated log manager may or may not use this root logger. In case it does,
            // we must replicate the behavior of LogManager.RootLogger which recreates handlers every
            // time configuration is re-read.
            //
            // However, if this default root logger will not be used we
            // must not attempt to parse the config because it may be of different format. Tomcat
            // for example is using different syntax for "handlers" property. Therefore our root
            // logger must re-read the config only when asked to, lazily.
            rootLogger = createDefaultRootLogger();
            manager.addLogger(rootLogger);

            manager.addPropertyChangeListener(new PropertyChangeListener() {
                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    synchronized (manager) {
                        configMayHaveChanged = true;
                    }
                }
            });

            manager.readConfiguration();
        }

        private Logger createDefaultRootLogger() {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(Logger.class);
            enhancer.setCallback(new MethodInterceptor() {
                @Override
                public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                    synchronized (getManager()) {
                        if (configMayHaveChanged) {
                            configMayHaveChanged = false;
                            reconfigureRootHandlers();
                        }
                    }
                    return methodProxy.invokeSuper(o, objects);
                }
            });
            return (Logger) enhancer.create(new Class[]{String.class, String.class}, new Object[]{"", null});
        }
    }
}
TOP

Related Classes of io.osv.jul.LogManagerWrapper$LogManagerInitializer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.