< prev index next >

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

Print this page


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


 139  * <p>
 140  * Thus if three processes were all trying to log to fred%u.%g.txt then
 141  * they  might end up using fred0.0.txt, fred1.0.txt, fred2.0.txt as
 142  * the first file in their rotating sequences.
 143  * <p>
 144  * Note that the use of unique ids to avoid conflicts is only guaranteed
 145  * to work reliably when using a local disk file system.
 146  *
 147  * @since 1.4
 148  */
 149 
 150 public class FileHandler extends StreamHandler {
 151     private MeteredStream meter;
 152     private boolean append;
 153     private int limit;       // zero => no limit.
 154     private int count;
 155     private String pattern;
 156     private String lockFileName;
 157     private FileChannel lockFileChannel;
 158     private File files[];
 159     private static final int MAX_LOCKS = 100;

 160     private static final Set<String> locks = new HashSet<>();
 161 

















 162     /**
 163      * A metered stream is a subclass of OutputStream that
 164      * (a) forwards all its output to a target stream
 165      * (b) keeps track of how many bytes have been written
 166      */
 167     private class MeteredStream extends OutputStream {
 168         final OutputStream out;
 169         int written;
 170 
 171         MeteredStream(OutputStream out, int written) {
 172             this.out = out;
 173             this.written = written;
 174         }
 175 
 176         @Override
 177         public void write(int b) throws IOException {
 178             out.write(b);
 179             written++;
 180         }
 181 


 417     private void openFiles() throws IOException {
 418         LogManager manager = LogManager.getLogManager();
 419         manager.checkPermission();
 420         if (count < 1) {
 421            throw new IllegalArgumentException("file count = " + count);
 422         }
 423         if (limit < 0) {
 424             limit = 0;
 425         }
 426 
 427         // We register our own ErrorManager during initialization
 428         // so we can record exceptions.
 429         InitializationErrorManager em = new InitializationErrorManager();
 430         setErrorManager(em);
 431 
 432         // Create a lock file.  This grants us exclusive access
 433         // to our set of output files, as long as we are alive.
 434         int unique = -1;
 435         for (;;) {
 436             unique++;
 437             if (unique > MAX_LOCKS) {
 438                 throw new IOException("Couldn't get lock for " + pattern);

 439             }
 440             // Generate a lock file name from the "unique" int.
 441             lockFileName = generate(pattern, 0, unique).toString() + ".lck";
 442             // Now try to lock that filename.
 443             // Because some systems (e.g., Solaris) can only do file locks
 444             // between processes (and not within a process), we first check
 445             // if we ourself already have the file locked.
 446             synchronized(locks) {
 447                 if (locks.contains(lockFileName)) {
 448                     // We already own this lock, for a different FileHandler
 449                     // object.  Try again.
 450                     continue;
 451                 }
 452 
 453                 final Path lockFilePath = Paths.get(lockFileName);
 454                 FileChannel channel = null;
 455                 int retries = -1;
 456                 boolean fileCreated = false;
 457                 while (channel == null && retries++ < 1) {
 458                     try {


   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


 139  * <p>
 140  * Thus if three processes were all trying to log to fred%u.%g.txt then
 141  * they  might end up using fred0.0.txt, fred1.0.txt, fred2.0.txt as
 142  * the first file in their rotating sequences.
 143  * <p>
 144  * Note that the use of unique ids to avoid conflicts is only guaranteed
 145  * to work reliably when using a local disk file system.
 146  *
 147  * @since 1.4
 148  */
 149 
 150 public class FileHandler extends StreamHandler {
 151     private MeteredStream meter;
 152     private boolean append;
 153     private int limit;       // zero => no limit.
 154     private int count;
 155     private String pattern;
 156     private String lockFileName;
 157     private FileChannel lockFileChannel;
 158     private File files[];
 159     private static final int DEFAULT_MAX_LOCKS = 100;
 160     private static int maxLocks;
 161     private static final Set<String> locks = new HashSet<>();
 162     
 163     /*
 164      * Initialize maxLocks from the System property if set.
 165      * If invalid/no property is provided 100 will be used as a default value.
 166      */
 167     static {
 168         maxLocks = java.security.AccessController.doPrivileged(
 169                 (PrivilegedAction<Integer>) () ->
 170                         Integer.getInteger(
 171                                 "jdk.internal.FileHandlerLogging.maxLocks",
 172                                 DEFAULT_MAX_LOCKS)
 173         );
 174 
 175         if (maxLocks <= 0) {
 176             maxLocks = DEFAULT_MAX_LOCKS;
 177         }
 178     }
 179 
 180     /**
 181      * A metered stream is a subclass of OutputStream that
 182      * (a) forwards all its output to a target stream
 183      * (b) keeps track of how many bytes have been written
 184      */
 185     private class MeteredStream extends OutputStream {
 186         final OutputStream out;
 187         int written;
 188 
 189         MeteredStream(OutputStream out, int written) {
 190             this.out = out;
 191             this.written = written;
 192         }
 193 
 194         @Override
 195         public void write(int b) throws IOException {
 196             out.write(b);
 197             written++;
 198         }
 199 


 435     private void openFiles() throws IOException {
 436         LogManager manager = LogManager.getLogManager();
 437         manager.checkPermission();
 438         if (count < 1) {
 439            throw new IllegalArgumentException("file count = " + count);
 440         }
 441         if (limit < 0) {
 442             limit = 0;
 443         }
 444 
 445         // We register our own ErrorManager during initialization
 446         // so we can record exceptions.
 447         InitializationErrorManager em = new InitializationErrorManager();
 448         setErrorManager(em);
 449 
 450         // Create a lock file.  This grants us exclusive access
 451         // to our set of output files, as long as we are alive.
 452         int unique = -1;
 453         for (;;) {
 454             unique++;
 455             if (unique > maxLocks) {
 456                 throw new IOException("Couldn't get lock for " + pattern
 457                         + ", maxLocks: " + maxLocks);
 458             }
 459             // Generate a lock file name from the "unique" int.
 460             lockFileName = generate(pattern, 0, unique).toString() + ".lck";
 461             // Now try to lock that filename.
 462             // Because some systems (e.g., Solaris) can only do file locks
 463             // between processes (and not within a process), we first check
 464             // if we ourself already have the file locked.
 465             synchronized(locks) {
 466                 if (locks.contains(lockFileName)) {
 467                     // We already own this lock, for a different FileHandler
 468                     // object.  Try again.
 469                     continue;
 470                 }
 471 
 472                 final Path lockFilePath = Paths.get(lockFileName);
 473                 FileChannel channel = null;
 474                 int retries = -1;
 475                 boolean fileCreated = false;
 476                 while (channel == null && retries++ < 1) {
 477                     try {


< prev index next >