新聞中心
Jenkins 的默認(rèn)日志難以閱讀,但日志本不必如此。

為南山等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及南山網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為網(wǎng)站制作、成都網(wǎng)站建設(shè)、南山網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!
Jenkins 是一個(gè)自由開源的自動(dòng)化服務(wù)器,用于構(gòu)建、測(cè)試和部署代碼。它是持續(xù)集成Continuous Integration(CI)、持續(xù)交付Continuous Delivery(CD)的基礎(chǔ),可以為開發(fā)人員每天節(jié)約幾小時(shí),并保護(hù)他們免受失敗的代碼上線的影響。一旦代碼失效或開發(fā)人員需要查看測(cè)試輸出時(shí),Jenkins 提供了日志文件以供檢查。
默認(rèn)的 Jenkins 管道Pipeline日志可能難以閱讀。這篇關(guān)于 Jenkins 日志的基礎(chǔ)知識(shí)的總結(jié)文章提供了一些技巧(和代碼),說明了如何提升它們的可讀性。
你獲得什么
Jenkins 管道分為 幾個(gè)階段。Jenkins 自動(dòng)記錄每個(gè)階段的開始,記錄內(nèi)容如下:
[Pipeline] // stage
[Pipeline] stage (hide)
[Pipeline] { (Apply all openshift resources)
[Pipeline] dir
上文顯示的內(nèi)容沒有太大區(qū)分度,重要的內(nèi)容(如階段的開始)未突出顯示。在多達(dá)數(shù)百行的管道日志中,要找到一個(gè)階段的起始和另外一個(gè)階段的終止位置可能會(huì)很艱巨。當(dāng)隨意瀏覽日志尋找一個(gè)特定的階段的時(shí)候,這種艱巨尤其明顯。
Jenkins 管道是由 Groovy 和 Shell 腳本混合編寫的。在 Groovy 代碼中,日志記錄很少。很多時(shí)候,日志是由命令中的不起眼的文本組成,沒有詳細(xì)信息。在 Shell 腳本中,打開了調(diào)試模式(set -x),所以每條命令都會(huì)被完全具現(xiàn)化realized(變量被解除引用并打印出數(shù)值)并詳細(xì)記錄,輸出也是如此。
鑒于日志可能有很多內(nèi)容,通讀日志獲取相關(guān)信息可能很繁瑣。由于在管道中被處理,并跟著一個(gè) Shell 腳本的 Groovy 日志可讀性差,它們很多時(shí)候缺少上下文:
[Pipeline] dir
Running in /home/jenkins/agent/workspace/devop-master/devops-server-pipeline/my-repo-dir/src
[Pipeline] { (hide)
[Pipeline] findFiles
[Pipeline] findFiles
[Pipeline] readYaml
[Pipeline] }
我可以知道我正在使用的目錄,并且知道我正在使用 Jenkins 的步驟搜索文件、讀取 YAML 文件。但是我在尋找什么?我找到并讀取的內(nèi)容是什么?
能做什么?
我很高興你這么問,因?yàn)檫@里有一些簡(jiǎn)單的做法和一些小的代碼片段可以提供幫助。首先,代碼如下:
def echoBanner(def ... msgs) {
echo createBanner(msgs)
}
def errorBanner(def ... msgs) {
error(createBanner(msgs))
}
def createBanner(def ... msgs) {
return """
===========================================
${msgFlatten(null, msgs).join("\n ")}
===========================================
"""
}
// flatten function hack included in case Jenkins security
// is set to preclude calling Groovy flatten() static method
// NOTE: works well on all nested collections except a Map
def msgFlatten(def list, def msgs) {
list = list ?: []
if (!(msgs instanceof String) && !(msgs instanceof GString)) {
msgs.each { msg ->
list = msgFlatten(list, msg)
}
}
else {
list += msgs
}
return list
}
將這段代碼添加到每個(gè)管道的末尾,也可以 加載一個(gè) Groovy 文件 或者使其成為 Jenkins 共享庫 的一部分,這樣更有效。
在每個(gè)階段起始處(或者在階段中的特定位置),只需調(diào)用 echoBanner:
echoBanner("MY STAGE", ["DOING SOMETHING 1", "DOING SOMETHING 2"])
你的 Jenkins 日志會(huì)展示如下:
===========================================
MY STAGE
DOING SOMETHING 1
DOING SOMETHING 2
===========================================
這個(gè)橫幅很容易從日志中分辨出來。當(dāng)正確使用它們時(shí),它們還有助于界定管道流,并且可以很好的將日志分解開來進(jìn)行閱讀。
我已經(jīng)在某些地方專業(yè)地使用這些代碼一些時(shí)間了。在幫助管道日志更易讀和流程更易理解方面,反饋是非常積極的。
上述的 errorBanner 方法以相同的方式工作,但是它會(huì)立即使腳本失效。這有助于突顯失敗的位置與原因。
最佳實(shí)踐
- 在你的 Groovy 代碼中大量使用
echoJenkins 步驟來通知用戶你在做什么。這些也可以幫助記錄你的代碼。 - 使用空的日志語句(Groovy 中空的 echo 步驟、
echo ''或 Shell 中的echo)來分割輸出,提高可讀性。你可能在你的代碼中為同樣的目的使用空行。 - 避免在腳本中使用
set +x的陷阱,因?yàn)樗[藏了日志記錄已執(zhí)行的 Shell 語句。它并沒有清理你的日志,而是使你的管道成為一個(gè)黑盒子,隱藏了管道正在做的行為以及出現(xiàn)的任何錯(cuò)誤。確保管道功能盡可能透明。 - 如果你的管道創(chuàng)建了中間工件Intermediate Artifacts,開發(fā)人員和 DevOps 人員可以使用這些工件來幫助調(diào)試問題,那么也要記錄它的內(nèi)容。是的,它會(huì)加長(zhǎng)日志,但這只是文本。在某些時(shí)候,這會(huì)是有用的信息,而(利用得當(dāng)?shù)模┤罩静痪褪顷P(guān)于發(fā)生了什么和為什么發(fā)生的大量信息嗎?
Kubernetes 機(jī)密信息:無法完全透明的地方
有些事情你不希望出現(xiàn)在日志里暴露出來。如果你在使用 Kubernetes 并引用保存在 Kubernetes 機(jī)密信息Secrets中的數(shù)據(jù),那么你絕對(duì)不希望在日志中公開該數(shù)據(jù),因?yàn)檫@些數(shù)據(jù)只是被混淆了,而沒有被加密。
假如你想獲取一些保存在機(jī)密信息中的數(shù)據(jù),然后將其注入模板化 JSON 文件中。(機(jī)密信息和 JSON 模板的完整內(nèi)容與此例無關(guān)。)按照最佳實(shí)踐,你希望保持透明并記錄你的操作,但你不想公開機(jī)密信息數(shù)據(jù)。
將腳本模式從調(diào)試(set -x)更改為命令記錄(set -v)。在腳本敏感部分的結(jié)尾,將 Shell 重置為調(diào)試模式:
sh """
# change script mode from debugging to command logging
set +x -v
# capture data from secret in shell variable
MY_SECRET=\$(kubectl get secret my-secret --no-headers -o 'custom-column=:.data.my-secret-data')
# replace template placeholder inline
sed s/%TEMPLATE_PARAM%/${MY_SECRET_DATA}/ my-template-file.json
# do something with modified template-file.json...
# reset the shell to debugging mode
set -x +v
"""
這將輸出此行到日志:
sed s/%TEMPLATE_PARAM%/${MY_SECRET_DATA}/ my-template-file.json
與 Shell 調(diào)試模式中不同,這不會(huì)具現(xiàn)化 Shell 變量 MY_SECRET_DATA。顯然,如果管道中在這一點(diǎn)出現(xiàn)問題,而你試圖找出問題出在哪里,那么這不如調(diào)試模式有用。但這是在保持管道執(zhí)行對(duì)開發(fā)人員和 DevOps 透明的同時(shí),也保持你的秘密的最佳平衡。
當(dāng)前題目:如何使Jenkins日志更可讀
文章位置:http://m.fisionsoft.com.cn/article/ccooehc.html


咨詢
建站咨詢
