DebugImpl.java revision c1b45299506613a522e8eeaffe0efd1b9cd5e355
4501N/A/**
4501N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4501N/A *
4501N/A * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved
4501N/A *
4501N/A * The contents of this file are subject to the terms
4501N/A * of the Common Development and Distribution License
4501N/A * (the License). You may not use this file except in
4501N/A * compliance with the License.
4501N/A *
4501N/A * You can obtain a copy of the License at
4501N/A * https://opensso.dev.java.net/public/CDDLv1.0.html or
4501N/A * opensso/legal/CDDLv1.0.txt
4501N/A * See the License for the specific language governing
4501N/A * permission and limitations under the License.
4501N/A *
4501N/A * When distributing Covered Code, include this CDDL
4501N/A * Header Notice in each file and include the License file
4501N/A * at opensso/legal/CDDLv1.0.txt.
4501N/A * If applicable, add the following below the CDDL Header,
4501N/A * with the fields enclosed by brackets [] replaced by
4501N/A * your own identifying information:
4501N/A * "Portions Copyrighted [year] [name of copyright owner]"
4501N/A *
4501N/A * $Id: DebugImpl.java,v 1.4 2009/03/07 08:01:53 veiming Exp $
4501N/A *
4517N/A */
4501N/A
4501N/A/**
4830N/A * Portions Copyrighted 2014-2015 ForgeRock AS.
4811N/A */
4798N/Apackage com.sun.identity.shared.debug.impl;
4501N/A
4501N/Aimport com.sun.identity.shared.configuration.SystemPropertiesManager;
4501N/Aimport com.sun.identity.shared.debug.DebugConstants;
4501N/Aimport com.sun.identity.shared.debug.DebugLevel;
4501N/Aimport com.sun.identity.shared.debug.IDebug;
4501N/Aimport com.sun.identity.shared.debug.file.DebugFile;
4501N/Aimport com.sun.identity.shared.debug.file.DebugFileProvider;
4837N/Aimport com.sun.identity.shared.debug.file.impl.StdDebugFile;
4501N/Aimport org.forgerock.openam.utils.IOUtils;
4671N/A
4501N/Aimport java.io.IOException;
4501N/Aimport java.io.InputStream;
4671N/Aimport java.text.SimpleDateFormat;
4501N/Aimport java.util.Date;
4501N/Aimport java.util.Properties;
4501N/A
4501N/A/**
4798N/A * Debug implementation class.
4501N/A */
4501N/Apublic class DebugImpl implements IDebug {
4501N/A
4798N/A private static Properties debugFileNames;
4798N/A
4501N/A static {
4501N/A initProperties();
4501N/A }
4830N/A
4830N/A private final static int DIR_ISSUE_ERROR_INTERVAL_IN_MS = 60 * 1000;
4830N/A private static volatile long lastDirectoryIssue = 0l;
4501N/A
4501N/A private final String debugName;
4501N/A private boolean mergeAllMode = false;
4501N/A
4501N/A private DebugLevel debugLevel = DebugLevel.ON;
4501N/A
4501N/A private SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss:SSS a zzz");
4501N/A
4501N/A private DebugFileProvider debugFileProvider;
4501N/A private DebugFile debugFile = null;
4798N/A private DebugFile stdoutDebugFile;
4501N/A
4501N/A /**
4798N/A * Creates an instance of <code>DebugImpl</code>.
4501N/A *
4501N/A * @param debugName Name of the debug.
4501N/A * @param debugFileProvider A debug file provider
4501N/A */
4501N/A public DebugImpl(String debugName, DebugFileProvider debugFileProvider) {
4501N/A this.debugName = debugName;
4501N/A
4501N/A if (SystemPropertiesManager.get(DebugConstants.CONFIG_DEBUG_LEVEL) != null) {
4501N/A setDebug(SystemPropertiesManager.get(DebugConstants.CONFIG_DEBUG_LEVEL));
4501N/A } else {
4501N/A setDebug(DebugLevel.ON);
4501N/A }
4501N/A
4501N/A this.debugFileProvider = debugFileProvider;
4501N/A stdoutDebugFile = debugFileProvider.getStdOutDebugFile();
4501N/A
4501N/A String mf = SystemPropertiesManager.get(DebugConstants.CONFIG_DEBUG_MERGEALL);
4517N/A mergeAllMode = "on".equals(mf);
4641N/A
4517N/A //NB : we don't initialize debugFile now, we will do it when we will write on it
4517N/A }
4501N/A
4501N/A /**
4501N/A * Returns debug name.
4501N/A *
4501N/A * @return debug name.
4501N/A */
4501N/A public String getName() {
4501N/A return this.debugName;
4501N/A }
4501N/A
4501N/A /**
4641N/A * Returns debug level.
4501N/A *
4641N/A * @return debug level.
4501N/A */
4501N/A public int getState() {
4501N/A return this.debugLevel.getLevel();
4501N/A }
4671N/A
4501N/A /**
4811N/A * Sets debug level.
4501N/A *
4798N/A * @param level Debug level.
4501N/A */
4501N/A public void setDebug(int level) {
4501N/A
4501N/A try {
4501N/A setDebug(DebugLevel.fromLevel(level));
4501N/A } catch (IllegalArgumentException e) {
4501N/A // ignore invalid level values
4501N/A StdDebugFile.printError(DebugImpl.class.getSimpleName(), e.getMessage(), e);
4501N/A }
4501N/A }
4501N/A
4501N/A /**
4501N/A * Sets debug level.
4501N/A *
4501N/A * @param strDebugLevel Debug level.
4641N/A */
4501N/A public void setDebug(String strDebugLevel) {
4501N/A
4501N/A try {
4501N/A setDebug(DebugLevel.fromName(strDebugLevel));
4641N/A } catch (IllegalArgumentException e) {
4501N/A // ignore invalid level values
4671N/A StdDebugFile.printError(DebugImpl.class.getSimpleName(), e.getMessage(), e);
4501N/A }
4501N/A }
4501N/A
4501N/A /**
4641N/A * Sets debug level.
4501N/A *
4501N/A * @param debugLevel Debug level.
4501N/A */
4501N/A public void setDebug(DebugLevel debugLevel) {
4501N/A
4501N/A this.debugLevel = debugLevel;
4501N/A }
4501N/A
4501N/A /**
4501N/A * Reset this instance - ths will trigger this instance to reinitialize
4501N/A * itself.
4501N/A *
4501N/A * @param mf merge flag : true: merge debugs into a single file.`
4501N/A */
4501N/A public void resetDebug(String mf) {
4641N/A mergeAllMode = "on".equals(mf);
4641N/A setDebug(SystemPropertiesManager.get(DebugConstants.CONFIG_DEBUG_LEVEL));
4501N/A
4798N/A // Note : we don't need to close the writer we will keep it
4798N/A // in the Writer cache in case merge mode changes again.
4798N/A debugFile = null;
4501N/A }
4641N/A
4641N/A /**
4641N/A * Returns <code>true</code> if debug is enabled.
4641N/A *
4641N/A * @return <code>true</code> if debug is enabled.
4641N/A */
4501N/A public boolean messageEnabled() {
4501N/A return this.debugLevel.compareLevel(DebugLevel.MESSAGE) >= 0;
4501N/A }
4501N/A
4501N/A /**
4501N/A * Returns <code>true</code> if debug warning is enabled.
4501N/A *
4501N/A * @return <code>true</code> if debug warning is enabled.
4501N/A */
4501N/A public boolean warningEnabled() {
4501N/A return this.debugLevel.compareLevel(DebugLevel.WARNING) >= 0;
4501N/A }
4501N/A
4501N/A /**
4501N/A * Returns <code>true</code> if debug error is enabled.
4501N/A *
4501N/A * @return <code>true</code> if debug error is enabled.
4501N/A */
4501N/A public boolean errorEnabled() {
4501N/A return this.debugLevel.compareLevel(DebugLevel.ERROR) >= 0;
4501N/A }
4501N/A
4501N/A /**
4501N/A * Writes debug message.
4501N/A *
4501N/A * @param message Debug message.
4501N/A * @param th Throwable object along with the message.
4501N/A */
4501N/A public void message(String message, Throwable th) {
4501N/A if (messageEnabled()) {
4501N/A record(message, th);
4501N/A }
4501N/A }
4641N/A
4501N/A /**
4501N/A * Writes debug warning message.
4501N/A *
4501N/A * @param message Debug message.
4501N/A * @param th Throwable object along with the warning message.
4501N/A */
4501N/A public void warning(String message, Throwable th) {
4501N/A if (warningEnabled()) {
4811N/A record("WARNING: " + message, th);
4811N/A }
4811N/A }
4811N/A
4811N/A /**
4811N/A * Writes debug error message.
4811N/A *
4811N/A * @param message Debug message.
4811N/A * @param th Throwable object along with the error message.
4811N/A */
4811N/A public void error(String message, Throwable th) {
4811N/A if (errorEnabled()) {
4811N/A record("ERROR: " + message, th);
4811N/A }
4811N/A }
4811N/A
4837N/A private void record(String msg, Throwable th) {
4811N/A
4811N/A StringBuilder prefix = new StringBuilder();
4811N/A prefix.append(debugName).append(":").append(this.dateFormat.format(new Date())).append(": ").append(Thread
4811N/A .currentThread().toString());
4811N/A
4798N/A writeIt(prefix.toString(), msg, th);
4659N/A }
4798N/A
4811N/A /**
4659N/A * Write message on Debug file. If it failed, it try to print it on the Sdtout Debug file.
4641N/A * If both failed, it prints in System.out
4802N/A *
4659N/A * @param prefix Message prefix
4501N/A * @param msg Message to be recorded.
4802N/A * @param th the optional <code>java.lang.Throwable</code> which if
4659N/A * present will be used to record the stack trace.
4641N/A */
4802N/A private void writeIt(String prefix, String msg, Throwable th) {
4802N/A
4659N/A //we create the debug file only if we need to write on it
4659N/A if (debugFile == null) {
4659N/A String debugFileName = resolveDebugFileName();
4659N/A debugFile = debugFileProvider.getInstance(debugFileName);
4659N/A }
4659N/A
4659N/A try {
4501N/A if (this.debugLevel == DebugLevel.ON) {
4659N/A stdoutDebugFile.writeIt(prefix, msg, th);
4659N/A } else {
4837N/A
4697N/A try {
4802N/A this.debugFile.writeIt(prefix, msg, th);
4697N/A } catch (IOException e) {
4697N/A /*
4802N/A * In order to have less logs for this kind of issue. It's waiting an interval of time before
4659N/A * printing this error again.
4641N/A */
4659N/A if (lastDirectoryIssue + DIR_ISSUE_ERROR_INTERVAL_IN_MS < System.currentTimeMillis()) {
4659N/A lastDirectoryIssue = System.currentTimeMillis();
4641N/A stdoutDebugFile.writeIt(prefix, "Debug file can't be written : " + e.getMessage(), null);
4802N/A }
4659N/A stdoutDebugFile.writeIt(prefix, msg, th);
4659N/A
4659N/A }
4659N/A }
4659N/A } catch (IOException ioex) {
4802N/A StdDebugFile.printError(DebugImpl.class.getSimpleName(), ioex.getMessage(), ioex);
4501N/A }
4501N/A }
4501N/A
4501N/A /**
4501N/A * Return the Debug file name that should be used for this debug name
4802N/A *
4802N/A * @return the debug file name to use
4659N/A */
4641N/A private String resolveDebugFileName() {
4802N/A
4659N/A if (mergeAllMode) {
4659N/A return DebugConstants.CONFIG_DEBUG_MERGEALL_FILE;
4641N/A } else {
4641N/A // Find the bucket this debug belongs to
4798N/A String nm = (String) debugFileNames.getProperty(debugName);
4659N/A if (nm != null) {
4798N/A return nm;
4659N/A } else {
4641N/A // Default to debugName if no mapping is found
4659N/A return debugName;
4659N/A }
4641N/A }
4802N/A }
4659N/A
4659N/A /**
4659N/A * initialize the properties
4659N/A * It will reset the current properties for every Debug instance
4659N/A */
4802N/A public static synchronized void initProperties() {
4659N/A
4641N/A debugFileNames = new Properties();
4659N/A // Load properties : debugmap.properties
4659N/A InputStream is = null;
4641N/A try {
4659N/A is = DebugImpl.class.getResourceAsStream(DebugConstants.CONFIG_DEBUG_FILEMAP);
4659N/A if (is == null && SystemPropertiesManager.get(DebugConstants.CONFIG_DEBUG_FILEMAP_VARIABLE) != null) {
4641N/A is = DebugImpl.class.getResourceAsStream(SystemPropertiesManager.get(DebugConstants
4659N/A .CONFIG_DEBUG_FILEMAP_VARIABLE));
4802N/A }
4659N/A debugFileNames.load(is);
4659N/A } catch (Exception ex) {
4659N/A StdDebugFile.printError(DebugImpl.class.getSimpleName(), "Can't read debug files map. '. Please check the" +
4659N/A " configuration file '" + DebugConstants.CONFIG_DEBUG_FILEMAP + "'.", ex);
4697N/A } finally {
4802N/A IOUtils.closeIfNotNull(is);
4659N/A }
4641N/A }
4659N/A
4659N/A}
4641N/A