This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#/bin/sh | |
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin | |
s='{"endpoint":"%s","timestamp":%s,"metric":"%s","value":%s,"tags":"name=%s","counterType":"GAUGE","step":60}\n' | |
docker stats --no-stream $(docker ps | awk '{if(NR>1) print $NF}') \ | |
| awk '{if(NR>1) {gsub(/%/,"",$2); print "docker.stats.cpu.used.percent", $2, $1;gsub(/%/,"",$8);print "docker.stats.mem.used.percent", $8, $1}}' \ | |
| awk -v date="$(date +%s)" -v hostname="$(hostname -s)" '{print hostname, date, $0}' \ | |
| awk -v format=$s '{printf(format,$1,$2,$3,$4,$5) }' \ | |
| awk -v size=$(docker ps | wc -l) 'BEGIN{print "["}{if(NR<2*(size-1)){print $0","} else {print $0}}END{print "]"}' |
這種風格它有幾項特色:
1. 主要使用 awk
2. awk 指令用 unix pipe 串接
仔細分析這種風格使用的程式語言的概念:
1. 每一行的 awk 指令,可以視為是函數呼叫,而且是「高階函數」(higher order function) 。是高階函數是因為 awk 指令都隱含了一個迴圈、每一行就是對應一次的迴圈操作。
2. 每一行的 awk 指令裡的部分運算內容,可以視為是傳遞進入高階函數裡的運算,換言之,它們可以視為是匿名函數。
3. unix pipe 之間,是通過有特定格式「字串流」 (string stream) 來傳遞資料。 其『特定格式』是表格的形式,以斷行字元 (\n) 來分隔 row,以空白字元 (\s) 來分隔 column
有了上述的分析,要講出優點就容易多了:
1. 因為使用了高階函數的概念,要寫的 boilerplate code 就變少了,寫起來自然快。
2. 因為使用了匿名函數,一方面減少了 boilerplate code ,還省去了函數命名的心理負擔。
3. 使用有特定格式的字串流來傳遞資料,因為特定格式通常可以描述輸出所需要的完整資料,程式就可以變成「單向的資料流」。程式要復用的時候,通常就是截取資料流之中,可以復用的部分來復用。
此外,這種使用字串流的風格與 C style 的程式設計最大的差異點在於: 「C style 的程式設計風格是只要是不會被函數修改的資料,都盡量不要放進函數的輸入、輸出。」這是因為執行效能考量,減少不必要的拷貝。付出的代價則是,往往為了輸入輸出引數的一點點變化,要寫許多重覆的程式、或是套接 (adapter) 的程式碼,因而減少了開發效率。
4. Unix pipe 雖然不是惰性求值 (lazy evaluation) ,而是 buffered queue ,但是使用 unix pipe 寫出的 shell script 卻是惰性求值的風格:『不需要管資料的長度』。
另一方面,也有缺點,但是要克服缺點,就需要使用 python/clojure 之類的語言才容易克服了。
1. 每一行 (row) 的字串資料對應的 awk 指令,其實就是 functional programming 裡的 map/filter 操作。改成用 map/filter/reduce 來寫,表現力不會打折扣,可讀性還會提高。
2. 匿名函數如果要復用時,還是給它取個名稱比較好。
3. 使用特定格式的字串流來傳遞資料,不如使用 list 或是 hash map 來傳遞資料。後者的表現能力更強、而且還可以夾帶型別資訊。