Tie*_*ran 5 logging continuous-integration verbosity jenkins
我们有一个构建作业,其中控制台输出显示许多奇怪的消息,如下所示,因此我们无法加载完整日志,并且必须删除-X构建配置中的选项以摆脱它们。我认为这是在我升级 Jenkins 版本后发生的。
知道是什么原因造成的吗?
[DEBUG] http-outgoing-0 >> "j[0x5]q4/J[0x18]^di[0x86][0xbf]C_[0xd6]G[0x1d]
[0xd4][0x7][0xf3][0xc7][0x14][0xdf][0x8d][0xe1][0x13][0xd8]$y|#[0x1e][0xbf]
[0xe6][0x81]<[0xca][0x6][0xa1]~j[0x81]3[0xbc][0x98][0xd1][0x83][0xa7]
[0xc5]8[0xfa]>[0xd9]edZ[0xb2][0xc][0xe0][0x5][0xab][0xf3][0x1a]M[0xb3][0xe7]
[0x1][0xf4][\n]"
[DEBUG] http-outgoing-0 >> "[0xcd][0x9d][0x86]Zjp[0xb4][0x8d][0x87]
[0x8f]cn[0xe7][0xab]oL.[0xb2]}[0x86][0xf8]D[0x87][0xba][0x9d][0xcc]j[0x15]
[0xa4][0xe6]![0x9f]_BBC[0xbf]j[0xab]Rl[0x10][0x92][0xc5])[0xb2][0xc5]i[0xc2]
Run Code Online (Sandbox Code Playgroud)
我大约在同一时间(2018 年 4 月)遇到了这个问题,并发现它是由 Artifactory 插件 2.15.0(及更高版本)触发的。一年多来,我一直将该插件降级,以避免在我的构建日志中记录调试日志。虽然这对我有用(直到上周由于与新版本的 Artifactory 不兼容而被迫升级),但类路径中的不同插件或 jar 文件可能会导致您的情况出现问题。
在花了整个周末解决这个问题后,我终于在我的构建环境中找到了根本原因。
重点是:
潜在的问题
就我而言,DEBUG 日志记录的根本原因是我的测试依赖项中有cobertura-2.1.1.jar,其中包含logback.xml文件,并且还将logback-classic.jar作为依赖项引入(广泛认为是错误,参见第 2 期、第 14 期、第 36 期)。当在类路径中找到logback.xml文件时,它会覆盖 Jenkins(以及正在构建的项目)中的任何其他 logback 设置。但是,由于 logback 不是 Apache Commons Logging (JCL) 选择的日志框架,因此从未触发此日志设置。
触发
将 Artifactory 插件从 2.14.0 升级到 2.15.0 将其日志记录从:commons-logging-1.1.1.jar ( log4j-1.2.17.jar ) 切换为:jcl-over-slf4j-1.7.25.jar ( slf4j -api-1.7.25.jar)。仅供参考,log4j 1.x使用默认的根日志记录级别 DEBUG,而log4j 2.x使用全局日志记录级别 ERROR,这可能是完全不同的 DEBUG 日志记录源(但在我的情况下不是)。我的构建环境(ant)在类路径上提供 log4j 2.10.0 和 logback,这只会根据构建过程中运行的插件产生不一致的结果来混淆我的测试。
使用 Artifactory 插件 v2.15.0+ 时,日志记录框架切换到 logback,这为cobertura-2.1.1.jar中的logback.xml文件提供了将根日志级别设置为 DEBUG 的权限,从而强制构建的所有后续部分在DEBUG级别记录的过程。这包括Apache Commons HttpClient的线路日志记录,它会生成http-outgoing-0(来自每个 HTTP/S 消息的序列化十六进制和交错 Base64 编码内容 - 正如您在问题中所示)。即使对于小型项目,以这种方式记录 JAR 文件的单个 PUT 也会将构建时间和构建日志的大小增加几个数量级(这是我在构建环境中遇到的情况),这可以轻松瘫痪你的整个 Jenkins 服务器。这是一个巨大的问题,正如您从上面的 Cobertura GitHub 问题中看到的那样,尽管这是一个简单的修复,但在四年内没有采取任何步骤来生成修复版本。
修复方法
为了解决这个问题,我必须在 Jenkins 服务器上进行一些更改:
将.ant/lib文件夹中的logback-classic.jar和logback-core.jar替换为slf4j-simple-1.7.26.jar(这是 Ant 在构建和测试我的项目时使用的类路径)。此更改完全阻止在 Ant 中使用 logback(因此类路径中的任何logback.xml文件都变得无关紧要),同时仍然允许您的构建通过 SLF4J API 执行日志记录(通过slf4j-simple)。
删除对冗余日志记录版本的任何依赖项(例如,不要在类路径中同时包含commons-logging-1.1.1和commons-logging-1.2 )。如果使用 log4j,这一点尤其重要,其中版本 1.1 默认为 DEBUG,版本 1.2 默认为 ERROR。您永远不知道 JCL 会选择哪个底层框架,因此您希望为其提供尽可能少的选项。
最后,为了让测试环境与Ant环境匹配,我调整了所有项目的依赖关系,专门排除 logback-classic(我使用ivy进行依赖解析,所以maven或gradle会有不同的语法):
<dependency org="net.sourceforge.cobertura" name="cobertura" rev="latest.release" conf="test->default">
<exclude org="org.apache.ant" />
<exclude name="jaxen" />
<exclude name="jetty" />
<exclude name="jetty-util" />
<exclude name="servlet-api-2.5" />
<exclude name="logback-classic" /> <!-- IMPORTANT -->
</dependency>
Run Code Online (Sandbox Code Playgroud)作为参考,我损坏的 .ant/lib文件夹包含这些与日志记录相关的 jar 文件(DEBUG 日志的 2 个可能来源):
而我的固定 .ant/lib文件夹包含以下日志记录 jar:
在我的固定 Ant 类路径中,commons-logging-1.2只能选择 SLF4J API(或 JUL),并且只有一个 SLF4J 实现可用(slf4j-simple)。
长话短说
三年来,Cobertura 2.1.1 一直在告诉 logback “DEBUG All the Things!” ,但没有人在听,直到新版本的 Artifactory 插件更改了 JCL 版本并带来了 SLF4J 实现,允许将 logback 选为“最佳可用”日志框架。当 JCL 被引入 logback 时,logback 采纳了 Cobertura 的建议并在我的构建日志中举办了一场聚会。可以通过从环境中删除 logback 并为 JCL 和 SLF4J API(例如slf4j-simple)提供行为良好的日志记录框架来防止这种情况。