個人開發者的伺服器日誌收集
來自專欄為了不折騰而去折騰的那些事
個人開發者的伺服器日誌收集
互聯網時代,數據的價值被無限強調,對於開發人員來說,日誌並不陌生,但是不知道有多少人有嘗試過系統化的收集和處理日誌,本文嘗試從伺服器日誌收集建設開始講起,給出一套相對簡單、經濟的日誌採集方案。
這幾年各家雲主機輪番價格戰之後,我們的雲主機越來越多,網站也越來越多,除了在雲主機管理面板或者通過API進行資源查詢之外,有什麼更好的方式可以儘可能在不大量編碼,把不同雲主機廠商的日誌收歸一處么?
當然,現在的公司一般都配置了數據團隊,會使用ELK技術棧或者SPARK技術棧去進行數據的ETL,但是對於個人來說,這些都過於笨重了,即使因為容器技術蓬勃發展,幾個配置文件一兩條命令就能夠把服務啟動起來,但是有2個小問題:
- ELK本身對維護和對硬體資源要求不低。
- 周邊對接的系統,對維護和資源的要求不低。
本著節約(窮)的精神,本文使用家裡的寬頻和一台閑置小主機進行日誌的採集收歸,相關資源配置,我在Home-Network-Note有提及,一台ATOM群暉兼容機即可,還能偷懶不折騰界面。
數據橋樑
公網和家裡的機器想愉快進行日誌採集,有這麼幾個方式:
- 家庭寬頻有固定IP,暴露埠到最外層路由,公網機器和家庭機器公網IP到公網IP。
- 前幾年還有這類寬頻,現在已經基本絕跡,商用寬頻太貴,而且需要公司進行申請。
- 家庭寬頻有浮動IP,使用DDNS將家庭IP綁定到一個域名上,隨著IP更新,域名指向更新。
- 如果動態域名指向的最外層設備存在安全隱患,將會危害整個內網,以及需要考慮域名解析被劫持的問題,域名解析存在生效時間、域名解析服務商選擇也比較麻煩。
- 使用被動連接的方式,將家庭內部應用流量轉發到一個固定IP的公網機器,充當數據橋樑,雲主機到雲主機,然後再從這台橋樑的機器轉發到內網。
- 本文採取這種方案。
配置日誌採集服務端
我們先進行服務端配置。
在群暉Web管理界面中找到套件中心
,選擇日誌中心
進行安裝,軟體安裝之後。
我們可以ssh到機器上,通過ps
進行進程查看,我們可以看到:
soulteary@Lemon:/$ ps -ef | grep logsystem 4325 1 0 01:27 ? 00:03:09 /usr/bin/syslog-ng -F --worker-threads=4 -u system -g logroot 4747 1 0 01:27 ? 00:00:02 /usr/syno/sbin/synologaccd -froot 4881 1 0 01:27 ? 00:00:00 /usr/syno/bin/synologrotatedsoultea+ 5741 5722 0 12:06 pts/17 00:00:00 grep --color=auto logroot 11594 1 0 01:28 ? 00:00:18 /var/packages/LogCenter/target/usr/bin/syslog-ng --cfgfile=/var/packages/LogCenter/target/etc/syslog-ng/syslog-ng.conf -F --worker-threads=4
群暉的日誌系統是使用 syslog-ng
這個軟體來做的服務端,簡單掃了一眼這個開源項目的倉庫,了解到這個工具有一個將日誌進行資料庫化落地的能力,支持 RFC3164
和 RFC5424
兩種風格的日誌消息。
簡單進行一番配置,選擇好文件資料庫存放位置,歸檔配置(synologrotated),新建一個接收日誌的配置(syslog-ng)。
下面是我的配置:
名稱: CloudServer日誌格式: BSD格式規則參數: 不填傳輸協議: UDP埠: 514SSL安全連接:不勾選
為了測試這個服務是否正常,我寫了一個簡單的腳本來進行驗證:
const os = require(os);const syslog = require(syslog-client);const reportHost = 10.9.8.180;const port = 514;const mode = UDP;const facility = syslog.Facility.User;const appName = Test;const syslogHostname = os.hostname();const severity = syslog.Severity.Informational;const transport = (mode === UDP ? syslog.Transport.Udp : syslog.Transport.Tcp);const testTimes = 100000;const options = {syslogHostname, transport, port, facility, appName, severity};const logger = syslog.createClient(reportHost, options);for (let i = 0; i < 10; i++) { setTimeout(() => { for (let i = 0; i < testTimes / 10; i++) { logger.log(example message); } }, 10);}logger.on(close, () => { console.log(socket closed);});logger.on(error, (error) => { console.error(error);});
執行腳本,嘗試在短時間內快速發送10萬個日誌,看到日誌中心有實時的消息進來了,但是數量有很大的出入。
將腳本中定義的發送方式改為TCP,同時修改接受服務端的模式,再次嘗試發送。
可以看到10w個日誌一條不差的都收集過來了。
接下來把內網的日誌服務通過一台公網伺服器暴露出去就可以對外提供服務了。
這裡採取frp的方式進行,之前的文章里有提過這個方式,不過這次要轉發的不是HTTP/HTTPS協議的內容,而是TCP。
前文提過數據橋樑的事情,內網伺服器雖然是日誌採集服務端,但是在數據傳遞上面來講,它是數據橋樑的消費者,所以要執行frp客戶端。
下面直接給出一份客戶端配置參考:
[common]server_addr = 你的公網伺服器地址server_port = 公網frp服務埠token = 連接tokendns_server = DNS伺服器地址,這裡填寫內網DNS伺服器地址[syslog]type = tcplocal_ip = 0.0.0.0local_port = 514remote_port = 公網伺服器服務埠
使用方式同之前的文章中提到的,在服務端執行服務端程序並指定配置文件,客戶端同理:
frpc -c frpc.ini
(群暉進程守護部分稍後補上。)
接下來我們來配置日誌採集客戶端。
日誌採集客戶端
在搭建日誌採集的客戶端,數據提供方之前,我們需要把網路先聯通,把之前提到的數據橋樑先搭建起來。
同樣給出frp的服務端配置:
[common]bind_port = 公網frp服務埠token = 連接tokendashboard_addr = 0.0.0.0dashboard_port = 公網管理埠# dashboard user and passwd for basic auth protect, if not set, both default value is admindashboard_user = 管理用戶賬號dashboard_pwd = 管理用戶密碼
啟動服務,可以看到frp客戶端和服務端顯示已經連接成功,出於信息敏感就不貼日誌輸出了。
frpc -c frpc.ini
一般來說,伺服器的運行是很穩定的,但是伺服器有可能因為提供商的種種原因而升級或者遷移而重啟、進程可能因為系統資源不足而被幹掉,為了保障服務的穩定,我們使用進行管理工具來進一步加固這個服務。
這裡推薦使用 supervisor
進行進程守護,先進行安裝,並進行:
sudo apt install supervisor -y
在 /etc/supervisor/conf.d
創建一個frp的配置文件,:
[program:syslog-frp]user=rootcommand=/data/syslog/frps -c /data/syslog/frps.iniautostart=truestartsecs=3startretries=100autorestart=truestderr_logfile=/data/syslog/error.logstderr_logfile_maxbytes=50MBstderr_logfile_backups=10stdout_logfile=/data/syslog/access.logstdout_logfile_maxbytes=50MBstdout_logfile_backups=10
重啟 supervisor
,載入剛剛創建的配置,然後查看配置是否被正確的載入。
sudo systemctl restart supervisorsudo supervisorctl status
可以看到配置文件被正確的載入,frp進程得到了守護。
syslog-frp RUNNING pid 3781, uptime 1:09:34
好了,那麼接著來配置日誌上報服務。
剛才提到服務端支持兩種協議,所以我們不必使用同樣的軟體,只要軟體支持這兩種協議即可。
這裡推薦使用rsyslog進行日誌的採集傳輸,Linux系統中一般都會默認安裝,如果沒有安裝可以使用下面的命令進行安裝:
sudo apt-get install rsyslog -y
在使用之前,需要先檢查一下版本,新老版本支持的配置有一些不同。
rsyslogd -versionrsyslogd 8.16.0, compiled with: PLATFORM: x86_64-pc-linux-gnu PLATFORM (lsb_release -d): FEATURE_REGEXP: Yes GSSAPI Kerberos 5 support: Yes FEATURE_DEBUG (debug build, slow code): No 32bit Atomic operations supported: Yes 64bit Atomic operations supported: Yes memory allocator: system default Runtime Instrumentation (slow code): No uuid support: Yes Number of Bits in RainerScript integers: 64See http://www.rsyslog.com for more information.
如果你的軟體大版本也是8.x的話,可以參考下面的配置方法:
先修改位於 /etc/rsyslog.conf
的配置文件。
# 添加或者去掉配置文件中被注釋的內容module(load="imtcp")input(type="imtcp" port="514")# 在文件底部添加使用TCP模式轉發日誌數據*.* @@公網伺服器地址:公網服務端埠
重啟服務,讓本次修改生效。
service rsyslog restart
為了驗證服務是否配置正確,輸入測試語句:
logger -p local0.info "Hello World"
可以看到客戶端已經可以成功接收來自雲伺服器的日誌消息了。
之前提到我有使用traefik來提供服務發現,作為應用網關。
當時把輸出日誌保存成了文件,對於這類日誌該如何處理呢,再次修改位於 /etc/rsyslog.conf
的配置文件。
# 在配置頂部添加讀取文件的模塊,配置更新間隔為1smodule(load="imfile" PollingInterval="1")
創建一個 /etc/rsyslog.d/30-traefik.conf
配置文件,內容如下:
# proc log$InputFileName /data/traefik/logs/access.log$InputFileTag traefik-proc:$InputFileStateFile stat-traefik-proc$InputFileSeverity debug$InputFileFaility local6$InputFilePollInterval 1$InputRunFileMonitor# access log$InputFileName /data/traefik/logs/access.log$InputFileTag traefik:$InputFileSeverity debug$InputFileFaility local6$InputFilePollInterval 1$InputRunFileMonitor
再次重啟進程之後,我們發現客戶端已經可以正確接受這些消息了。
額外要提的一些事
對所有的機器和應用進行類似的配置之後,你的日誌採集服務就搭設完畢了。
在服務運行一定時間之後,我們就可以嘗試進行簡單的ETL數據操作了。
另外,日誌文件雖然不見得有「業務文件」和「業務數據」重要,但是備份也是必須的。
建議使用Raid或者Rsync之類的方案將數據進行合理備份,避免後續想進行分析的時候缺少數據。
最後
先寫到這裡,後面有機會聊聊日誌文件的分析整理,以及採集服務的安全加固。
如果你對本篇文章的內容有疑問或者想討論,歡迎聯繫我,我的聯繫方式聰明的你應該找的到吧?
--EOF
推薦閱讀:
※一行代碼導致幣價歸零!BEC美密智能合約漏洞復盤
※無需從 App Store 下架,App 便能轉至其他開發者賬號→詳細圖解&附蘋果官方 Q&A
※Arction控制項開發商十年之旅回顧
※唐才林:DAP為開發者供性價比最優的移動變現方案
※新品首發,LeanMug 2.0 金屬容器免費申請使用