[ 1897512 ] CLogger not thread safe

- replace use of static and instance variable with context. Context should then be implemented as inheritable thread local in server environment ( done for ZK client, need to check the EJB & Servlet implementation ).
This commit is contained in:
Heng Sin Low 2008-07-15 09:42:35 +00:00
parent d8a3f9b6d3
commit c9fea0e495
2 changed files with 87 additions and 48 deletions

View File

@ -30,6 +30,12 @@ import org.compiere.model.*;
*/ */
public class CLogErrorBuffer extends Handler public class CLogErrorBuffer extends Handler
{ {
private static final String ISSUE_ERROR_KEY = "org.compiere.util.CLogErrorBuffer.issueError";
private static final String HISTORY_KEY = "org.compiere.util.CLogErrorBuffer.history";
private static final String ERRORS_KEY = "org.compiere.util.CLogErrorBuffer.errors";
private static final String LOGS_KEY = "org.compiere.util.CLogErrorBuffer.logs";
/** /**
* Get Client Log Handler * Get Client Log Handler
* @param create create if not exists * @param create create if not exists
@ -62,17 +68,9 @@ public class CLogErrorBuffer extends Handler
/** Error Buffer Size */ /** Error Buffer Size */
private static final int ERROR_SIZE = 20; private static final int ERROR_SIZE = 20;
/** The Error Buffer */
private LinkedList<LogRecord> m_errors = new LinkedList<LogRecord>();
/** The Error Buffer History */
private LinkedList<LogRecord[]> m_history = new LinkedList<LogRecord[]>();
/** Log Size */ /** Log Size */
private static final int LOG_SIZE = 100; private static final int LOG_SIZE = 100;
/** The Log Buffer */
private LinkedList<LogRecord> m_logs = new LinkedList<LogRecord>();
/** Issue Error */
private volatile boolean m_issueError = true;
/** /**
* Initialize * Initialize
@ -95,7 +93,13 @@ public class CLogErrorBuffer extends Handler
*/ */
public boolean isIssueError() public boolean isIssueError()
{ {
return m_issueError; Boolean b = (Boolean) Env.getCtx().get(ISSUE_ERROR_KEY);
if (b == null)
{
b = Boolean.TRUE;
setIssueError(b);
}
return b;
} // isIssueError } // isIssueError
/** /**
@ -104,7 +108,7 @@ public class CLogErrorBuffer extends Handler
*/ */
public void setIssueError(boolean issueError) public void setIssueError(boolean issueError)
{ {
m_issueError = issueError; Env.getCtx().put(ISSUE_ERROR_KEY, issueError);
} // setIssueError } // setIssueError
/** /**
@ -134,6 +138,9 @@ public class CLogErrorBuffer extends Handler
*/ */
public void publish (LogRecord record) public void publish (LogRecord record)
{ {
checkContext();
LinkedList<LogRecord> m_logs = (LinkedList<LogRecord>) Env.getCtx().get(LOGS_KEY);
if (!isLoggable (record) || m_logs == null) if (!isLoggable (record) || m_logs == null)
return; return;
@ -148,6 +155,8 @@ public class CLogErrorBuffer extends Handler
// We have an error // We have an error
if (record.getLevel() == Level.SEVERE) if (record.getLevel() == Level.SEVERE)
{ {
LinkedList<LogRecord> m_errors = (LinkedList<LogRecord>) Env.getCtx().get(ERRORS_KEY);
LinkedList<LogRecord[]> m_history = (LinkedList<LogRecord[]>) Env.getCtx().get(HISTORY_KEY);
if (m_errors.size() >= ERROR_SIZE) if (m_errors.size() >= ERROR_SIZE)
{ {
m_errors.removeFirst(); m_errors.removeFirst();
@ -183,7 +192,7 @@ public class CLogErrorBuffer extends Handler
historyArray[no++] = (LogRecord)history.get(i); historyArray[no++] = (LogRecord)history.get(i);
m_history.add(historyArray); m_history.add(historyArray);
// Issue Reporting // Issue Reporting
if (m_issueError) if (isIssueError())
{ {
String loggerName = record.getLoggerName(); // class name String loggerName = record.getLoggerName(); // class name
String className = record.getSourceClassName(); // physical class String className = record.getSourceClassName(); // physical class
@ -196,16 +205,16 @@ public class CLogErrorBuffer extends Handler
&& loggerName.indexOf("CConnection") == -1 && loggerName.indexOf("CConnection") == -1
) )
{ {
m_issueError = false; setIssueError(false);
try try
{ {
MIssue.create(record); MIssue.create(record);
m_issueError = true; setIssueError(true);
} catch (Throwable e) } catch (Throwable e)
{ {
//failed to save exception to db, print to console //failed to save exception to db, print to console
System.err.println(getFormatter().format(record)); System.err.println(getFormatter().format(record));
m_issueError = false; setIssueError(false);
} }
} }
else else
@ -239,15 +248,9 @@ public class CLogErrorBuffer extends Handler
*/ */
public void close () throws SecurityException public void close () throws SecurityException
{ {
if (m_logs != null) Env.getCtx().remove(LOGS_KEY);
m_logs.clear(); Env.getCtx().remove(ERRORS_KEY);
m_logs = null; Env.getCtx().remove(HISTORY_KEY);
if (m_errors != null)
m_errors.clear();
m_errors = null;
if (m_history != null)
m_history.clear();
m_history = null;
} // close } // close
@ -308,6 +311,10 @@ public class CLogErrorBuffer extends Handler
*/ */
public LogRecord[] getRecords (boolean errorsOnly) public LogRecord[] getRecords (boolean errorsOnly)
{ {
checkContext();
LinkedList<LogRecord> m_logs = (LinkedList<LogRecord>) Env.getCtx().get(LOGS_KEY);
LinkedList<LogRecord> m_errors = (LinkedList<LogRecord>) Env.getCtx().get(ERRORS_KEY);
LogRecord[] retValue = null; LogRecord[] retValue = null;
if (errorsOnly) if (errorsOnly)
{ {
@ -334,6 +341,11 @@ public class CLogErrorBuffer extends Handler
*/ */
public void resetBuffer (boolean errorsOnly) public void resetBuffer (boolean errorsOnly)
{ {
checkContext();
LinkedList<LogRecord> m_logs = (LinkedList<LogRecord>) Env.getCtx().get(LOGS_KEY);
LinkedList<LogRecord> m_errors = (LinkedList<LogRecord>) Env.getCtx().get(ERRORS_KEY);
LinkedList<LogRecord[]> m_history = (LinkedList<LogRecord[]>) Env.getCtx().get(HISTORY_KEY);
synchronized (m_errors) synchronized (m_errors)
{ {
m_errors.clear(); m_errors.clear();
@ -356,10 +368,13 @@ public class CLogErrorBuffer extends Handler
*/ */
public String getErrorInfo (Properties ctx, boolean errorsOnly) public String getErrorInfo (Properties ctx, boolean errorsOnly)
{ {
checkContext();
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
// //
if (errorsOnly) if (errorsOnly)
{ {
LinkedList<LogRecord[]> m_history = (LinkedList<LogRecord[]>) Env.getCtx().get(HISTORY_KEY);
for (int i = 0; i < m_history.size(); i++) for (int i = 0; i < m_history.size(); i++)
{ {
sb.append("-------------------------------\n"); sb.append("-------------------------------\n");
@ -373,6 +388,7 @@ public class CLogErrorBuffer extends Handler
} }
else else
{ {
LinkedList<LogRecord> m_logs = (LinkedList<LogRecord>) Env.getCtx().get(LOGS_KEY);
for (int i = 0; i < m_logs.size(); i++) for (int i = 0; i < m_logs.size(); i++)
{ {
LogRecord record = (LogRecord)m_logs.get(i); LogRecord record = (LogRecord)m_logs.get(i);
@ -386,12 +402,38 @@ public class CLogErrorBuffer extends Handler
return sb.toString(); return sb.toString();
} // getErrorInfo } // getErrorInfo
private void checkContext()
{
if (!Env.getCtx().containsKey(LOGS_KEY))
{
LinkedList<LogRecord> m_logs = new LinkedList<LogRecord>();
Env.getCtx().put(LOGS_KEY, m_logs);
}
if (!Env.getCtx().containsKey(ERRORS_KEY))
{
LinkedList<LogRecord> m_errors = new LinkedList<LogRecord>();
Env.getCtx().put(ERRORS_KEY, m_errors);
}
if (!Env.getCtx().containsKey(HISTORY_KEY))
{
LinkedList<LogRecord[]> m_history = new LinkedList<LogRecord[]>();
Env.getCtx().put(HISTORY_KEY, m_history);
}
}
/** /**
* String Representation * String Representation
* @return info * @return info
*/ */
public String toString () public String toString ()
{ {
checkContext();
LinkedList<LogRecord> m_logs = (LinkedList<LogRecord>) Env.getCtx().get(LOGS_KEY);
LinkedList<LogRecord> m_errors = (LinkedList<LogRecord>) Env.getCtx().get(ERRORS_KEY);
LinkedList<LogRecord[]> m_history = (LinkedList<LogRecord[]>) Env.getCtx().get(HISTORY_KEY);
StringBuffer sb = new StringBuffer ("CLogErrorBuffer["); StringBuffer sb = new StringBuffer ("CLogErrorBuffer[");
sb.append("Errors=").append(m_errors.size()) sb.append("Errors=").append(m_errors.size())
.append(",History=").append(m_history.size()) .append(",History=").append(m_history.size())

View File

@ -28,6 +28,12 @@ import java.util.logging.*;
*/ */
public class CLogger extends Logger implements Serializable public class CLogger extends Logger implements Serializable
{ {
private static final String LAST_INFO = "org.compiere.util.CLogger.lastInfo";
private static final String LAST_WARNING = "org.compiere.util.CLogger.lastWarning";
private static final String LAST_ERROR = "org.compiere.util.CLogger.lastError";
private static final String LAST_EXCEPTION = "org.compiere.util.CLogger.lastException";
/** /**
* Get Logger * Get Logger
* @param className class name * @param className class name
@ -91,15 +97,6 @@ public class CLogger extends Logger implements Serializable
/*************************************************************************/ /*************************************************************************/
/** Last Error Message */
private static ValueNamePair s_lastError = null;
/** Last Exception */
private static Exception s_lastException = null;
/** Last Warning Message */
private static ValueNamePair s_lastWarning = null;
/** Last Info Message */
private static ValueNamePair s_lastInfo = null;
/** /**
* Set and issue Error and save as ValueNamePair * Set and issue Error and save as ValueNamePair
* @param AD_Message message key * @param AD_Message message key
@ -119,7 +116,7 @@ public class CLogger extends Logger implements Serializable
*/ */
public boolean saveError (String AD_Message, Exception ex) public boolean saveError (String AD_Message, Exception ex)
{ {
s_lastException = ex; Env.getCtx().put(LAST_EXCEPTION, ex);
return saveError (AD_Message, ex.getLocalizedMessage(), true); return saveError (AD_Message, ex.getLocalizedMessage(), true);
} // saveError } // saveError
@ -132,7 +129,8 @@ public class CLogger extends Logger implements Serializable
*/ */
public boolean saveError (String AD_Message, String message, boolean issueError) public boolean saveError (String AD_Message, String message, boolean issueError)
{ {
s_lastError = new ValueNamePair (AD_Message, message); ValueNamePair lastError = new ValueNamePair (AD_Message, message);
Env.getCtx().put(LAST_ERROR, lastError);
// print it // print it
if (issueError) if (issueError)
severe(AD_Message + " - " + message); severe(AD_Message + " - " + message);
@ -145,8 +143,7 @@ public class CLogger extends Logger implements Serializable
*/ */
public static ValueNamePair retrieveError() public static ValueNamePair retrieveError()
{ {
ValueNamePair vp = s_lastError; ValueNamePair vp = (ValueNamePair) Env.getCtx().remove(LAST_ERROR);
s_lastError = null;
return vp; return vp;
} // retrieveError } // retrieveError
@ -170,8 +167,7 @@ public class CLogger extends Logger implements Serializable
*/ */
public static Exception retrieveException() public static Exception retrieveException()
{ {
Exception ex = s_lastException; Exception ex = (Exception) Env.getCtx().remove(LAST_EXCEPTION);
s_lastException = null;
return ex; return ex;
} // retrieveError } // retrieveError
@ -183,7 +179,8 @@ public class CLogger extends Logger implements Serializable
*/ */
public boolean saveWarning (String AD_Message, String message) public boolean saveWarning (String AD_Message, String message)
{ {
s_lastWarning = new ValueNamePair (AD_Message, message); ValueNamePair lastWarning = new ValueNamePair(AD_Message, message);
Env.getCtx().put(LAST_WARNING, lastWarning);
// print it // print it
if (true) // issueError if (true) // issueError
warning(AD_Message + " - " + message); warning(AD_Message + " - " + message);
@ -196,8 +193,7 @@ public class CLogger extends Logger implements Serializable
*/ */
public static ValueNamePair retrieveWarning() public static ValueNamePair retrieveWarning()
{ {
ValueNamePair vp = s_lastWarning; ValueNamePair vp = (ValueNamePair) Env.getCtx().remove(LAST_WARNING);
s_lastWarning = null;
return vp; return vp;
} // retrieveWarning } // retrieveWarning
@ -209,7 +205,9 @@ public class CLogger extends Logger implements Serializable
*/ */
public boolean saveInfo (String AD_Message, String message) public boolean saveInfo (String AD_Message, String message)
{ {
s_lastInfo = new ValueNamePair (AD_Message, message); // s_lastInfo = new ValueNamePair (AD_Message, message);
ValueNamePair lastInfo = new ValueNamePair (AD_Message, message);
Env.getCtx().put(LAST_INFO, lastInfo);
return true; return true;
} // saveInfo } // saveInfo
@ -219,8 +217,7 @@ public class CLogger extends Logger implements Serializable
*/ */
public static ValueNamePair retrieveInfo() public static ValueNamePair retrieveInfo()
{ {
ValueNamePair vp = s_lastInfo; ValueNamePair vp = (ValueNamePair) Env.getCtx().remove(LAST_INFO);
s_lastInfo = null;
return vp; return vp;
} // retrieveInfo } // retrieveInfo
@ -229,10 +226,10 @@ public class CLogger extends Logger implements Serializable
*/ */
public static void resetLast() public static void resetLast()
{ {
s_lastError = null; Env.getCtx().remove(LAST_ERROR);
s_lastException = null; Env.getCtx().remove(LAST_EXCEPTION);
s_lastWarning = null; Env.getCtx().remove(LAST_WARNING);
s_lastInfo = null; Env.getCtx().remove(LAST_INFO);
} // resetLast } // resetLast
/** /**