/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2006-2009 Sun Microsystems, Inc. */ package org.opends.server.loggers.debug; import org.opends.server.api.DebugLogPublisher; import org.opends.server.types.DebugLogCategory; import org.opends.server.types.DebugLogLevel; import org.opends.server.loggers.LogLevel; import org.opends.server.loggers.LogCategory; import java.util.Map; import java.nio.ByteBuffer; import com.sleepycat.je.OperationStatus; import com.sleepycat.je.Transaction; import com.sleepycat.je.DatabaseEntry; import com.sleepycat.je.Database; /** * Class for source-code tracing at the method level. * * One DebugTracer instance exists for each Java class using tracing. * Tracer must be registered with the DebugLogger. * * Logging is always done at a level basis, with debug log messages * exceeding the trace threshold being traced, others being discarded. */ public class DebugTracer { // The class this aspect traces. private String className; /** * A class that represents a settings cache entry. */ private class PublisherSettings { DebugLogPublisher debugPublisher; TraceSettings classSettings; Map methodSettings; } PublisherSettings[] publisherSettings; /** * Construct a new DebugTracer object with cached settings obtained from * the provided array of publishers. * * @param publishers The array of publishers to obtain the settings from. */ @SuppressWarnings("unchecked") DebugTracer(DebugLogPublisher[] publishers) { // Trim off the debug logging and non OpenDS frames. StackTraceElement callerFrame = getCallerFrame(Thread.currentThread().getStackTrace()); // TODO: What if this is null or 0 length? if(callerFrame != null) { // The caller should be the first item on the stack. className = callerFrame.getClassName(); } publisherSettings = new PublisherSettings[publishers.length]; // Get the settings from all publishers. for(int i = 0; i < publishers.length; i++) { DebugLogPublisher publisher = publishers[i]; PublisherSettings settings = new PublisherSettings(); settings.debugPublisher = publisher; settings.classSettings = publisher.getClassSettings(className); // For some reason, the compiler doesn't see that // debugLogPublihser.getMethodSettings returns a parameterized Map. // This problem goes away if a parameterized verson of DebugLogPublisher // is used. However, we can't not use reflection to instantiate a generic // DebugLogPublisher type. The only thing // we can do is to just supress the compiler warnings. settings.methodSettings = publisher.getMethodSettings(className); publisherSettings[i] = settings; } } /** * Log an constructor execution event. * * @param level The level of the message being logged. * @param args The arguments passed to the constructor. */ public void debugConstructor(LogLevel level, Object... args) { if(DebugLogger.debugEnabled()) { StackTraceElement[] stackTrace = null; StackTraceElement[] filteredStackTrace = null; StackTraceElement callerFrame = null; for (PublisherSettings settings : publisherSettings) { TraceSettings activeSettings = settings.classSettings; Map methodSettings = settings.methodSettings; if (shouldLog(level, DebugLogCategory.CONSTRUCTOR, activeSettings) || methodSettings != null) { if(stackTrace == null) { stackTrace = Thread.currentThread().getStackTrace(); } if (callerFrame == null) { callerFrame = getCallerFrame(stackTrace); } String signature = callerFrame.getMethodName(); // Specific method settings still could exist. Try getting // the settings for this method. if(methodSettings != null) { TraceSettings mSettings = methodSettings.get(signature); if (mSettings == null) { // Try looking for an undecorated method name int idx = signature.indexOf('('); if (idx != -1) { mSettings = methodSettings.get(signature.substring(0, idx)); } } // If this method does have a specific setting and it is not // suppose to be logged, continue. if (mSettings != null) { if(!shouldLog(level, DebugLogCategory.CONSTRUCTOR, mSettings)) { continue; } else { activeSettings = mSettings; } } } String sl = callerFrame.getFileName() + ":" + callerFrame.getLineNumber(); if (activeSettings.noArgs) { args = null; } if (filteredStackTrace == null && activeSettings.stackDepth > 0) { filteredStackTrace = DebugStackTraceFormatter.SMART_FRAME_FILTER. getFilteredStackTrace(stackTrace); } settings.debugPublisher.traceConstructor(level, activeSettings, signature, sl, args, filteredStackTrace); } } } } /** * Log an non static method entry event. * * @param level The level of the message being logged. * @param obj The object type instance the method is a member of. * @param args The arguments passed to the method. */ public void debugMethodEntry(LogLevel level, Object obj, Object... args) { if(DebugLogger.debugEnabled()) { StackTraceElement[] stackTrace = null; StackTraceElement[] filteredStackTrace = null; StackTraceElement callerFrame = null; for (PublisherSettings settings : publisherSettings) { TraceSettings activeSettings = settings.classSettings; Map methodSettings = settings.methodSettings; if (shouldLog(level, DebugLogCategory.ENTER, activeSettings) || methodSettings != null) { if(stackTrace == null) { stackTrace = Thread.currentThread().getStackTrace(); } if (callerFrame == null) { callerFrame = getCallerFrame(stackTrace); } String signature = callerFrame.getMethodName(); // Specific method settings still could exist. Try getting // the settings for this method. if(methodSettings != null) { TraceSettings mSettings = methodSettings.get(signature); if (mSettings == null) { // Try looking for an undecorated method name int idx = signature.indexOf('('); if (idx != -1) { mSettings = methodSettings.get(signature.substring(0, idx)); } } // If this method does have a specific setting and it is not // suppose to be logged, continue. if (mSettings != null) { if(!shouldLog(level, DebugLogCategory.ENTER, mSettings)) { continue; } else { activeSettings = mSettings; } } } String sl = callerFrame.getFileName() + ":" + callerFrame.getLineNumber(); if (activeSettings.noArgs) { args = null; } if (filteredStackTrace == null && activeSettings.stackDepth > 0) { filteredStackTrace = DebugStackTraceFormatter.SMART_FRAME_FILTER. getFilteredStackTrace(stackTrace); } settings.debugPublisher.traceMethodEntry(level, activeSettings, signature, sl, obj, args, filteredStackTrace); } } } } /** * Log an static method entry event. * * @param level The level of the message being logged. * @param args The arguments passed to the method. */ public void debugStaticMethodEntry(LogLevel level, Object... args) { if(DebugLogger.debugEnabled()) { StackTraceElement[] stackTrace = null; StackTraceElement[] filteredStackTrace = null; StackTraceElement callerFrame = null; for (PublisherSettings settings : publisherSettings) { TraceSettings activeSettings = settings.classSettings; Map methodSettings = settings.methodSettings; if (shouldLog(level, DebugLogCategory.ENTER, activeSettings) || methodSettings != null) { if(stackTrace == null) { stackTrace = Thread.currentThread().getStackTrace(); } if (callerFrame == null) { callerFrame = getCallerFrame(stackTrace); } String signature = callerFrame.getMethodName(); // Specific method settings still could exist. Try getting // the settings for this method. if(methodSettings != null) { TraceSettings mSettings = methodSettings.get(signature); if (mSettings == null) { // Try looking for an undecorated method name int idx = signature.indexOf('('); if (idx != -1) { mSettings = methodSettings.get(signature.substring(0, idx)); } } // If this method does have a specific setting and it is not // suppose to be logged, continue. if (mSettings != null) { if(!shouldLog(level, DebugLogCategory.ENTER, mSettings)) { continue; } else { activeSettings = mSettings; } } } String sl = callerFrame.getFileName() + ":" + callerFrame.getLineNumber(); if (activeSettings.noArgs) { args = null; } if (filteredStackTrace == null && activeSettings.stackDepth > 0) { filteredStackTrace = DebugStackTraceFormatter.SMART_FRAME_FILTER. getFilteredStackTrace(stackTrace); } settings.debugPublisher.traceStaticMethodEntry(level, activeSettings, signature, sl, args, filteredStackTrace); } } } } /** * Log a return from a method call event. * * @param level The level of the message being logged. * @param ret The value being returned from the method. */ public void debugReturn(LogLevel level, Object ret) { if(DebugLogger.debugEnabled()) { StackTraceElement[] stackTrace = null; StackTraceElement[] filteredStackTrace = null; StackTraceElement callerFrame = null; for (PublisherSettings settings : publisherSettings) { TraceSettings activeSettings = settings.classSettings; Map methodSettings = settings.methodSettings; if (shouldLog(level, DebugLogCategory.ENTER, activeSettings) || methodSettings != null) { if(stackTrace == null) { stackTrace = Thread.currentThread().getStackTrace(); } if (callerFrame == null) { callerFrame = getCallerFrame(stackTrace); } String signature = callerFrame.getMethodName(); // Specific method settings still could exist. Try getting // the settings for this method. if(methodSettings != null) { TraceSettings mSettings = methodSettings.get(signature); if (mSettings == null) { // Try looking for an undecorated method name int idx = signature.indexOf('('); if (idx != -1) { mSettings = methodSettings.get(signature.substring(0, idx)); } } // If this method does have a specific setting and it is not // suppose to be logged, continue. if (mSettings != null) { if(!shouldLog(level, DebugLogCategory.ENTER, mSettings)) { continue; } else { activeSettings = mSettings; } } } String sl = callerFrame.getFileName() + ":" + callerFrame.getLineNumber(); if (activeSettings.noRetVal) { ret = null; } if (filteredStackTrace == null && activeSettings.stackDepth > 0) { filteredStackTrace = DebugStackTraceFormatter.SMART_FRAME_FILTER. getFilteredStackTrace(stackTrace); } settings.debugPublisher.traceReturn(level, activeSettings, signature, sl, ret, filteredStackTrace); } } } } /** * Log an exception thrown from a method. * * @param level The level of the message being logged. * @param ex The exception being thrown. */ public void debugThrown(LogLevel level, Throwable ex) { if(DebugLogger.debugEnabled()) { StackTraceElement[] stackTrace = null; StackTraceElement[] filteredStackTrace = null; StackTraceElement callerFrame = null; for (PublisherSettings settings : publisherSettings) { TraceSettings activeSettings = settings.classSettings; Map methodSettings = settings.methodSettings; if (shouldLog(level, DebugLogCategory.THROWN, activeSettings) || methodSettings != null) { if(stackTrace == null) { stackTrace = Thread.currentThread().getStackTrace(); } if (callerFrame == null) { callerFrame = getCallerFrame(stackTrace); } String signature = callerFrame.getMethodName(); // Specific method settings still could exist. Try getting // the settings for this method. if(methodSettings != null) { TraceSettings mSettings = methodSettings.get(signature); if (mSettings == null) { // Try looking for an undecorated method name int idx = signature.indexOf('('); if (idx != -1) { mSettings = methodSettings.get(signature.substring(0, idx)); } } // If this method does have a specific setting and it is not // suppose to be logged, continue. if (mSettings != null) { if(!shouldLog(level, DebugLogCategory.THROWN, mSettings)) { continue; } else { activeSettings = mSettings; } } } String sl = callerFrame.getFileName() + ":" + callerFrame.getLineNumber(); if (filteredStackTrace == null && activeSettings.stackDepth > 0) { filteredStackTrace = DebugStackTraceFormatter.SMART_FRAME_FILTER. getFilteredStackTrace(ex.getStackTrace()); } settings.debugPublisher.traceThrown(level, activeSettings, signature, sl, ex, filteredStackTrace); } } } } /** * Log an arbitrary event at the verbose level. * Same as debugMessage(DebugLogLevel.ERROR, msg) * * @param msg message to format and log. */ public void debugVerbose(String msg) { debugMessage(DebugLogLevel.VERBOSE, msg, new Object[]{}); } /** * Log an arbitrary event at the verbose level. * Same as debugMessage(DebugLogLevel.ERROR, msg, msgArgs...) * * @param msg message to format and log. * @param msgArgs arguments to place into the format string. */ public void debugVerbose(String msg, Object... msgArgs) { debugMessage(DebugLogLevel.VERBOSE, msg, msgArgs); } /** * Log an arbitrary event at the info level. * Same as debugMessage(DebugLogLevel.ERROR, msg) * * @param msg message to format and log. */ public void debugInfo(String msg) { debugMessage(DebugLogLevel.INFO, msg, new Object[]{}); } /** * Log an arbitrary event at the info level. * Same as debugMessage(DebugLogLevel.ERROR, msg, msgArgs...) * * @param msg message to format and log. * @param msgArgs arguments to place into the format string. */ public void debugInfo(String msg, Object... msgArgs) { debugMessage(DebugLogLevel.INFO, msg, msgArgs); } /** * Log an arbitrary event at the warning level. * Same as debugMessage(DebugLogLevel.ERROR, msg) * * @param msg message to format and log. */ public void debugWarning(String msg) { debugMessage(DebugLogLevel.WARNING, msg, new Object[]{}); } /** * Log an arbitrary event at the warning level. * Same as debugMessage(DebugLogLevel.ERROR, msg, msgArgs...) * * @param msg message to format and log. * @param msgArgs arguments to place into the format string. */ public void debugWarning(String msg, Object... msgArgs) { debugMessage(DebugLogLevel.WARNING, msg, msgArgs); } /** * Log an arbitrary event at the error level. * Same as debugMessage(DebugLogLevel.ERROR, msg) * * @param msg message to format and log. */ public void debugError(String msg) { debugMessage(DebugLogLevel.ERROR, msg, new Object[]{}); } /** * Log an arbitrary event at the error level. * Same as debugMessage(DebugLogLevel.ERROR, msg, msgArgs...) * * @param msg message to format and log. * @param msgArgs arguments to place into the format string. */ public void debugError(String msg, Object... msgArgs) { debugMessage(DebugLogLevel.ERROR, msg, msgArgs); } /** * Log an arbitrary event. * * @param level the level of the log message. * @param msg message to format and log. */ public void debugMessage(LogLevel level, String msg) { debugMessage(level, msg, new Object[]{}); } /** * Log an arbitrary event. * * @param level the level of the log message. * @param msg message to format and log. * @param msgArgs arguments to place into the format string. */ public void debugMessage(LogLevel level, String msg, Object... msgArgs) { if(DebugLogger.debugEnabled()) { StackTraceElement[] stackTrace = null; StackTraceElement[] filteredStackTrace = null; StackTraceElement callerFrame = null; for (PublisherSettings settings : publisherSettings) { TraceSettings activeSettings = settings.classSettings; Map methodSettings = settings.methodSettings; if (shouldLog(level, DebugLogCategory.MESSAGE, activeSettings) || methodSettings != null) { if(stackTrace == null) { stackTrace = Thread.currentThread().getStackTrace(); } if (callerFrame == null) { callerFrame = getCallerFrame(stackTrace); } String signature = callerFrame.getMethodName(); // Specific method settings still could exist. Try getting // the settings for this method. if(methodSettings != null) { TraceSettings mSettings = methodSettings.get(signature); if (mSettings == null) { // Try looking for an undecorated method name int idx = signature.indexOf('('); if (idx != -1) { mSettings = methodSettings.get(signature.substring(0, idx)); } } // If this method does have a specific setting and it is not // suppose to be logged, continue. if (mSettings != null) { if(!shouldLog(level, DebugLogCategory.MESSAGE, mSettings)) { continue; } else { activeSettings = mSettings; } } } String sl = callerFrame.getFileName() + ":" + callerFrame.getLineNumber(); if(msgArgs != null && msgArgs.length > 0) { msg = String.format(msg, msgArgs); } if (filteredStackTrace == null && activeSettings.stackDepth > 0) { filteredStackTrace = DebugStackTraceFormatter.SMART_FRAME_FILTER. getFilteredStackTrace(stackTrace); } settings.debugPublisher.traceMessage(level, activeSettings, signature, sl, msg, filteredStackTrace); } } } } /** * Log an cought exception. * * @param level the level of the log message. * @param ex the exception caught. */ public void debugCaught(LogLevel level, Throwable ex) { if(DebugLogger.debugEnabled()) { StackTraceElement[] stackTrace = null; StackTraceElement[] filteredStackTrace = null; StackTraceElement callerFrame = null; for (PublisherSettings settings : publisherSettings) { TraceSettings activeSettings = settings.classSettings; Map methodSettings = settings.methodSettings; if (shouldLog(level, DebugLogCategory.CAUGHT, activeSettings) || methodSettings != null) { if(stackTrace == null) { stackTrace = Thread.currentThread().getStackTrace(); } if (callerFrame == null) { callerFrame = getCallerFrame(stackTrace); } String signature = callerFrame.getMethodName(); // Specific method settings still could exist. Try getting // the settings for this method. if(methodSettings != null) { TraceSettings mSettings = methodSettings.get(signature); if (mSettings == null) { // Try looking for an undecorated method name int idx = signature.indexOf('('); if (idx != -1) { mSettings = methodSettings.get(signature.substring(0, idx)); } } // If this method does have a specific setting and it is not // suppose to be logged, continue. if (mSettings != null) { if(!shouldLog(level, DebugLogCategory.CAUGHT, mSettings)) { continue; } else { activeSettings = mSettings; } } } String sl = callerFrame.getFileName() + ":" + callerFrame.getLineNumber(); if (filteredStackTrace == null && activeSettings.stackDepth > 0) { filteredStackTrace = DebugStackTraceFormatter.SMART_FRAME_FILTER. getFilteredStackTrace(ex.getStackTrace()); } settings.debugPublisher.traceCaught(level, activeSettings, signature, sl, ex, filteredStackTrace); } } } } /** * Log a JE database access event. * * @param level the level of the log message. * @param status status of the JE operation. * @param database the database handle. * @param txn transaction handle (may be null). * @param key the key to dump. * @param data the data to dump. */ public void debugJEAccess(LogLevel level, OperationStatus status, Database database, Transaction txn, DatabaseEntry key, DatabaseEntry data) { if(DebugLogger.debugEnabled()) { StackTraceElement[] stackTrace = null; StackTraceElement[] filteredStackTrace = null; StackTraceElement callerFrame = null; for (PublisherSettings settings : publisherSettings) { TraceSettings activeSettings = settings.classSettings; Map methodSettings = settings.methodSettings; if (shouldLog(level, DebugLogCategory.DATABASE_ACCESS, activeSettings) || methodSettings != null) { if(stackTrace == null) { stackTrace = Thread.currentThread().getStackTrace(); } if (callerFrame == null) { callerFrame = getCallerFrame(stackTrace); } String signature = callerFrame.getMethodName(); // Specific method settings still could exist. Try getting // the settings for this method. if(methodSettings != null) { TraceSettings mSettings = methodSettings.get(signature); if (mSettings == null) { // Try looking for an undecorated method name int idx = signature.indexOf('('); if (idx != -1) { mSettings = methodSettings.get(signature.substring(0, idx)); } } // If this method does have a specific setting and it is not // suppose to be logged, continue. if (mSettings != null) { if(!shouldLog(level, DebugLogCategory.DATABASE_ACCESS, mSettings)) { continue; } else { activeSettings = mSettings; } } } String sl = callerFrame.getFileName() + ":" + callerFrame.getLineNumber(); if (filteredStackTrace == null && activeSettings.stackDepth > 0) { filteredStackTrace = DebugStackTraceFormatter.SMART_FRAME_FILTER. getFilteredStackTrace(stackTrace); } settings.debugPublisher.traceJEAccess(level, activeSettings, signature, sl, status, database, txn, key, data, filteredStackTrace); } } } } /** * Log raw data in the form of a byte array. * * @param level the level of the log message. * @param data the data to dump. */ public void debugData(LogLevel level, byte[] data) { if(DebugLogger.debugEnabled() && data != null) { StackTraceElement[] stackTrace = null; StackTraceElement[] filteredStackTrace = null; StackTraceElement callerFrame = null; for (PublisherSettings settings : publisherSettings) { TraceSettings activeSettings = settings.classSettings; Map methodSettings = settings.methodSettings; if (shouldLog(level, DebugLogCategory.DATA, activeSettings) || methodSettings != null) { if(stackTrace == null) { stackTrace = Thread.currentThread().getStackTrace(); } if (callerFrame == null) { callerFrame = getCallerFrame(stackTrace); } String signature = callerFrame.getMethodName(); // Specific method settings still could exist. Try getting // the settings for this method. if(methodSettings != null) { TraceSettings mSettings = methodSettings.get(signature); if (mSettings == null) { // Try looking for an undecorated method name int idx = signature.indexOf('('); if (idx != -1) { mSettings = methodSettings.get(signature.substring(0, idx)); } } // If this method does have a specific setting and it is not // suppose to be logged, continue. if (mSettings != null) { if(!shouldLog(level, DebugLogCategory.DATA, mSettings)) { continue; } else { activeSettings = mSettings; } } } String sl = callerFrame.getFileName() + ":" + callerFrame.getLineNumber(); if (filteredStackTrace == null && activeSettings.stackDepth > 0) { filteredStackTrace = DebugStackTraceFormatter.SMART_FRAME_FILTER. getFilteredStackTrace(stackTrace); } settings.debugPublisher.traceData(level, activeSettings, signature, sl, data, filteredStackTrace); } } } } /** * Log a protocol element. * * @param level the level of the log message. * @param elementStr the string representation of protocol element. */ public void debugProtocolElement(LogLevel level, String elementStr) { if(DebugLogger.debugEnabled() && elementStr != null) { StackTraceElement[] stackTrace = null; StackTraceElement[] filteredStackTrace = null; StackTraceElement callerFrame = null; for (PublisherSettings settings : publisherSettings) { TraceSettings activeSettings = settings.classSettings; Map methodSettings = settings.methodSettings; if (shouldLog(level, DebugLogCategory.PROTOCOL, activeSettings) || methodSettings != null) { if(stackTrace == null) { stackTrace = Thread.currentThread().getStackTrace(); } if (callerFrame == null) { callerFrame = getCallerFrame(stackTrace); } String signature = callerFrame.getMethodName(); // Specific method settings still could exist. Try getting // the settings for this method. if(methodSettings != null) { TraceSettings mSettings = methodSettings.get(signature); if (mSettings == null) { // Try looking for an undecorated method name int idx = signature.indexOf('('); if (idx != -1) { mSettings = methodSettings.get(signature.substring(0, idx)); } } // If this method does have a specific setting and it is not // suppose to be logged, continue. if (mSettings != null) { if(!shouldLog(level, DebugLogCategory.PROTOCOL, mSettings)) { continue; } else { activeSettings = mSettings; } } } String sl = callerFrame.getFileName() + ":" + callerFrame.getLineNumber(); if (filteredStackTrace == null && activeSettings.stackDepth > 0) { filteredStackTrace = DebugStackTraceFormatter.SMART_FRAME_FILTER. getFilteredStackTrace(stackTrace); } settings.debugPublisher.traceProtocolElement(level, activeSettings, signature, sl, elementStr, filteredStackTrace); } } } } /** * Log raw data in the form of a ByteBuffer. * * @param level the level of the log message. * @param buffer the data to dump. */ public void debugData(LogLevel level, ByteBuffer buffer) { debugData(level, buffer.array()); } /** * Gets the name of the class this tracer traces. * * @return The name of the class this tracer traces. */ public String getTracedClassName() { return className; } /** * Update the cached settings of the tracer with the settings from the * provided publishers. * * @param publishers The array of publishers to obtain the settings from. */ @SuppressWarnings("unchecked") void updateSettings(DebugLogPublisher[] publishers) { PublisherSettings[] newSettings = new PublisherSettings[publishers.length]; // Get the settings from all publishers. for(int i = 0; i < publishers.length; i++) { DebugLogPublisher publisher = publishers[i]; PublisherSettings settings = new PublisherSettings(); settings.debugPublisher = publisher; settings.classSettings = publisher.getClassSettings(className); // For some reason, the compiler doesn't see that // debugLogPublihser.getMethodSettings returns a parameterized Map. // This problem goes away if a parameterized verson of DebugLogPublisher // is used. However, we can't not use reflection to instantiate a generic // DebugLogPublisher type. The only thing // we can do is to just supress the compiler warnings. settings.methodSettings = publisher.getMethodSettings(className); newSettings[i] = settings; } publisherSettings = newSettings; } /** * Return the caller stack frame. * * @param stackTrace The entrie stack trace frames. * @return the caller stack frame or null if none is found on the * stack trace. */ private StackTraceElement getCallerFrame(StackTraceElement[] stackTrace) { if (stackTrace != null && stackTrace.length > 0) { // Skip leading frames debug logging classes and getStackTrace // method call frame if any. for (int i = 0; i < stackTrace.length; i++) { StackTraceElement aStackTrace = stackTrace[i]; if(aStackTrace.getClassName().startsWith("java.lang.Thread")) { continue; } if (!aStackTrace.getClassName().startsWith( "org.opends.server.loggers.debug")) { return aStackTrace; } } } return null; } private boolean shouldLog(LogLevel messageLevel, LogCategory messageCategory, TraceSettings activeSettings) { return !(activeSettings.includeCategories != null && !activeSettings.includeCategories.contains(messageCategory)) && messageLevel.intValue() >= activeSettings.level.intValue(); } }