4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * The contents of this file are subject to the terms
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * of the Common Development and Distribution License
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * (the License). You may not use this file except in
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * compliance with the License.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * You can obtain a copy of the License at
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * https://opensso.dev.java.net/public/CDDLv1.0.html or
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * See the License for the specific language governing
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * permission and limitations under the License.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * When distributing Covered Code, include this CDDL
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Header Notice in each file and include the License file
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * If applicable, add the following below the CDDL Header,
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * with the fields enclosed by brackets [] replaced by
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * your own identifying information:
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * "Portions Copyrighted [year] [name of copyright owner]"
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * $Id: FileHandler.java,v 1.14 2009/07/27 19:50:55 bigfatrat Exp $
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Portions Copyrighted 2011-2016 ForgeRock AS.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Portions Copyrighted 2014 Nomura Research Institute, Ltd
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport com.sun.identity.common.GeneralTaskRunnable;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport com.sun.identity.monitoring.MonitoringUtil;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport com.sun.identity.monitoring.SsoServerLoggingHdlrEntryImpl;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkimport com.sun.identity.monitoring.SsoServerLoggingSvcImpl;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * This <tt> FileHandler </tt> is very much similar to the
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * <t> java.util.logging.FileHandler </tt>. <p> The <TT> FileHandler </TT>
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * can either write to a specified file, or it can write to a rotating set
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * of files. <P>
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * For a rotating set of files, as each file reaches the limit
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * (<i> LogConstants.MAX_FILE_SIZE</I>), it is closed, rotated out, and a
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * new file opened. Successively older files and named by adding "-1", "-2",
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * etc., * to the base filename. The Locking mechanism is much more relaxed
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * (in JDK's FileHandler an exclusive lock is created on the file till the
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * handler is closed which makes reading impossible)
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenkpublic class FileHandler extends java.util.logging.Handler {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk private LogManager lmanager = LogManagerUtil.getLogManager();
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk private int count; // count represent number of history files
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk private SsoServerLoggingSvcImpl logServiceImplForMonitoring = null;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk private SsoServerLoggingHdlrEntryImpl fileLogHandlerForMonitoring = null;
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * By default the size based rotation is enabled
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk private static final String DEFAULT_LOG_SUFFIX_FORMAT = "-MM.dd.yy-kk.mm";
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk private class MeteredStream extends OutputStream {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk MeteredStream(File fileName, boolean append) throws IOException {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk FileOutputStream fout = new FileOutputStream(filename, append);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * writes a single integer to the outputstream and increments
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * the number of bytes written by one.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * @param b integer value to be written.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * @throws IOException if it fails to write out.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Writes the array of bytes to the output stream and increments
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * the number of bytes written by the size of the array.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * @param b the byte array to be written.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * @throws IOException if it fails to write out.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk public void write(byte[] b) throws IOException {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Writes the array of bytes to the output stream and increments
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * the number of bytes written by the size of the array.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * @param b the byte array to be written.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * @param offset the offset of array to be written.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * @param length the length of bytes to be written.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * @throws IOException if it fails to write out.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk public void write(byte[] b, int offset, int length)
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Flush any buffered messages.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * @throws IOException if it fails to write out.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * close the current output stream.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * @throws IOException if it fails to close output stream.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * sets the output stream to the specified output stream ..picked up from
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * StreamHandler.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk private void setOutputStream(OutputStream out) throws SecurityException,
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk Debug.warning(fileName + ":FileHandler: OutputStream is null");
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk writer = new OutputStreamWriter(output, encoding);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk Debug.error(fileName + ":FileHandler: Unsupported Encoding", e);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk throw new UnsupportedEncodingException(e.getMessage());
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * Set (or change) the character encoding used by this <tt>Handler</tt>.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * The encoding should be set before any <tt>LogRecords</tt> are written
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * to the <tt>Handler</tt>.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * @param encoding The name of a supported character encoding.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * May be null, to indicate the default platform encoding.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * @exception SecurityException if a security manager exists and if
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * the caller does not have
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * <tt>LoggingPermission("control")</tt>.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * @exception UnsupportedEncodingException if the named encoding is
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * not supported.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk public void setEncoding(String encoding) throws SecurityException,
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk // Replace the current writer with a writer for the new encoding.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk writer = new OutputStreamWriter(output, encoding);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * This method is used for getting the properties from LogManager
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk * and setting the private variables count, maxFileSize etc.
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk throws NullLocationException, FormatterInitException {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk String bufferSize = lmanager.getProperty(LogConstants.BUFFER_SIZE);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk if (bufferSize != null && bufferSize.length() > 0) {
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk ":FileHandler: Setting buffer size to 1");
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk ":FileHandler: Invalid buffer size: " + bufferSize);
4b8d88eb610aa1e0bb6ec632f792744b3d6b5f22jeff.schenk ":FileHandler: Setting buffer size to 1");
timeBufferingEnabled = true;
throw new NullLocationException(
} catch (Exception e) {
throw new FormatterInitException(
if (rotateEnabled) {
rotatingBySize = false;
configure();
ioe);
if (timeBufferingEnabled) {
flush();
} catch (IOException e) {
return headerString;
null) {
rotate();
if (!headerWritten) {
headerWritten = true;
cleanup();
if (rotateEnabled) {
if (rotatingBySize) {
if (rotatingBySize) {
if (!renameSuccess) {
fnfe);
ioex);
ioe);
headerWritten = true;
headerWritten = false;
null) {
rotate();
if (!headerWritten) {
headerWritten = true;
cleanup();
return runPeriod;
long interval;
SystemTimer.getTimer().schedule(bufferTask, new Date(((currentTimeMillis() + interval) / 1000) * 1000));
} catch (IllegalArgumentException e) {
e.getMessage());
} catch (IllegalStateException e) {
e.getMessage());