Docker CLI 的 --format 參數提供了基于 Go模闆 的日志格式化輸出輔助功能,并提供了一些内置的增強函數。 本文結合 docker 日志輸出格式化的具體操作示例,先簡要介紹 Go模闆的常用文法,再介紹 Docker 内置增強函數的使用。

上圖是大家熟悉的 MVC 架構(Model View Controller): Model(模型,通常在服務端)用于處理資料、View(視圖,用戶端代碼)用于展現結果、Controller(控制器)用于控制資料流,確定 M 和 V 的同步,即一旦 M 改變,V 也應該同步更新。
而對于 View 端的處理,在很多動态語言中是通過在靜态 HTML 代碼中插入動态資料來實作的。例如 JSP 的 <code><%=....=%></code> 和 PHP 的 <code><?php.....?></code> 文法。
由于最終展示給使用者的資訊大部分是靜态不變的,隻有少部分資料會根據使用者的不同而動态生成。比如,對于 docker ls 的輸出資訊會根據附加參數的不同而不同,但其表頭資訊是固定的。是以,将靜态資訊固化為模闆可以複用代碼,提高展示效率。
Go語言提供了簡單靈活的模闆支援,而基于 Go 開發的 Docker 繼承了該強大能力,使其可以脫離 Shell 的相關操作,直接對結果進行格式化輸出。所有支援 --format 擴充的 Docker CLI 指令均支援該操作。
格式: <code>{{/*注釋内容*/}}</code>
示例:
點号表示目前對象及上下文,和 Java、C++ 中的 this 類似。可以直接通過<code>{{.}}</code>擷取目前對象。
另外,如果傳回結果也是一個 Struct 對象(Json 中以花括号/大括号包含),則可以直接通過點号級聯調用,擷取子對象的指定屬性值。
示例代碼:
注意: 如果需要擷取的屬性名稱包含點号(比如下列示例資料)或者以數字開頭,則不能直接通過級聯調用擷取資訊。因為屬性名稱中的點号會被解析成級聯資訊,進而導緻傳回錯誤結果。即便使用引号将其包含也會提示文法格式錯誤。此時,需要通過 index 來讀取指定屬性資訊。
示例操作:
可以在處理過程中設定自定義變量,然後結合自定義變量做更複雜的處理。 如果自定義變量的傳回值是對象,則可以通過點号進一步級聯通路其屬性。比如 {{$Myvar.Field1}}。
格式:
range 用于周遊結構内傳回值的所有資料。支援的類型包括 array, slice, map 和 channel。使用要點:
對應的值長度為 0 時,range 不會執行。
結構内部如要使用外部的變量,需要在前面加 $ 引用,比如 $Var2。
range 也支援 else 操作。效果是:當傳回值為空或長度為 0 時執行 else 内的内容。
如果傳回結果是一個 map, slice, array 或 string,則可以使用 index 加索引序号(從零開始計數)來讀取屬性值。
not
傳回單一參數的布爾否定值,即傳回輸入參數的否定值。
or:
{{or x y}}: 表示如果 x 為真傳回 x,否則傳回 y。
{{or x y z}}:後面跟多個參數時會逐一判斷每個參數,并傳回第一個非空的參數。如果都為 false,則傳回最後一個參數。
除了 null(空)和 false 被識别為 false,其它值(字元串、數字、對象等)均被識别為 true。
判斷語句通常需要結合判斷條件一起使用,使用格式基本相同:
go模闆支援如下判斷方式:
eq: 相等,即 arg1 == arg2。比較特殊的是,它支援多個參數進行與比較,此時,它會将第一個參數和其餘參數依次比較,傳回下式的結果:
ne: 不等,即 arg1 != arg2。
lt: 小于,即 arg1 < arg2。
le: 小于等于,即 arg1 <= arg2。
gt: 大于,即 arg1 > arg2。
ge: 大于等于,即 arg1 >= arg2。
docker --format 預設調用 go語言的 print 函數對模闆中的字元串進行輸出。而 go語言還有另外 2 種相似的内置函數,對比說明如下:
print: 将傳入的對象轉換為字元串并寫入到标準輸出中。如果後跟多個參數,輸出結果之間會自動填充空格進行分隔。
println: 功能和 print 類似,但會在結尾添加一個換行符。也可以直接使用 <code>{{println}}</code> 來換行。
對比示例輸出:
管道 即 pipeline ,與 shell 中類似,可以是上下文的變量輸出,也可以是函數通過管道傳遞的傳回值。
内置函數 len 傳回相應對象的長度。
Docker 基于 go模闆的基礎上,建構了一些内置函數。下面逐一說明:
Docker 預設以字元串顯示傳回結果。而該函數可以将結果格式化為壓縮後的 json 格式資料。
用指定的字元串将傳回結果連接配接後一起展示。操作對象必須是字元串數組。
将傳回結果中的字母全部轉換為小寫。操作對象必須是字元串。
将傳回結果中的字母全部轉換為大寫。操作對象必須是字元串。
将傳回結果的首字母轉換為大寫。操作對象必須是字元串,而且不能是純數字。
使用指定分隔符将傳回結果拆分為字元串清單。操作對象必須是字元串且不能是純數字。同時,字元串中必須包含相應的分隔符,否則會直接忽略操作。
<a href="https://golang.org/pkg/html/template/">Go模闆官方文檔</a>
<a href="https://docs.docker-cn.com/engine/admin/formatting/#template-functions">Docker 官方日志格式化說明文檔</a>