Package com.mebigfatguy.fbcontrib.detect
Class LoggerOddities
java.lang.Object
edu.umd.cs.findbugs.visitclass.BetterVisitor
edu.umd.cs.findbugs.visitclass.PreorderVisitor
edu.umd.cs.findbugs.visitclass.AnnotationVisitor
edu.umd.cs.findbugs.visitclass.DismantleBytecode
edu.umd.cs.findbugs.BytecodeScanningDetector
com.mebigfatguy.fbcontrib.detect.LoggerOddities
- All Implemented Interfaces:
edu.umd.cs.findbugs.Detector,edu.umd.cs.findbugs.Priorities,org.apache.bcel.classfile.Visitor
@CustomUserValue
public class LoggerOddities
extends edu.umd.cs.findbugs.BytecodeScanningDetector
looks for uses of log4j or slf4j where the class specified when creating the
logger is not the same as the class in which this logger is used. Also looks
for using concatenation with slf4j logging rather than using the
parameterized interface.
-
Nested Class Summary
Nested Classes -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate static final Patternprivate static final Patternprivate final edu.umd.cs.findbugs.BugReporterprivate static final Stringprivate static final Patternprivate booleanprivate static final Stringprivate static final Stringprivate static final Stringprivate Stringprivate static final Patternprivate static final Stringprivate static final Stringprivate static final Stringprivate static final Stringprivate static final Stringprivate static final Stringprivate static final Stringprivate static final Stringprivate static final Stringprivate static final Stringprivate static final Stringprivate static final Stringprivate static final Stringprivate static final Stringprivate edu.umd.cs.findbugs.OpcodeStackprivate org.apache.bcel.classfile.JavaClassFields inherited from class edu.umd.cs.findbugs.visitclass.DismantleBytecode
codeBytes, lineNumberTable, M_BR, M_CP, M_INT, M_PAD, M_R, M_UINTFields inherited from interface edu.umd.cs.findbugs.Priorities
EXP_PRIORITY, HIGH_PRIORITY, IGNORE_PRIORITY, LOW_PRIORITY, NORMAL_PRIORITY -
Constructor Summary
ConstructorsConstructorDescriptionLoggerOddities(edu.umd.cs.findbugs.BugReporter bugReporter) constructs a LO detector given the reporter to report bugs on. -
Method Summary
Modifier and TypeMethodDescriptionprivate voidlooks for slf4j calls where an exception is passed as a logger parameter, expecting to be substituted for a {} marker.private voidlooks for a variety of logging issues with log statementsprivate voidprivate voidprivate voidprivate static intcountAnchors(String formatString) returns the number of anchors {} in a stringprivate Stringprivate intgetVarArgsParmCount(String signature) returns the number of parameters slf4j or log4j2 is expecting to inject into the format stringprivate booleanreturns whether an exception object is on the stack slf4j will find this, and not include it in the parm list so i we find one, just don't reportprivate booleanisLoggerWithClassParm(edu.umd.cs.findbugs.ba.XMethod m) returns whether this method class is a standard logger instantiation that takes a java/lang/Class parameterprivate booleanisNonPrivateLogField(String fieldClsName, String fieldName, String fieldSig) looks to see if this field is a logger, and declared non privatelyprivate voidlooks for instantiation of a logger with what looks like a class name that isn't the same as the class in which it exists.voidsawOpcode(int seen) implements the visitor to look for calls to Logger.getLogger with the wrong class namevoidvisitClassContext(edu.umd.cs.findbugs.ba.ClassContext classContext) implements the visitor to discover what the class name is if it is a normal class, or the owning class, if the class is an anonymous class.voidvisitCode(org.apache.bcel.classfile.Code obj) implements the visitor to reset the stackMethods inherited from class edu.umd.cs.findbugs.BytecodeScanningDetector
getClassContext, report, shouldVisitCodeMethods inherited from class edu.umd.cs.findbugs.visitclass.DismantleBytecode
afterOpcode, areOppositeBranches, atCatchBlock, beforeOpcode, getBranchFallThrough, getBranchOffset, getBranchTarget, getClassConstantOperand, getClassDescriptorOperand, getCodeByte, getConstantRefOperand, getDefaultSwitchOffset, getDottedClassConstantOperand, getFieldDescriptorOperand, getIntConstant, getLongConstant, getMaxPC, getMethodDescriptorOperand, getNameConstantOperand, getNextCodeByte, getNextOpcode, getNextPC, getOpcode, getPC, getPrevOpcode, getRefConstantOperand, getRefFieldIsStatic, getRegisterOperand, getSigConstantOperand, getStringConstantOperand, getSwitchLabels, getSwitchOffsets, getXClassOperand, getXFieldOperand, getXMethodOperand, isBranch, isMethodCall, isRegisterLoad, isRegisterStore, isRegisterStore, isReturn, isShift, isSwitch, isWideOpcode, printOpCode, sawBranchTo, sawClass, sawDouble, sawField, sawFloat, sawIMethod, sawInt, sawLong, sawMethod, sawRegister, sawString, visitMethods inherited from class edu.umd.cs.findbugs.visitclass.AnnotationVisitor
getAnnotationParameterAsEnum, getAnnotationParameterAsString, getAnnotationParameterAsStringArray, visitAnnotation, visitAnnotation, visitParameterAnnotation, visitParameterAnnotation, visitSyntheticParameterAnnotationMethods inherited from class edu.umd.cs.findbugs.visitclass.PreorderVisitor
amVisitingMainMethod, asUnsignedByte, doVisitMethod, getClassDescriptor, getClassName, getCode, getConstantPool, getDottedClassName, getDottedFieldSig, getDottedMethodSig, getDottedSuperclassName, getField, getFieldDescriptor, getFieldIsStatic, getFieldName, getFieldSig, getFullyQualifiedFieldName, getFullyQualifiedMethodName, getMethod, getMethodDescriptor, getMethodName, getMethodSig, getMethodVisitOrder, getNumberArguments, getNumberMethodArguments, getPackageName, getSizeOfSurroundingTryBlock, getSizeOfSurroundingTryBlock, getSourceFile, getStringFromIndex, getSuperclassName, getSurroundingCaughtExceptions, getSurroundingCaughtExceptions, getSurroundingCaughtExceptionTypes, getSurroundingTryBlock, getSurroundingTryBlock, getThisClass, getXClass, getXField, getXMethod, hasInterestingClass, hasInterestingMethod, isVisitMethodsInCallOrder, setupVisitorForClass, setVisitMethodsInCallOrder, shouldVisit, toString, visitAfter, visitAfter, visitAnnotationDefault, visitAnnotationEntry, visitBootstrapMethods, visitConstantInvokeDynamic, visitConstantMethodHandle, visitConstantMethodType, visitConstantModule, visitConstantPackage, visitConstantPool, visitEnclosingMethod, visitingField, visitingMethod, visitInnerClasses, visitJavaClass, visitLineNumberTable, visitLocalVariableTable, visitMethodParameters, visitParameterAnnotationEntry, visitStackMap, visitStackMapEntryMethods inherited from class edu.umd.cs.findbugs.visitclass.BetterVisitor
clone, report, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visitCodeException, visitConstantClass, visitConstantDouble, visitConstantFieldref, visitConstantFloat, visitConstantInteger, visitConstantInterfaceMethodref, visitConstantLong, visitConstantMethodref, visitConstantNameAndType, visitConstantString, visitConstantUtf8, visitConstantValue, visitDeprecated, visitExceptionTable, visitField, visitInnerClass, visitLineNumber, visitLocalVariable, visitLocalVariableTypeTable, visitMethod, visitSignature, visitSourceFile, visitSynthetic, visitUnknownMethods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitMethods inherited from interface org.apache.bcel.classfile.Visitor
visitConstantDynamic, visitMethodParameter, visitModule, visitModuleExports, visitModuleMainClass, visitModuleOpens, visitModulePackages, visitModuleProvides, visitModuleRequires, visitNestHost, visitNestMembers, visitRecord, visitRecordComponent, visitStackMapType
-
Field Details
-
LOGGER_METHODS
-
COMMONS_LOGGER
- See Also:
-
LOG4J_LOGGER
- See Also:
-
LOG4J2_LOGGER
- See Also:
-
LOG4J2_LOGMANAGER
- See Also:
-
SLF4J_LOGGER
- See Also:
-
SIG_STRING_AND_TWO_OBJECTS_TO_VOID
-
SIG_STRING_AND_OBJECT_ARRAY_TO_VOID
-
SIG_OBJECT_AND_THROWABLE_TO_VOID
-
SIG_STRING_AND_THROWABLE_TO_VOID
-
SIG_CLASS_TO_COMMONS_LOGGER
-
SIG_CLASS_TO_LOG4J_LOGGER
-
SIG_CLASS_TO_LOG4J2_LOGGER
-
SIG_CLASS_TO_SLF4J_LOGGER
-
SIG_STRING_TO_COMMONS_LOGGER
-
SIG_STRING_TO_LOG4J_LOGGER
-
SIG_STRING_TO_LOG4J2_LOGGER
-
SIG_STRING_TO_SLF4J_LOGGER
-
SIG_STRING_AND_FACTORY_TO_LOG4J_LOGGER
-
BAD_FORMATTING_ANCHOR
-
BAD_STRING_FORMAT_PATTERN
-
FORMATTER_ANCHOR
-
NON_SIMPLE_FORMAT
-
bugReporter
private final edu.umd.cs.findbugs.BugReporter bugReporter -
formatterLoggers
-
throwableClass
private org.apache.bcel.classfile.JavaClass throwableClass -
stack
private edu.umd.cs.findbugs.OpcodeStack stack -
nameOfThisClass
-
isStaticInitializer
private boolean isStaticInitializer
-
-
Constructor Details
-
LoggerOddities
public LoggerOddities(edu.umd.cs.findbugs.BugReporter bugReporter) constructs a LO detector given the reporter to report bugs on.- Parameters:
bugReporter- the sync of bug reports
-
-
Method Details
-
visitClassContext
public void visitClassContext(edu.umd.cs.findbugs.ba.ClassContext classContext) implements the visitor to discover what the class name is if it is a normal class, or the owning class, if the class is an anonymous class.- Specified by:
visitClassContextin interfaceedu.umd.cs.findbugs.Detector- Overrides:
visitClassContextin classedu.umd.cs.findbugs.BytecodeScanningDetector- Parameters:
classContext- the context object of the currently parsed class
-
visitCode
public void visitCode(org.apache.bcel.classfile.Code obj) implements the visitor to reset the stack- Specified by:
visitCodein interfaceorg.apache.bcel.classfile.Visitor- Overrides:
visitCodein classedu.umd.cs.findbugs.visitclass.PreorderVisitor- Parameters:
obj- the context object of the currently parsed code block
-
sawOpcode
public void sawOpcode(int seen) implements the visitor to look for calls to Logger.getLogger with the wrong class name- Overrides:
sawOpcodein classedu.umd.cs.findbugs.visitclass.DismantleBytecode- Parameters:
seen- the opcode of the currently parsed instruction
-
isNonPrivateLogField
private boolean isNonPrivateLogField(@SlashedClassName String fieldClsName, String fieldName, String fieldSig) looks to see if this field is a logger, and declared non privately- Parameters:
fieldClsName- the owning class type of the fieldfieldName- the name of the fieldfieldSig- the signature of the field- Returns:
- if the field is a logger and not private
-
isLoggerWithClassParm
private boolean isLoggerWithClassParm(edu.umd.cs.findbugs.ba.XMethod m) returns whether this method class is a standard logger instantiation that takes a java/lang/Class parameter- Parameters:
m- the method to check- Returns:
- if the method is a logger factory method that takes a Class object
-
checkForProblemsWithLoggerMethods
looks for a variety of logging issues with log statements- Throws:
ClassNotFoundException- if the exception class, or a parent class can't be found
-
checkForProblemsWithLoggerThrowableMethods
private void checkForProblemsWithLoggerThrowableMethods() -
checkForProblemsWithLoggerSingleArgumentMethod
- Throws:
ClassNotFoundException
-
checkForProblemsWithLoggerParameterisedMethods
-
checkForLoggerParam
private void checkForLoggerParam()looks for slf4j calls where an exception is passed as a logger parameter, expecting to be substituted for a {} marker. As slf4j just passes the exception down to the message generation itself, the {} marker will go unpopulated. -
lookForSuspectClasses
private void lookForSuspectClasses()looks for instantiation of a logger with what looks like a class name that isn't the same as the class in which it exists. There are some cases where a 'classname-like' string is presented purposely different than this class, and an attempt is made to ignore those. -
getLoggingClassNameFromStackValue
-
countAnchors
returns the number of anchors {} in a string- Parameters:
formatString- the format string- Returns:
- the number of anchors
-
getVarArgsParmCount
returns the number of parameters slf4j or log4j2 is expecting to inject into the format string- Parameters:
signature- the method signature of the error, warn, info, debug statement- Returns:
- the number of expected parameters
-
hasExceptionOnStack
private boolean hasExceptionOnStack()returns whether an exception object is on the stack slf4j will find this, and not include it in the parm list so i we find one, just don't report- Returns:
- whether or not an exception i present
-