使用ArchUnit强制日志上下文:示例代码编译失败求助
解决ArchUnit日志上下文规则编译错误的方案
错误原因
编译错误源于rawParameterTypes方法期望接收针对HasParameterTypes类型的DescribedPredicate,但你传入的是直接测试List<JavaClass>的谓词,导致类型不匹配。
修复后的规则实现
针对ArchUnit 1.0.1版本,提供两种可行的实现方式:
方式一:直接判断参数数量(简洁版)
如果只需校验参数个数,用parameterCount条件更直观:
import com.tngtech.archunit.core.domain.JavaClass; import com.tngtech.archunit.lang.ArchCondition; import com.tngtech.archunit.lang.ArchRule; import com.tngtech.archunit.lang.Conditions; import com.tngtech.archunit.lang.conditions.CallMethodCondition; import static com.tngtech.archunit.lang.conditions.ArchConditions.callMethodWhere; import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; import static com.tngtech.archunit.core.domain.JavaClass.Predicates.assignableTo; import org.slf4j.Logger; public class LoggingArchRules { public static ArchRule noInfoLoggingWithoutContext() { ArchCondition<JavaClass> loggerWithoutContext = callMethodWhere( CallMethodCondition.target( Conditions.name("info") .and(Conditions.owner(assignableTo(Logger.class))) .and(Conditions.parameterCountLessThanOrEqualTo(1)) ) ).as("调用logger.info时未传入上下文信息(参数数量不足)"); return noClasses().should(loggerWithoutContext); } }
方式二:自定义参数校验(灵活版)
如果需要更复杂的参数类型判断,可通过HasParameterTypes获取参数列表:
import com.tngtech.archunit.core.domain.JavaClass; import com.tngtech.archunit.lang.ArchCondition; import com.tngtech.archunit.lang.ArchRule; import com.tngtech.archunit.lang.DescribedPredicate; import com.tngtech.archunit.lang.conditions.CallMethodCondition; import static com.tngtech.archunit.lang.conditions.ArchConditions.callMethodWhere; import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; import static com.tngtech.archunit.core.domain.JavaClass.Predicates.assignableTo; import org.slf4j.Logger; public class LoggingArchRules { public static ArchRule noInfoLoggingWithoutContext() { ArchCondition<JavaClass> loggerWithoutContext = callMethodWhere( CallMethodCondition.target( DescribedPredicate.describe("info方法且参数数量≤1", target -> target.getName().equals("info") && target.getOwner().isAssignableTo(Logger.class) && target.getRawParameterTypes().size() <= 1 ) ) ).as("调用logger.info时未传入上下文信息"); return noClasses().should(loggerWithoutContext); } }
说明
两种方案均能强制logger.info调用必须携带至少两个参数(如格式化字符串+上下文参数、异常+描述信息等),确保日志包含足够排查问题的上下文。注意导入对应的ArchUnit和SLF4J类,避免编译依赖错误。
内容的提问来源于stack exchange,提问作者gaurs
相关产品推荐
相关产品推荐

