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

Print this page




 132  * Thus if three processes were all trying to log to fred%u.%g.txt then
 133  * they  might end up using fred0.0.txt, fred1.0.txt, fred2.0.txt as
 134  * the first file in their rotating sequences.
 135  * <p>
 136  * Note that the use of unique ids to avoid conflicts is only guaranteed
 137  * to work reliably when using a local disk file system.
 138  *
 139  * @since 1.4
 140  */
 141 
 142 public class FileHandler extends StreamHandler {
 143     private MeteredStream meter;
 144     private boolean append;
 145     private int limit;       // zero => no limit.
 146     private int count;
 147     private String pattern;
 148     private String lockFileName;
 149     private FileChannel lockFileChannel;
 150     private File files[];
 151     private static final int MAX_LOCKS = 100;
 152     private static java.util.HashMap<String, String> locks = new java.util.HashMap<>();
 153 
 154     /**
 155      * A metered stream is a subclass of OutputStream that
 156      * (a) forwards all its output to a target stream
 157      * (b) keeps track of how many bytes have been written
 158      */
 159     private class MeteredStream extends OutputStream {
 160         OutputStream out;
 161         int written;
 162 
 163         MeteredStream(OutputStream out, int written) {
 164             this.out = out;
 165             this.written = written;
 166         }
 167 

 168         public void write(int b) throws IOException {
 169             out.write(b);
 170             written++;
 171         }
 172 

 173         public void write(byte buff[]) throws IOException {
 174             out.write(buff);
 175             written += buff.length;
 176         }
 177 

 178         public void write(byte buff[], int off, int len) throws IOException {
 179             out.write(buff,off,len);
 180             written += len;
 181         }
 182 

 183         public void flush() throws IOException {
 184             out.flush();
 185         }
 186 

 187         public void close() throws IOException {
 188             out.close();
 189         }
 190     }
 191 
 192     private void open(File fname, boolean append) throws IOException {
 193         int len = 0;
 194         if (append) {
 195             len = (int)fname.length();
 196         }
 197         FileOutputStream fout = new FileOutputStream(fname.toString(), append);
 198         BufferedOutputStream bout = new BufferedOutputStream(fout);
 199         meter = new MeteredStream(bout, len);
 200         setOutputStream(meter);
 201     }
 202 
 203     /**
 204      * Configure a FileHandler from LogManager properties and/or default values
 205      * as specified in the class javadoc.
 206      */


 590                 f1.renameTo(f2);
 591             }
 592         }
 593         try {
 594             open(files[0], false);
 595         } catch (IOException ix) {
 596             // We don't want to throw an exception here, but we
 597             // report the exception to any registered ErrorManager.
 598             reportError(null, ix, ErrorManager.OPEN_FAILURE);
 599 
 600         }
 601         setLevel(oldLevel);
 602     }
 603 
 604     /**
 605      * Format and publish a <tt>LogRecord</tt>.
 606      *
 607      * @param  record  description of the log event. A null record is
 608      *                 silently ignored and is not published
 609      */

 610     public synchronized void publish(LogRecord record) {
 611         if (!isLoggable(record)) {
 612             return;
 613         }
 614         super.publish(record);
 615         flush();
 616         if (limit > 0 && meter.written >= limit) {
 617             // We performed access checks in the "init" method to make sure
 618             // we are only initialized from trusted code.  So we assume
 619             // it is OK to write the target files, even if we are
 620             // currently being called from untrusted code.
 621             // So it is safe to raise privilege here.
 622             AccessController.doPrivileged(new PrivilegedAction<Object>() {

 623                 public Object run() {
 624                     rotate();
 625                     return null;
 626                 }
 627             });
 628         }
 629     }
 630 
 631     /**
 632      * Close all the files.
 633      *
 634      * @exception  SecurityException  if a security manager exists and if
 635      *             the caller does not have <tt>LoggingPermission("control")</tt>.
 636      */

 637     public synchronized void close() throws SecurityException {
 638         super.close();
 639         // Unlock any lock file.
 640         if (lockFileName == null) {
 641             return;
 642         }
 643         try {
 644             // Close the lock file channel (which also will free any locks)
 645             lockFileChannel.close();
 646         } catch (Exception ex) {
 647             // Problems closing the stream.  Punt.
 648         }
 649         synchronized(locks) {
 650             locks.remove(lockFileName);
 651         }
 652         new File(lockFileName).delete();
 653         lockFileName = null;
 654         lockFileChannel = null;
 655     }
 656 
 657     private static class InitializationErrorManager extends ErrorManager {
 658         Exception lastException;

 659         public void error(String msg, Exception ex, int code) {
 660             lastException = ex;
 661         }
 662     }
 663 
 664     /**
 665      * check if we are in a set UID program.
 666      */
 667     private static native boolean isSetUID();
 668 }


 132  * Thus if three processes were all trying to log to fred%u.%g.txt then
 133  * they  might end up using fred0.0.txt, fred1.0.txt, fred2.0.txt as
 134  * the first file in their rotating sequences.
 135  * <p>
 136  * Note that the use of unique ids to avoid conflicts is only guaranteed
 137  * to work reliably when using a local disk file system.
 138  *
 139  * @since 1.4
 140  */
 141 
 142 public class FileHandler extends StreamHandler {
 143     private MeteredStream meter;
 144     private boolean append;
 145     private int limit;       // zero => no limit.
 146     private int count;
 147     private String pattern;
 148     private String lockFileName;
 149     private FileChannel lockFileChannel;
 150     private File files[];
 151     private static final int MAX_LOCKS = 100;
 152     private static final java.util.HashMap<String, String> locks = new java.util.HashMap<>();
 153 
 154     /**
 155      * A metered stream is a subclass of OutputStream that
 156      * (a) forwards all its output to a target stream
 157      * (b) keeps track of how many bytes have been written
 158      */
 159     private class MeteredStream extends OutputStream {
 160         final OutputStream out;
 161         int written;
 162 
 163         MeteredStream(OutputStream out, int written) {
 164             this.out = out;
 165             this.written = written;
 166         }
 167 
 168         @Override
 169         public void write(int b) throws IOException {
 170             out.write(b);
 171             written++;
 172         }
 173 
 174         @Override
 175         public void write(byte buff[]) throws IOException {
 176             out.write(buff);
 177             written += buff.length;
 178         }
 179 
 180         @Override
 181         public void write(byte buff[], int off, int len) throws IOException {
 182             out.write(buff,off,len);
 183             written += len;
 184         }
 185 
 186         @Override
 187         public void flush() throws IOException {
 188             out.flush();
 189         }
 190 
 191         @Override
 192         public void close() throws IOException {
 193             out.close();
 194         }
 195     }
 196 
 197     private void open(File fname, boolean append) throws IOException {
 198         int len = 0;
 199         if (append) {
 200             len = (int)fname.length();
 201         }
 202         FileOutputStream fout = new FileOutputStream(fname.toString(), append);
 203         BufferedOutputStream bout = new BufferedOutputStream(fout);
 204         meter = new MeteredStream(bout, len);
 205         setOutputStream(meter);
 206     }
 207 
 208     /**
 209      * Configure a FileHandler from LogManager properties and/or default values
 210      * as specified in the class javadoc.
 211      */


 595                 f1.renameTo(f2);
 596             }
 597         }
 598         try {
 599             open(files[0], false);
 600         } catch (IOException ix) {
 601             // We don't want to throw an exception here, but we
 602             // report the exception to any registered ErrorManager.
 603             reportError(null, ix, ErrorManager.OPEN_FAILURE);
 604 
 605         }
 606         setLevel(oldLevel);
 607     }
 608 
 609     /**
 610      * Format and publish a <tt>LogRecord</tt>.
 611      *
 612      * @param  record  description of the log event. A null record is
 613      *                 silently ignored and is not published
 614      */
 615     @Override
 616     public synchronized void publish(LogRecord record) {
 617         if (!isLoggable(record)) {
 618             return;
 619         }
 620         super.publish(record);
 621         flush();
 622         if (limit > 0 && meter.written >= limit) {
 623             // We performed access checks in the "init" method to make sure
 624             // we are only initialized from trusted code.  So we assume
 625             // it is OK to write the target files, even if we are
 626             // currently being called from untrusted code.
 627             // So it is safe to raise privilege here.
 628             AccessController.doPrivileged(new PrivilegedAction<Object>() {
 629                 @Override
 630                 public Object run() {
 631                     rotate();
 632                     return null;
 633                 }
 634             });
 635         }
 636     }
 637 
 638     /**
 639      * Close all the files.
 640      *
 641      * @exception  SecurityException  if a security manager exists and if
 642      *             the caller does not have <tt>LoggingPermission("control")</tt>.
 643      */
 644     @Override
 645     public synchronized void close() throws SecurityException {
 646         super.close();
 647         // Unlock any lock file.
 648         if (lockFileName == null) {
 649             return;
 650         }
 651         try {
 652             // Close the lock file channel (which also will free any locks)
 653             lockFileChannel.close();
 654         } catch (Exception ex) {
 655             // Problems closing the stream.  Punt.
 656         }
 657         synchronized(locks) {
 658             locks.remove(lockFileName);
 659         }
 660         new File(lockFileName).delete();
 661         lockFileName = null;
 662         lockFileChannel = null;
 663     }
 664 
 665     private static class InitializationErrorManager extends ErrorManager {
 666         Exception lastException;
 667         @Override
 668         public void error(String msg, Exception ex, int code) {
 669             lastException = ex;
 670         }
 671     }
 672 
 673     /**
 674      * check if we are in a set UID program.
 675      */
 676     private static native boolean isSetUID();
 677 }