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

Print this page


   1 /*
   2  * Copyright (c) 2000, 2006, 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


 167     private LogManager manager;
 168     private String name;
 169     private final CopyOnWriteArrayList<Handler> handlers =
 170         new CopyOnWriteArrayList<Handler>();
 171     private String resourceBundleName;
 172     private volatile boolean useParentHandlers = true;
 173     private volatile Filter filter;
 174     private boolean anonymous;
 175 
 176     private ResourceBundle catalog;     // Cached resource bundle
 177     private String catalogName;         // name associated with catalog
 178     private Locale catalogLocale;       // locale associated with catalog
 179 
 180     // The fields relating to parent-child relationships and levels
 181     // are managed under a separate lock, the treeLock.
 182     private static Object treeLock = new Object();
 183     // We keep weak references from parents to children, but strong
 184     // references from children to parents.
 185     private volatile Logger parent;    // our nearest parent.
 186     private ArrayList<WeakReference<Logger>> kids;   // WeakReferences to loggers that have us as parent



 187     private volatile Level levelObject;
 188     private volatile int levelValue;  // current effective level value
 189 
 190     /**
 191      * GLOBAL_LOGGER_NAME is a name for the global logger.
 192      *
 193      * @since 1.6
 194      */
 195     public static final String GLOBAL_LOGGER_NAME = "global";
 196 
 197     /**
 198      * Return global logger object with the name Logger.GLOBAL_LOGGER_NAME.
 199      *
 200      * @return global logger object
 201      * @since 1.7
 202      */
 203     public static final Logger getGlobal() {
 204         return global;
 205     }
 206 


1371     }
1372 
1373     // Private method to do the work for parenting a child
1374     // Logger onto a parent logger.
1375     private void doSetParent(Logger newParent) {
1376 
1377         // System.err.println("doSetParent \"" + getName() + "\" \""
1378         //                              + newParent.getName() + "\"");
1379 
1380         synchronized (treeLock) {
1381 
1382             // Remove ourself from any previous parent.
1383             if (parent != null) {
1384                 // assert parent.kids != null;
1385                 for (Iterator<WeakReference<Logger>> iter = parent.kids.iterator(); iter.hasNext(); ) {
1386                     WeakReference<Logger> ref =  iter.next();
1387                     Logger kid =  ref.get();
1388                     if (kid == this) {
1389                         iter.remove();
1390                         break;








1391                     }
1392                 }
1393                 // We have now removed ourself from our parents' kids.
1394             }
1395 
1396             // Set our new parent.
1397             parent = newParent;
1398             if (parent.kids == null) {
1399                 parent.kids = new ArrayList<WeakReference<Logger>>(2);
1400             }
1401             parent.kids.add(new WeakReference<Logger>(this));
1402 
1403             // As a result of the reparenting, the effective level
1404             // may have changed for us and our children.
1405             updateEffectiveLevel();
1406 









1407         }
1408     }
1409 
1410     // Recalculate the effective level for this node and
1411     // recursively for our children.
1412 
1413     private void updateEffectiveLevel() {
1414         // assert Thread.holdsLock(treeLock);
1415 
1416         // Figure out our current effective level.
1417         int newLevelValue;
1418         if (levelObject != null) {
1419             newLevelValue = levelObject.intValue();
1420         } else {
1421             if (parent != null) {
1422                 newLevelValue = parent.levelValue;
1423             } else {
1424                 // This may happen during initialization.
1425                 newLevelValue = Level.INFO.intValue();
1426             }
1427         }
1428 
1429         // If our effective value hasn't changed, we're done.
1430         if (levelValue == newLevelValue) {
1431             return;
1432         }
1433 
1434         levelValue = newLevelValue;
1435 
1436         // System.err.println("effective level: \"" + getName() + "\" := " + level);
1437 
1438         // Recursively update the level on each of our kids.
1439         if (kids != null) {
1440             for (int i = 0; i < kids.size(); i++) {
1441                 WeakReference<Logger> ref = kids.get(i);

1442                 Logger kid =  ref.get();
1443                 if (kid != null) {
1444                     kid.updateEffectiveLevel();







1445                 }
1446             }























1447         }
1448     }
1449 
1450 
1451     // Private method to get the potentially inherited
1452     // resource bundle name for this Logger.
1453     // May return null
1454     private String getEffectiveResourceBundleName() {
1455         Logger target = this;
1456         while (target != null) {
1457             String rbn = target.getResourceBundleName();
1458             if (rbn != null) {
1459                 return rbn;
1460             }
1461             target = target.getParent();
1462         }
1463         return null;
1464     }
1465 
1466 
   1 /*
   2  * Copyright (c) 2000, 2010, 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


 167     private LogManager manager;
 168     private String name;
 169     private final CopyOnWriteArrayList<Handler> handlers =
 170         new CopyOnWriteArrayList<Handler>();
 171     private String resourceBundleName;
 172     private volatile boolean useParentHandlers = true;
 173     private volatile Filter filter;
 174     private boolean anonymous;
 175 
 176     private ResourceBundle catalog;     // Cached resource bundle
 177     private String catalogName;         // name associated with catalog
 178     private Locale catalogLocale;       // locale associated with catalog
 179 
 180     // The fields relating to parent-child relationships and levels
 181     // are managed under a separate lock, the treeLock.
 182     private static Object treeLock = new Object();
 183     // We keep weak references from parents to children, but strong
 184     // references from children to parents.
 185     private volatile Logger parent;    // our nearest parent.
 186     private ArrayList<WeakReference<Logger>> kids;   // WeakReferences to loggers that have us as parent
 187     // marker to know if this Logger has already been visited during the
 188     // current WeakReference cleanup pass
 189     private int kidsCleanupMarker;
 190     private volatile Level levelObject;
 191     private volatile int levelValue;  // current effective level value
 192 
 193     /**
 194      * GLOBAL_LOGGER_NAME is a name for the global logger.
 195      *
 196      * @since 1.6
 197      */
 198     public static final String GLOBAL_LOGGER_NAME = "global";
 199 
 200     /**
 201      * Return global logger object with the name Logger.GLOBAL_LOGGER_NAME.
 202      *
 203      * @return global logger object
 204      * @since 1.7
 205      */
 206     public static final Logger getGlobal() {
 207         return global;
 208     }
 209 


1374     }
1375 
1376     // Private method to do the work for parenting a child
1377     // Logger onto a parent logger.
1378     private void doSetParent(Logger newParent) {
1379 
1380         // System.err.println("doSetParent \"" + getName() + "\" \""
1381         //                              + newParent.getName() + "\"");
1382 
1383         synchronized (treeLock) {
1384 
1385             // Remove ourself from any previous parent.
1386             if (parent != null) {
1387                 // assert parent.kids != null;
1388                 for (Iterator<WeakReference<Logger>> iter = parent.kids.iterator(); iter.hasNext(); ) {
1389                     WeakReference<Logger> ref =  iter.next();
1390                     Logger kid =  ref.get();
1391                     if (kid == this) {
1392                         iter.remove();
1393                         break;
1394                     } else if (kid == null) {
1395                         // Since we're already iterating the previous
1396                         // parent's kid list, remove any stale weak
1397                         // references to Logger objects that have been
1398                         // GC'ed. Note this will only cleanup stale weak
1399                         // refs that we encounter before we find ourself
1400                         // on the kids list.
1401                         iter.remove();
1402                     }
1403                 }
1404                 // We have now removed ourself from our parents' kids.
1405             }
1406 
1407             // Set our new parent.
1408             parent = newParent;
1409             if (parent.kids == null) {
1410                 parent.kids = new ArrayList<WeakReference<Logger>>(2);
1411             }
1412             parent.kids.add(new WeakReference<Logger>(this));
1413 
1414             // As a result of the reparenting, the effective level
1415             // may have changed for us and our children.
1416             updateEffectiveLevel();
1417 
1418             // Look for possible weak reference cleanup from the new
1419             // parent Logger down. The updateEffectiveLevel() call above
1420             // might have already done some or none of this work so
1421             // this call is the only way to be absolutely sure we have
1422             // have checked for stale weak refs in every Logger in the
1423             // parent Logger's hierarchy. See deleteStaleWeakRefs()
1424             // below for why this marker is needed.
1425             parent.kidsCleanupMarker = (int) System.currentTimeMillis();
1426             parent.deleteStaleWeakRefs(parent.kidsCleanupMarker);
1427         }
1428     }
1429 
1430     // Recalculate the effective level for this node and
1431     // recursively for our children.
1432 
1433     private void updateEffectiveLevel() {
1434         // assert Thread.holdsLock(treeLock);
1435 
1436         // Figure out our current effective level.
1437         int newLevelValue;
1438         if (levelObject != null) {
1439             newLevelValue = levelObject.intValue();
1440         } else {
1441             if (parent != null) {
1442                 newLevelValue = parent.levelValue;
1443             } else {
1444                 // This may happen during initialization.
1445                 newLevelValue = Level.INFO.intValue();
1446             }
1447         }
1448 
1449         // If our effective value hasn't changed, we're done.
1450         if (levelValue == newLevelValue) {
1451             return;
1452         }
1453 
1454         levelValue = newLevelValue;
1455 
1456         // System.err.println("effective level: \"" + getName() + "\" := " + level);
1457 
1458         // Recursively update the level on each of our kids.
1459         if (kids != null) {
1460             for (Iterator<WeakReference<Logger>> iter = kids.iterator();
1461                  iter.hasNext(); ) {
1462                 WeakReference<Logger> ref = iter.next();
1463                 Logger kid =  ref.get();
1464                 if (kid != null) {
1465                     kid.updateEffectiveLevel();
1466                 } else {
1467                     // Since we're already iterating this kid list,
1468                     // remove any stale weak references to Logger
1469                     // objects that have been GC'ed. Note this will
1470                     // only cleanup stale weak refs that we encounter
1471                     // when we have to update the effective Level value.
1472                     iter.remove();
1473                 }
1474             }
1475         }
1476     }
1477 
1478 
1479     // Recursively delete stale WeakReferences on each of our kids.
1480     // The marker parameter is used to know if a kid has been visited
1481     // before. This marker logic is needed because the Logging API
1482     // currently permits loops to be created in the Logger hierarchy.
1483     private void deleteStaleWeakRefs(int marker) {
1484         if (kids != null) {
1485             for (Iterator<WeakReference<Logger>> iter = kids.iterator();
1486                  iter.hasNext(); ) {
1487                 WeakReference<Logger> ref = iter.next();
1488                 Logger kid =  ref.get();
1489                 if (kid == null) {
1490                     // Logger has been GC'ed so delete the stale weak ref
1491                     iter.remove();
1492                 } else if (kid.kidsCleanupMarker != marker) {
1493                     // visit the non-GC'ed Logger (and its kids, if any)
1494                     kid.kidsCleanupMarker = marker;
1495                     kid.deleteStaleWeakRefs(marker);
1496                 }
1497             }
1498         }
1499     }
1500 
1501 
1502     // Private method to get the potentially inherited
1503     // resource bundle name for this Logger.
1504     // May return null
1505     private String getEffectiveResourceBundleName() {
1506         Logger target = this;
1507         while (target != null) {
1508             String rbn = target.getResourceBundleName();
1509             if (rbn != null) {
1510                 return rbn;
1511             }
1512             target = target.getParent();
1513         }
1514         return null;
1515     }
1516 
1517