< prev index next >

src/java.logging/share/classes/java/util/logging/LogManager.java

Print this page


   1 /*
   2  * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 379             // We use initializedCalled to break the recursion.
 380             initializedCalled = true;
 381             try {
 382                 AccessController.doPrivileged(new PrivilegedAction<Object>() {
 383                     @Override
 384                     public Object run() {
 385                         assert rootLogger == null;
 386                         assert initializedCalled && !initializationDone;
 387 
 388                         // create root logger before reading primordial
 389                         // configuration - to ensure that it will be added
 390                         // before the global logger, and not after.
 391                         final Logger root = owner.rootLogger = owner.new RootLogger();
 392 
 393                         // Read configuration.
 394                         owner.readPrimordialConfiguration();
 395 
 396                         // Create and retain Logger for the root of the namespace.
 397                         owner.addLogger(root);
 398 
 399                         // For backward compatibility: add any handlers configured using
 400                         // ".handlers"
 401                         owner.createLoggerHandlers("", ".handlers")
 402                                 .stream()
 403                                 .forEach(root::addHandler);
 404 
 405                         // Initialize level if not yet initialized
 406                         if (!root.isLevelInitialized()) {
 407                             root.setLevel(defaultLevel);
 408                         }
 409 
 410                         // Adding the global Logger.
 411                         // Do not call Logger.getGlobal() here as this might trigger
 412                         // subtle inter-dependency issues.
 413                         @SuppressWarnings("deprecation")
 414                         final Logger global = Logger.global;
 415 
 416                         // Make sure the global logger will be registered in the
 417                         // global manager
 418                         owner.addLogger(global);
 419                         return null;
 420                     }
 421                 });
 422             } finally {
 423                 initializationDone = true;
 424             }


 978             }
 979         });
 980     }
 981 
 982     private void setLoggerHandlers(final Logger logger, final String name,
 983                                    final String handlersPropertyName,
 984                                    List<Handler> handlers)
 985     {
 986         final boolean ensureCloseOnReset = ! handlers.isEmpty()
 987                     && getBooleanProperty(handlersPropertyName + ".ensureCloseOnReset",true);
 988         int count = 0;
 989         for (Handler hdl : handlers) {
 990             logger.addHandler(hdl);
 991             if (++count == 1 && ensureCloseOnReset) {
 992                 // add this logger to the closeOnResetLoggers list.
 993                 closeOnResetLoggers.addIfAbsent(CloseOnReset.create(logger));
 994             }
 995         }
 996     }
 997 
 998     private List<Handler> createLoggerHandlers(final String name, final String handlersPropertyName)

 999     {
1000         String names[] = parseClassNames(handlersPropertyName);
1001         List<Handler> handlers = new ArrayList<>(names.length);
1002         for (String type : names) {
1003             try {
1004                 @SuppressWarnings("deprecation")
1005                 Object o = ClassLoader.getSystemClassLoader().loadClass(type).newInstance();
1006                 Handler hdl = (Handler) o;
1007                 // Check if there is a property defining the
1008                 // this handler's level.
1009                 String levs = getProperty(type + ".level");
1010                 if (levs != null) {
1011                     Level l = Level.findLevel(levs);
1012                     if (l != null) {
1013                         hdl.setLevel(l);
1014                     } else {
1015                         // Probably a bad level. Drop through.
1016                         System.err.println("Can't set level for " + type);
1017                     }
1018                 }


1158     //   - minimum: 0.02 ms
1159     //   - maximum: 10.9 ms
1160     //
1161     private final static int MAX_ITERATIONS = 400;
1162     final void drainLoggerRefQueueBounded() {
1163         for (int i = 0; i < MAX_ITERATIONS; i++) {
1164             if (loggerRefQueue == null) {
1165                 // haven't finished loading LogManager yet
1166                 break;
1167             }
1168 
1169             LoggerWeakRef ref = (LoggerWeakRef) loggerRefQueue.poll();
1170             if (ref == null) {
1171                 break;
1172             }
1173             // a Logger object has been GC'ed so clean it up
1174             ref.dispose();
1175         }
1176     }
1177 






1178     /**
1179      * Add a named logger.  This does nothing and returns false if a logger
1180      * with the same name is already registered.
1181      * <p>
1182      * The Logger factory methods call this method to register each
1183      * newly created Logger.
1184      * <p>
1185      * The application should retain its own reference to the Logger
1186      * object to avoid it being garbage collected.  The LogManager
1187      * may only retain a weak reference.
1188      *
1189      * @param   logger the new logger.
1190      * @return  true if the argument logger was registered successfully,
1191      *          false if a logger of that name already exists.
1192      * @exception NullPointerException if the logger name is null.
1193      */
1194     public boolean addLogger(Logger logger) {
1195         final String name = logger.getName();
1196         if (name == null) {
1197             throw new NullPointerException();
1198         }
1199         drainLoggerRefQueueBounded();
1200         LoggerContext cx = getUserContext();
1201         if (cx.addLocalLogger(logger)) {
1202             // Do we have a per logger handler too?
1203             // Note: this will add a 200ms penalty
1204             loadLoggerHandlers(logger, name, name + ".handlers");
1205             return true;














1206         } else {
1207             return false;
1208         }
1209     }
1210 
1211     // Private method to set a level on a logger.
1212     // If necessary, we raise privilege before doing the call.
1213     private static void doSetLevel(final Logger logger, final Level level) {
1214         SecurityManager sm = System.getSecurityManager();
1215         if (sm == null) {
1216             // There is no security manager, so things are easy.
1217             logger.setLevel(level);
1218             return;
1219         }
1220         // There is a security manager.  Raise privilege before
1221         // calling setLevel.
1222         AccessController.doPrivileged(new PrivilegedAction<Object>() {
1223             @Override
1224             public Object run() {
1225                 logger.setLevel(level);


   1 /*
   2  * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 379             // We use initializedCalled to break the recursion.
 380             initializedCalled = true;
 381             try {
 382                 AccessController.doPrivileged(new PrivilegedAction<Object>() {
 383                     @Override
 384                     public Object run() {
 385                         assert rootLogger == null;
 386                         assert initializedCalled && !initializationDone;
 387 
 388                         // create root logger before reading primordial
 389                         // configuration - to ensure that it will be added
 390                         // before the global logger, and not after.
 391                         final Logger root = owner.rootLogger = owner.new RootLogger();
 392 
 393                         // Read configuration.
 394                         owner.readPrimordialConfiguration();
 395 
 396                         // Create and retain Logger for the root of the namespace.
 397                         owner.addLogger(root);
 398 






 399                         // Initialize level if not yet initialized
 400                         if (!root.isLevelInitialized()) {
 401                             root.setLevel(defaultLevel);
 402                         }
 403 
 404                         // Adding the global Logger.
 405                         // Do not call Logger.getGlobal() here as this might trigger
 406                         // subtle inter-dependency issues.
 407                         @SuppressWarnings("deprecation")
 408                         final Logger global = Logger.global;
 409 
 410                         // Make sure the global logger will be registered in the
 411                         // global manager
 412                         owner.addLogger(global);
 413                         return null;
 414                     }
 415                 });
 416             } finally {
 417                 initializationDone = true;
 418             }


 972             }
 973         });
 974     }
 975 
 976     private void setLoggerHandlers(final Logger logger, final String name,
 977                                    final String handlersPropertyName,
 978                                    List<Handler> handlers)
 979     {
 980         final boolean ensureCloseOnReset = ! handlers.isEmpty()
 981                     && getBooleanProperty(handlersPropertyName + ".ensureCloseOnReset",true);
 982         int count = 0;
 983         for (Handler hdl : handlers) {
 984             logger.addHandler(hdl);
 985             if (++count == 1 && ensureCloseOnReset) {
 986                 // add this logger to the closeOnResetLoggers list.
 987                 closeOnResetLoggers.addIfAbsent(CloseOnReset.create(logger));
 988             }
 989         }
 990     }
 991 
 992     private List<Handler> createLoggerHandlers(final String name,
 993                                                final String handlersPropertyName)
 994     {
 995         String names[] = parseClassNames(handlersPropertyName);
 996         List<Handler> handlers = new ArrayList<>(names.length);
 997         for (String type : names) {
 998             try {
 999                 @SuppressWarnings("deprecation")
1000                 Object o = ClassLoader.getSystemClassLoader().loadClass(type).newInstance();
1001                 Handler hdl = (Handler) o;
1002                 // Check if there is a property defining the
1003                 // this handler's level.
1004                 String levs = getProperty(type + ".level");
1005                 if (levs != null) {
1006                     Level l = Level.findLevel(levs);
1007                     if (l != null) {
1008                         hdl.setLevel(l);
1009                     } else {
1010                         // Probably a bad level. Drop through.
1011                         System.err.println("Can't set level for " + type);
1012                     }
1013                 }


1153     //   - minimum: 0.02 ms
1154     //   - maximum: 10.9 ms
1155     //
1156     private final static int MAX_ITERATIONS = 400;
1157     final void drainLoggerRefQueueBounded() {
1158         for (int i = 0; i < MAX_ITERATIONS; i++) {
1159             if (loggerRefQueue == null) {
1160                 // haven't finished loading LogManager yet
1161                 break;
1162             }
1163 
1164             LoggerWeakRef ref = (LoggerWeakRef) loggerRefQueue.poll();
1165             if (ref == null) {
1166                 break;
1167             }
1168             // a Logger object has been GC'ed so clean it up
1169             ref.dispose();
1170         }
1171     }
1172 
1173     @SuppressWarnings("deprecation")
1174     private boolean isSpecialLogger(Logger logger) {
1175         assert logger != null;
1176         return logger == rootLogger ||  logger == Logger.global;
1177     }
1178 
1179     /**
1180      * Add a named logger.  This does nothing and returns false if a logger
1181      * with the same name is already registered.
1182      * <p>
1183      * The Logger factory methods call this method to register each
1184      * newly created Logger.
1185      * <p>
1186      * The application should retain its own reference to the Logger
1187      * object to avoid it being garbage collected.  The LogManager
1188      * may only retain a weak reference.
1189      *
1190      * @param   logger the new logger.
1191      * @return  true if the argument logger was registered successfully,
1192      *          false if a logger of that name already exists.
1193      * @exception NullPointerException if the logger name is null.
1194      */
1195     public boolean addLogger(Logger logger) {
1196         final String name = logger.getName();
1197         if (name == null) {
1198             throw new NullPointerException();
1199         }
1200         drainLoggerRefQueueBounded();
1201         LoggerContext cx = getUserContext();
1202         if (cx.addLocalLogger(logger)) {
1203             // Do we have a per logger handler too?
1204             // Note: this will add a 200ms penalty
1205             loadLoggerHandlers(logger, name, name + ".handlers");
1206             return true;
1207         } else if (isSpecialLogger(logger)
1208                    && !initializationDone
1209                    && initializedCalled
1210                    && configurationLock.isHeldByCurrentThread()) {
1211             // Called just after reading the primordial configuration, in
1212             // the same thread that read it.
1213             // The root and global logger would already be present in the context
1214             // by this point, but we would not have called loadLoggerHandlers
1215             // yet.
1216             // For backward compatibility: add any handlers configured using
1217             // ".handlers" to the root logger, or any handlers configured
1218             // with "global.handlers" to the global logger.
1219             loadLoggerHandlers(logger, name, name + ".handlers");
1220             return true;
1221         } else {
1222             return false;
1223         }
1224     }
1225 
1226     // Private method to set a level on a logger.
1227     // If necessary, we raise privilege before doing the call.
1228     private static void doSetLevel(final Logger logger, final Level level) {
1229         SecurityManager sm = System.getSecurityManager();
1230         if (sm == null) {
1231             // There is no security manager, so things are easy.
1232             logger.setLevel(level);
1233             return;
1234         }
1235         // There is a security manager.  Raise privilege before
1236         // calling setLevel.
1237         AccessController.doPrivileged(new PrivilegedAction<Object>() {
1238             @Override
1239             public Object run() {
1240                 logger.setLevel(level);


< prev index next >