1. 程式人生 > >用 shell 指令碼做 restful api 介面監控

用 shell 指令碼做 restful api 介面監控

問題的提出

基於歷史原因,公司有一個“三無”採集服務——無人員、無運維、無監控——有能力做的部門不想接、接了的部門沒能力。於是就一直這樣裸奔,直到前幾天一個依賴於這個採集服務的大資料分析服務入口流量銳減,才發現居然是這個採集服務出問題了!而且問題不是簡單的掛掉,而是這個採集服務給客戶端下發的採集策略中,產品列表為空了!當時事出緊急,把所有產品開關挨個打開了一遍,算是臨時解決了這個問題。事後覆盤這個問題,從問題出現、到問題被感知到、再到問題被臨時解決,這中間消耗的時間太長了,在新的採集服務上線之前,需要隨時監控老的採集服務的介面狀態,一旦有問題就可以立即處理。

問題的解決

對於後臺開發或自動化測試來說,搞個監控是分分鐘的事,對於我們這種客戶端開發就不一樣了,如果用 c/c++ 寫程式碼倒是可以實現,但是一來慢、二來不靈活、三也不值當。於是重操舊業,用 shell 指令碼搞起!話說我用的是 Windows 系統,為了在上面跑 shell 指令碼,事先裝了一個 msys2 系統 —— git bash,這段之前很多文章涉及過了,就不再贅述,就是對我的開發環境做個簡要交待。

 

環境有了,現在整理一下我的思路,我希望做的是:訪問後臺 restful api 介面,從返回的結果中得到開啟的產品數量,如果數量小於某個值,就向相關人員傳送報警郵件,並記錄日誌。每隔一小時檢查一次。

檢查介面返回內容

訪問 restful api 一般是通過 http 協議,這裡我們選取 curl 做為拉取工具,寫指令碼如下:

curl -s "http://***.******.***/v3/server_status?type=100&data_version=2.4"

出於安全考慮,這裡域名被我用星號代替了,後面的兩個 url 引數分別是請求的型別(100 表示獲取產品列表)和當前協議版本號(2.4),如果一切正常的話,你會得到下面這一堆資料:

{"message":"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","md5":"7cc552ea3a1f12c13f63f96f53aec29b27ab7b59542cfaac0c2938375156fdfd","result":true}

 

本身是個 json,有用的域是 message 欄位,它本身又是加密的 (為毛不直接走 https?)。好吧,我們需要一個解密工具,對於客戶端開發來說手到擒來,直接把測試用例改改就弄出來一個:

curl -s "http://***.******.***/v3/server_status?type=100&data_version=2.4" | ./jq -r ".message" | xargs ./test-decode

 

相比上面的語句,多了兩個命令,其中 jq 是用來解析 json 的,負責將 message 欄位提取出來,msys2 預設是不帶這個命令的,可以訪問以下網址獲取:stedolan.github.com/jq/download/ ,安裝後將命令所在目錄新增到 PATH 環境變數、並重啟系統後,就可以在 msys2 系統中使用 jq 了,不過我這裡是直接把命令複製到了指令碼所在目錄,所以需要使用 ./jq 來指明;test-decode 就是我寫的解密工具啦,它從命令列引數讀取加密資料 (所以需要 xargs 進行轉換,不然可以直接用管道線連線啦),將解密後的資料輸出到標準輸出。經過上面的處理,這一坨資料就能被人類所識別了:

after decode:
{"products":[{"id":140,"name":"GrandDog","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":true},{"id":178,"name":"CubicostTRB","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":true},{"id":78,"name":"GTJ2017","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":true},{"id":137,"name":"GMD2017","aggre_status":true,"start":true,"enable_auto":false,"enable_filter":true},{"id":180,"name":"GDraw","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":true},{"id":276,"name":"GLC","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":true},{"id":164,"name":"GUX","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":true},{"id":67,"name":"GCCP5","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":true},{"id":261,"name":"GCCP6","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":true},{"id":17,"name":"TME","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":25,"name":"GWS","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":36,"name":"MOZIDIFFER","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":40,"name":"GMJ","aggre_status":true,"start":true,"enable_auto":false,"enable_filter":false},{"id":44,"name":"GCL2013","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":45,"name":"GGJ2013","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":56,"name":"MD_GMA","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":75,"name":"GDQ2015","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":76,"name":"GQI2017","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":77,"name":"GJG2015","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":80,"name":"GMP2016","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":83,"name":"Revit2GFC4GMP","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":100,"name":"GTJ2017CAD","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":112,"name":"GYZB2017","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":114,"name":"BIM5D_PC","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":115,"name":"GFYCM","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":125,"name":"GBCB","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":128,"name":"CubicostTAS","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":129,"name":"GMD","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":131,"name":"GAQ2017","aggre_status":true,"start":true,"enable_auto":false,"enable_filter":false},{"id":132,"name":"GBCB2017","aggre_status":true,"start":true,"enable_auto":false,"enable_filter":false},{"id":133,"name":"GBS2017","aggre_status":true,"start":true,"enable_auto":false,"enable_filter":false},{"id":134,"name":"GFYC2017","aggre_status":true,"start":true,"enable_auto":false,"enable_filter":false},{"id":135,"name":"GFYCM2017","aggre_status":true,"start":true,"enable_auto":false,"enable_filter":false},{"id":136,"name":"GMJ2017","aggre_status":true,"start":true,"enable_auto":false,"enable_filter":false},{"id":138,"name":"GSJ2017","aggre_status":true,"start":true,"enable_auto":false,"enable_filter":false},{"id":139,"name":"GJH2017","aggre_status":true,"start":true,"enable_auto":false,"enable_filter":false},{"id":142,"name":"TeamViewer","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":148,"name":"ZPert","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":160,"name":"GBS","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":162,"name":"GIR_C","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":163,"name":"TBQ2017","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":167,"name":"GYJC2017","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":177,"name":"GSXGZT2016","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":181,"name":"TBQD","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":182,"name":"TTED","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":183,"name":"TCFD","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":188,"name":"GSCApp","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":200,"name":"GFYC","aggre_status":true,"start":true,"enable_auto":false,"enable_filter":false},{"id":207,"name":"GDQ2017","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":217,"name":"GO","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":218,"name":"AppGbmp","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":222,"name":"GQI2018","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":226,"name":"GDS2017","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":228,"name":"GLDTCS","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":231,"name":"TenderGo","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":232,"name":"GDQ2018","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":233,"name":"SectionManual","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":234,"name":"BeamGo","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":235,"name":"GJG2018","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":236,"name":"RevitViewer","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":237,"name":"BIM5D_PC_TEST","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":238,"name":"BIM5D_PC_TRIAL","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":239,"name":"GEC5","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":240,"name":"GFYQ","aggre_status":true,"start":true,"enable_auto":false,"enable_filter":false},{"id":241,"name":"RoadDesigner","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":242,"name":"CECS100G","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":243,"name":"GBES","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":244,"name":"Ceshi","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":245,"name":"dpUpdate","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":246,"name":"GFY4","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":248,"name":"GGPT","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":249,"name":"GMA2020","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":250,"name":"JZYK","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":251,"name":"GVB5","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":252,"name":"GHW5","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":253,"name":"GUp","aggre_status":true,"start":true,"enable_auto":false,"enable_filter":false},{"id":254,"name":"BIM_COST","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":255,"name":"GICP5","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":256,"name":"bim5d_basic","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":257,"name":"GWH5","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":258,"name":"GFY4_2019","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":259,"name":"GDD2019","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":260,"name":"GCCP5_ShanDong_64","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":262,"name":"GSC6","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":263,"name":"GCCP6_WP","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":264,"name":"GEB6","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":265,"name":"GSH6","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":266,"name":"GTech2019","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":267,"name":"GPC5","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":268,"name":"GTJ2021","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":269,"name":"GDE2019","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":270,"name":"CubicostTIO","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":271,"name":"GCA5","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":272,"name":"GLC5","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":273,"name":"GMT5","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":274,"name":"GCN5","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":275,"name":"GHC5","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":277,"name":"GVB6","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":278,"name":"GJG2021","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":279,"name":"GJG","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":280,"name":"GAP","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":281,"name":"GSTP","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":283,"name":"TRS2021","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":284,"name":"TMEC","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":285,"name":"CubicostTMEC","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":286,"name":"GGF5","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":287,"name":"GRE5","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false},{"id":310,"name":"GA_CloudPlugin","aggre_status":false,"start":true,"enable_auto":false,"enable_filter":false}],"msg_type":100}

 

在網頁裡顯示會自動換行,實際上這段輸出只有兩行,而第二行才是我們需要的。提取第二行後交給 jq 解析出 products 域中的產品資料:

curl -s "http://***.******.***/v3/server_status?type=100&data_version=2.4" | ./jq -r ".message" | xargs ./test-decode | tail -1 | ./jq ".products|.[]"

 

其中 jq ”.products|.[]“ 將把外層的元素去掉,對剩下的“純純“的內容進行 beautify 處理:

{
  "id": 140,
  "name": "GrandDog",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": true
}
{
  "id": 178,
  "name": "CubicostTRB",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": true
}
{
  "id": 78,
  "name": "GTJ2017",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": true
}
{
  "id": 137,
  "name": "GMD2017",
  "aggre_status": true,
  "start": true,
  "enable_auto": false,
  "enable_filter": true
}
{
  "id": 180,
  "name": "GDraw",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": true
}
{
  "id": 276,
  "name": "GLC",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": true
}
{
  "id": 164,
  "name": "GUX",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": true
}
{
  "id": 67,
  "name": "GCCP5",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": true
}
{
  "id": 261,
  "name": "GCCP6",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": true
}
{
  "id": 17,
  "name": "TME",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 25,
  "name": "GWS",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 36,
  "name": "MOZIDIFFER",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 40,
  "name": "GMJ",
  "aggre_status": true,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 44,
  "name": "GCL2013",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 45,
  "name": "GGJ2013",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 56,
  "name": "MD_GMA",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 75,
  "name": "GDQ2015",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 76,
  "name": "GQI2017",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 77,
  "name": "GJG2015",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 80,
  "name": "GMP2016",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 83,
  "name": "Revit2GFC4GMP",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 100,
  "name": "GTJ2017CAD",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 112,
  "name": "GYZB2017",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 114,
  "name": "BIM5D_PC",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 115,
  "name": "GFYCM",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 125,
  "name": "GBCB",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 128,
  "name": "CubicostTAS",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 129,
  "name": "GMD",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 131,
  "name": "GAQ2017",
  "aggre_status": true,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 132,
  "name": "GBCB2017",
  "aggre_status": true,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 133,
  "name": "GBS2017",
  "aggre_status": true,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 134,
  "name": "GFYC2017",
  "aggre_status": true,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 135,
  "name": "GFYCM2017",
  "aggre_status": true,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 136,
  "name": "GMJ2017",
  "aggre_status": true,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 138,
  "name": "GSJ2017",
  "aggre_status": true,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 139,
  "name": "GJH2017",
  "aggre_status": true,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 142,
  "name": "TeamViewer",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 148,
  "name": "ZPert",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 160,
  "name": "GBS",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 162,
  "name": "GIR_C",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 163,
  "name": "TBQ2017",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 167,
  "name": "GYJC2017",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 177,
  "name": "GSXGZT2016",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 181,
  "name": "TBQD",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 182,
  "name": "TTED",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 183,
  "name": "TCFD",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 188,
  "name": "GSCApp",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 200,
  "name": "GFYC",
  "aggre_status": true,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 207,
  "name": "GDQ2017",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 217,
  "name": "GO",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 218,
  "name": "AppGbmp",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 222,
  "name": "GQI2018",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 226,
  "name": "GDS2017",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 228,
  "name": "GLDTCS",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 231,
  "name": "TenderGo",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 232,
  "name": "GDQ2018",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 233,
  "name": "SectionManual",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 234,
  "name": "BeamGo",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 235,
  "name": "GJG2018",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 236,
  "name": "RevitViewer",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 237,
  "name": "BIM5D_PC_TEST",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 238,
  "name": "BIM5D_PC_TRIAL",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 239,
  "name": "GEC5",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 240,
  "name": "GFYQ",
  "aggre_status": true,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 241,
  "name": "RoadDesigner",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 242,
  "name": "CECS100G",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 243,
  "name": "GBES",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 244,
  "name": "Ceshi",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 245,
  "name": "dpUpdate",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 246,
  "name": "GFY4",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 248,
  "name": "GGPT",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 249,
  "name": "GMA2020",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 250,
  "name": "JZYK",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 251,
  "name": "GVB5",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 252,
  "name": "GHW5",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 253,
  "name": "GUp",
  "aggre_status": true,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 254,
  "name": "BIM_COST",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 255,
  "name": "GICP5",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 256,
  "name": "bim5d_basic",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 257,
  "name": "GWH5",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 258,
  "name": "GFY4_2019",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 259,
  "name": "GDD2019",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 260,
  "name": "GCCP5_ShanDong_64",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 262,
  "name": "GSC6",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 263,
  "name": "GCCP6_WP",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 264,
  "name": "GEB6",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 265,
  "name": "GSH6",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 266,
  "name": "GTech2019",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 267,
  "name": "GPC5",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 268,
  "name": "GTJ2021",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 269,
  "name": "GDE2019",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 270,
  "name": "CubicostTIO",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 271,
  "name": "GCA5",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 272,
  "name": "GLC5",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 273,
  "name": "GMT5",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 274,
  "name": "GCN5",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 275,
  "name": "GHC5",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 277,
  "name": "GVB6",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 278,
  "name": "GJG2021",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 279,
  "name": "GJG",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 280,
  "name": "GAP",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 281,
  "name": "GSTP",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 283,
  "name": "TRS2021",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 284,
  "name": "TMEC",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 285,
  "name": "CubicostTMEC",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 286,
  "name": "GGF5",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 287,
  "name": "GRE5",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
{
  "id": 310,
  "name": "GA_CloudPlugin",
  "aggre_status": false,
  "start": true,
  "enable_auto": false,
  "enable_filter": false
}
View Code

 

然後就可以得到下發產品列表中的產品數量了:

1 lines=$(curl -s "http://***.******.***/v3/server_status?type=100&data_version=2.4" | ./jq -r ".message" | xargs ./test-decode | tail -1 | ./jq ".products|.[]" | wc -l)
2 # each item takes 8 line
3 prods=$(($lines/8))
4 echo "product count : $prods" >> log.txt

 

沒有找到 jq 怎麼輸出 json 陣列元素個數,這裡直接用 wc 計算行數除以 8 (每個產品佔用 8 行)得到。同理得到金鑰的數量(每個產品一個單獨的金鑰):

1 lines=$(curl -s "http://***.******.***/v3/server_status?type=101&data_version=2.4" | ./jq -r ".message" | xargs ./test-decode | tail -1 | ./jq ".keys|.[]" | wc -l)
2 # each item takes 4 line
3 keys=$(($lines/4))
4 echo "keys count : $keys" >> log.txt

 

這兩個數量必需一致,且大於某個域值,這裡設定為 100.

 1 limit=100
 2 if [ $prods -ne $keys ]; then 
 3     echo "product count != key count, fatal error" >> log.txt
 4     send_email "$prods" "$keys" "$limit"
 5     exit
 6 fi
 7 
 8 if [ $prods -lt $limit ]; then 
 9     echo "products list too less, warning" >> log.txt
10     send_email "$prods" "$keys" "$limit"
11     exit
12 fi
13 
14 echo "gux server ok" >> log.txt

 

如果有任何異常發生,通過 send_mail 函式來向相關人員傳送告警郵件。

異常情況下發送報警郵件

鐺鐺鐺~ 進入本文核心,現在如果介面中的產品資料為空或減少到特定值(產品一般只增加不減少),就需要通過郵件通知相關責任人了。這裡使用的是 sendmail 命令,在 msys2 環境中,沒有自帶這個命令,需要事先安裝 Windows 版本的壓縮包、並設定 PATH 環境變數包含該命令所在的目錄,重啟機器後就可以在 msys2 環境中直接訪問了。這裡給一個下載連結:www.glob.com.au/sendmail/sendmail.zip。注意這個命令只是模擬 sendmail -t 選項,並不是原生的 sendmail 命令,但是用法和原生命令沒什麼區別。在開始看 send_email 函式之前,讓我們先了解一些基本原理。

郵箱工作原理

你通過 qq 的賬號給 126 發了一封郵件,它經歷了哪些流程呢?請看下圖

 

拋開復雜的協議不談,單說整個流程,就是你先通過郵件客戶端把郵件發到 qq 的郵件伺服器,後者通過地址路郵給 126 的郵件伺服器,最後你的郵件客戶端再去後者的郵件伺服器里拉取收到的郵件。對於 sendmail 命令而言,最主要就是進行傳送賬號的各種配置。

配置傳送賬號

在配置傳送賬號前,我們先選擇一個可靠的賬號,這裡我選取 QQ(不要問為什麼,問就是請參考附錄)。首先登入 mail.qq.com

 

在郵箱的設定中找到賬戶相關設定,開通 IMAP/SMTP 服務:

 

開啟後可以獲取授權碼,一個賬戶可以獲取多個授權碼,用在不同應用裡:

 

出於安全考慮,這裡把授權碼隱掉了。

配置 sendmail 命令

有了賬號和授權碼就可以配置 sendmail 命令啦,下面開啟命令目錄內的 sendmail.ini 檔案,加入以下幾行:

 1 ; configuration for fake sendmail
 2 
 3 ; if this file doesn't exist, sendmail.exe will look for the settings in
 4 ; the registry, under HKLM\Software\Sendmail
 5 
 6 [sendmail]
 7 
 8 ; you must change mail.mydomain.com to your smtp server,
 9 ; or to IIS's "pickup" directory.  (generally C:\Inetpub\mailroot\Pickup)
10 ; emails delivered via IIS's pickup directory cause sendmail to
11 ; run quicker, but you won't get error messages back to the calling
12 ; application.
13 
14 smtp_server=smtp.qq.com
15 
16 ; smtp port (normally 25)
17 
18 smtp_port=25
19 
20 ; SMTPS (SSL) support
21 ;   auto = use SSL for port 465, otherwise try to use TLS
22 ;   ssl  = alway use SSL
23 ;   tls  = always use TLS
24 ;   none = never try to use SSL
25 
26 smtp_ssl=auto
27 
28 ; the default domain for this server will be read from the registry
29 ; this will be appended to email addresses when one isn't provided
30 ; if you want to override the value in the registry, uncomment and modify
31 
32 ;default_domain=mydomain.com
33 
34 ; log smtp errors to error.log (defaults to same directory as sendmail.exe)
35 ; uncomment to enable logging
36 
37 error_logfile=error.log
38 
39 ; create debug log as debug.log (defaults to same directory as sendmail.exe)
40 ; uncomment to enable debugging
41 
42 ;debug_logfile=debug.log
43 
44 ; if your smtp server requires authentication, modify the following two lines
45 
46 [email protected]
47 auth_password=*****************
48 
49 ; if your smtp server uses pop3 before smtp authentication, modify the 
50 ; following three lines.  do not enable unless it is required.
51 
52 pop3_server=
53 pop3_username=
54 pop3_password=
55 
56 ; force the sender to always be the following email address
57 ; this will only affect the "MAIL FROM" command, it won't modify 
58 ; the "From: " header of the message content
59 
60 force_sender=
61 
62 ; force the sender to always be the following email address
63 ; this will only affect the "RCTP TO" command, it won't modify 
64 ; the "To: " header of the message content
65 
66 force_recipient=
67 
68 ; sendmail will use your hostname and your default_domain in the ehlo/helo
69 ; smtp greeting.  you can manually set the ehlo/helo name if required
70 
71 hostname=

 

文中標黃的就是我們要加入的配置,這裡授權碼同樣被我隱掉了(哎呀,郵箱暴露了~)。命令配置好了以後,就可以在 shell 腳本里呼叫 sendmail 命令了

使用 sendmail 命令傳送郵件

終於可以回到我們之前提到的 send_mail 函數了,它有三個引數,分別是產品數量、金鑰數量和最小限制值:

 1 function send_email() 
 2 {
 3     pc=$1 # product count
 4     kc=$2 # key count
 5     lm=$3 # count limit
 6     from="[email protected]"
 7     # for multiple receiver, not work
 8     #to="yunh@******.com;anlj@******.com"
 9     # using an array of receivers
10     to=("yunh@******.com" "anlj@******.com" "yuyf-a@******.com" "duanxd@******.com" "zhangcj-c@******.com" "linc@******.com" "sunyd@******.com" "zhangb-l@******.com")
11     subject="gux server exception"
12     content="gux restful api exception: \nproducts: $pc \nkeys: $kc \n\nproducts count != keys count \nor products count < $lm !!\n\n\n"
13     mail="From: 'gux monitor' <$from>\nSubject: $subject\n\n$content"
14 
15     for var in ${to[@]};
16     do
17         mail=$(echo -e "To: <$var>\n$mail")
18     done
19     echo -e "$mail" >> mail.txt
20     echo -e "$mail" | sendmail -t
21 }

 

獲取各個引數 (line 3~5) 用於後續拼接郵件正文 (line 12),對於 sendmail 命令來說 (line 20) 使用 -t 引數後允許將所有引數通過一個格式化的文字來設定,這個格式類似這樣:

Subject: title
From: [email protected]
To: [email protected]
Cc: [email protected]

body...

 

由兩部分組成,郵件標題由 Subject(抬頭)、From(發件人)、To(收件人)、Cc(抄送)……組成,兩個空行之後是郵件正文。上面大段程式碼都是在設定這些內容 (line 6 ~ 13),注意為了減少對我 qq 賬號的關注,這裡對 From 域設定了別名 ‘gux monitor’,這樣收到郵件就比較直觀啦。下面是一次真實的報警郵件:

 

另外對於群發,不能簡單的在 To 域設定多個接收人,而是要分別對每個接收人進行一次單獨的 To 域設定(允許多個 To 域),這裡使用 shell 陣列對收件人進行了遍歷處理 (line 10,15 ~ 18),最後一次性發送 (line 20),下面是列印到 mail.txt 裡的郵件原文:

To: <zhangb-l@******.com>
To: <sunyd@******.com>
To: <linc@******.com>
To: <zhangcj-c@******.com>
To: <duanxd@******.com>
To: <yuyf-a@******.com>
To: <anlj@******.com>
To: <yunh@******.com>
From: 'gux monitor' <[email protected]>
Subject: gux server exception

gux restful api exception: 
products: 0 
keys: 0 

products count != keys count 
or products count < 100 !!

 

注意由於遍歷時是向郵件頭新增 To 域,整個收件人列表是呈倒序排列的。然後效果就是上面截圖的啦~

設定定時任務

最後就是把這個指令碼設定成定時執行的任務了,這塊可以參考之前寫過的一篇文章 《檢視部落格園積分與排名趨勢圖的工具 》,第 3 節。下面是經過一段時間後,指令碼輸出的日誌:

2020年07月 8日 16:00:01
product count : 103
keys count : 103
gux server ok
2020年07月 8日 16:55:15
product count : 103
keys count : 103
gux server ok
2020年07月 8日 17:00:01
product count : 103
keys count : 103
gux server ok
2020年07月 8日 18:00:01
product count : 103
keys count : 103
gux server ok
2020年07月 8日 19:00:01
product count : 103
keys count : 103
gux server ok

……
2020年07月13日 10:00:02 product count : 104 keys count : 104 gux server ok 2020年07月13日 11:00:01 product count : 104 keys count : 104 gux server ok 2020年07月13日 12:00:02 product count : 104 keys count : 104 gux server ok 2020年07月13日 13:00:02 product count : 104 keys count : 104 gux server ok 2020年07月13日 14:00:02 product count : 0 keys count : 0 products list too less, warning

輸出太長,中間有省略。可以觀察到 7.13 日 14:00 有一次報警 (不過後來證明是一次烏龍,汗~)

結語

後來查出問題的根因,居然是採集服務在和產品中心同步產品時(管理員登入的情況下),如果後者恰巧掛了,會導致前者同步不到資料,就會把所有產品開關重置掉!一個隱藏了 3+ years 的 bug 啊,教訓深刻。不過話說回來,不管程式碼怎麼 low,介面監控是不可少的。除了用來作介面監控,我還用 shell 指令碼給其它服務做簡單測試,例如驗證升級服務能否正常下發版本、驗證使用者中心能否正常登入等等,凡是通過 restful api 提供服務的,基本可以通過 curl + jq 搞定,甚至通過 tcp 長連線實現的訊息推送服務也可以用 shell 指令碼來驗證。不過這一系列的內容,因為涉及介面安全,我沒法提供 git 下載地址(壓根沒有相應的 git 庫),望大家理解,有需要的同學可以照貓畫虎,把裡面的介面換成自己能訪問的,來動手驗證一下。

參考

[1]. 在windows下配置sendmail伺服器

[2]. Using Sendmail on Windows

[3]. Linux簡單配置SendMail傳送郵件

[4]. linux shell 傳送email 郵件

[5]. 不可或缺的 sendEmail

[6]. 配置mail命令的IMAP和SMTP,接收郵件和傳送郵件

[7]. shell 發郵件命令之 sendmail

[8]. jq : Linux下json的命令列工具

[9]. 使用jq工具在Shell命令列處理JSON資料

[10]. 命令列 JSON 處理工具 jq 的使用介紹

[11]. shell指令碼處理JSON資料工具jq

[12]. HowTo: Install jq

[13]. https://github.com/stedolan/jq