后記
本文的主要邏輯代碼已提交PR并合并到官方代碼中,不過獲取變量改為FALCON_ENDPOINT。因此我們?cè)诰€上環(huán)境中,仍然自行維護(hù)了下文中的補(bǔ)丁,以適應(yīng)自身的業(yè)務(wù)需求。
背景
open-falcon 監(jiān)控系統(tǒng)里面有一個(gè)重要的概念為 endpoint,可以理解為監(jiān)控項(xiàng)目在主機(jī)標(biāo)識(shí)。
默認(rèn)將操作系統(tǒng)的主機(jī)名上報(bào)為 endpoint ,同時(shí)可以修改 agent 的 cfg.json 的 hostname 屬性來自定義主機(jī)標(biāo)識(shí)。
服務(wù)器規(guī)模大的時(shí)候,主機(jī)名命名趨向與業(yè)務(wù)無關(guān)、IP地址無關(guān),常見以各種隨機(jī)算法命名,也就是從主機(jī)名中很難看出來這臺(tái)服務(wù)器是什么業(yè)務(wù),也不一定能主機(jī)名中看出其IP地址的特征。
自定義主機(jī)名
我們的做法是,主機(jī)名隨機(jī)命名,監(jiān)控上報(bào)時(shí)以自定義數(shù)據(jù)來代替主機(jī)名,自定義數(shù)據(jù)中,有業(yè)務(wù)類型、業(yè)務(wù)屬性、IP 地址等信息,僅僅通過自定義主機(jī)名即可判斷告警的影響范圍。
自定義屬性舉例: basic_nginx_1.2.3.4, cache_redis_web_5.6.7.8, java_pay_11.22.33.44.
我們將自定義主機(jī)名命名為 ENDPOINT 環(huán)境變量。
自定義主機(jī)名的實(shí)現(xiàn)
在每個(gè)主機(jī)增加 /etc/endpoint.env 文件,示例內(nèi)容為:
ENDPOINT=basic_nginx_1.2.3.4
創(chuàng)建 /etc/profile.d/91-env.sh 文件,解析 /etc/endpoint.env 文件,輸出環(huán)境變量 ENDPOINT,并覆蓋 shell 的 PS1,文件內(nèi)容為:
#!/bin/bash
# /etc/profile.d/91-env.sh
export ENDPOINT=$(test -f /etc/endpoint.env && cat /etc/endpoint.env | cut -d'=' -f 2 || hostname -s)
export PS1='[\u@${ENDPOINT} \W]\$'
同時(shí),監(jiān)控系統(tǒng) zabbix、open-falcon 上報(bào)的主機(jī)名也不是默認(rèn)的操作系統(tǒng)的主機(jī)名,而是自定義的ENDPOINT 環(huán)境變量的值 。
1.0 時(shí)代:修改 open-falcon 客戶端配置
在初始化每臺(tái)主機(jī)時(shí),自動(dòng)將自定義主機(jī)名填入到 falcon-agent 的配置文件 cfg.json 中的 hostname 屬性。 這樣操作以后,每臺(tái)主機(jī)的 falcon-agent 的 cfg.json 配置文件的 hostname 屬性都不一樣,其他配置均相同。
PS: zabbix 修改 /etc/zabbix/zabbix_agentd.conf 的 Hostname 的屬性。
思考改進(jìn)
以上修改配置文件的方式,將每個(gè) agent 的配置文件變成了“有狀態(tài)”的方式,始終覺得不夠優(yōu)雅,增加了維護(hù)成本。
改進(jìn)思路:
- 修改啟動(dòng)腳本,啟動(dòng)時(shí)獲取環(huán)境變量 ENDPOINT,通過 jq 命令行修改 cfg.json 。
- 修改 agent 代碼,獲取環(huán)境變量 ENDPOINT 來代替獲取系統(tǒng)主機(jī)名。
分析 falcon-agent 關(guān)于主機(jī)名獲取的邏輯代碼,修改代碼相對(duì)容易,后期維護(hù)成本也比較低,我們采用了第二種方式。(在此YY一下,如果這種方式的處理能被官方接受,代碼合并到官方就更沒有維護(hù)成本了。)
處理代碼
主機(jī)名獲取的優(yōu)先級(jí)為:
- cfg.json 中的 hostname 屬性
- 環(huán)境變量 ENDPOINT
- 文件 /etc/endpoint.env 中的 ENDPOINT 的值 (作為取不到環(huán)境變量的 fallback 方法)
- 操作系統(tǒng)的主機(jī)名
diff --git a/modules/agent/g/cfg.go b/modules/agent/g/cfg.go
index c3e0181..6e4765a 100644
--- a/modules/agent/g/cfg.go
+++ b/modules/agent/g/cfg.go
@@ -2,8 +2,10 @@ package g
import (
"encoding/json"
+ "io/ioutil"
"log"
"os"
+ "strings"
"sync"
"github.com/toolkits/file"
@@ -72,6 +74,29 @@ func Hostname() (string, error) {
return hostname, nil
}
+ if os.Getenv("ENDPOINT") != "" {
+ hostname = os.Getenv("ENDPOINT")
+ return hostname, nil
+ }
+
+ // parse /etc/endpoint.env ( ENDPOINT=xxx_xxx_1.2.3.4 )
+ filePath := "/etc/endpoint.env"
+ if _, err := os.Stat(filePath); err == nil {
+ data, _ := ioutil.ReadFile(filePath)
+ str := string(data)
+ if !strings.ContainsAny(str, "ENDPOINT") {
+ log.Panic("ERROR: /etc/endpoint.env missing ENDPOINT")
+ }
+ if !strings.ContainsAny(str, "=") {
+ log.Panic("ERROR: /etc/endpoint.env missing =")
+ }
+ str = strings.Trim((strings.SplitAfter(str, "ENDPOINT"))[1], " ")
+ hostname = strings.Trim((strings.SplitAfter(str, "="))[1], " ")
+ if len(hostname) > 1 {
+ return hostname, nil
+ }
+ }
+
if os.Getenv("FALCON_ENDPOINT") != "" {
hostname = os.Getenv("FALCON_ENDPOINT")
return hostname, nil
falcon-agent 的 Systemd 啟動(dòng)腳本
啟動(dòng)腳本會(huì)將 ENDPOINT 環(huán)境變量傳遞給 falcon-agent 程序
/etc/systemd/system/falcon-agent.service
[Unit]
Description=The falcon agent
After=network.target
[Service]
LimitNOFILE=1048576
Restart=always
RestartSec=30
Type=simple
EnvironmentFile=-/etc/endpoint.env
Workdir=/app/monitor/falcon
ExecStartPre=/app/monitor/falcon/falcon-agent -c /app/monitor/falcon/cfg.json -check
ExecStart=/app/monitor/falcon/falcon-agent -c /app/monitor/falcon/cfg.json
TimeoutStopSec=5
PrivateTmp=true
User=nobody
[Install]
WantedBy=multi-user.target
說明: master 分支的代碼已經(jīng)修復(fù)了 agent check 啟動(dòng)失敗的問題。
falcon-agent 的 init 啟動(dòng)腳本
啟動(dòng)腳本會(huì)將 ENDPOINT 環(huán)境變量傳遞給 falcon-agent 程序
#!/bin/bash
# chkconfig: 2345 90 10
# description: falcon-agent
export PATH=/usr/java/latest/bin:/sbin:/bin:/usr/sbin:/usr/bin
WORKDIR="/app/monitor/falcon"
EXEC_CMD='/app/monitor/falcon/control'
if [[ ! -f ${EXEC_CMD} ]];then
echo "$EXEC_CMD not found"
exit 1
fi
RETVAL=$?
start_pre(){
source /etc/profile
test -f /etc/endpoint.env && export $( cat /etc/endpoint.env )
cd $WORKDIR
}
case "$1" in
start|stop|restart|status)
start_pre
su - nobody -s /bin/bash -c "$EXEC_CMD $1"
;;
*)
echo $"Usage: $0 {start|stop|restart|status}"
exit 1
;;
esac
exit $RETVAL
愉快的玩耍
修改后的 falcon-agent 程序和配置文件,在我們幾百臺(tái)服務(wù)器上都是一樣,通過灰度上線部分節(jié)點(diǎn)運(yùn)行無異常后,已通過自動(dòng)化發(fā)布程序全部更新上線。