- 需求介紹
- 原理說明
- 模塊添加
需求介紹
我先講一下我的需求姨蟋,估計我講完了机断,大家也就明白為什么要有這么一個模塊了,然后后面我再介紹如何給自己的模塊中添加它舰罚。
我們要在客戶端監(jiān)控一條日志信息微谓,但是由于客戶端節(jié)點非常多森篷,所以不好實現(xiàn)。有人可能已經(jīng)想到了豺型,在每個節(jié)點寫個腳本去監(jiān)控該日志仲智,如果出現(xiàn)了就把該日志插入到頭節(jié)點的某個文件里面,然后你再監(jiān)控這個文件且把這個文件的信息傳送給存儲節(jié)點不就可以了么姻氨。但是這樣做有一下缺點:
1.客戶的計算節(jié)點部署額外的監(jiān)控服務(wù)钓辆,增加了部署的復(fù)雜度,且有的客戶不太樂意給他們機器裝東西肴焊。
2.多個節(jié)點往一個節(jié)點的某個文件里面放日志前联,那我們就要考慮多個客戶端操作一個文件時的數(shù)據(jù)完整性,和時間序列是不是和我們需要的一樣抖韩,考慮的方面比較多蛀恩。
原理說明
綜上所述LogClient就派上用場了疫铜,我們發(fā)現(xiàn)在/var/log/ceph/下面有一個以集群名稱命名的一個日志文件茂浮,利用它可以監(jiān)控集群的健康狀態(tài),pgmap狀態(tài),甚至可以看到哪些操作slow之類的席揽。這里面的日志是monitor經(jīng)過paxos協(xié)議商量后發(fā)給了各個存儲節(jié)點上面的顽馋。大致流程如下圖所示:
我們利用它就可以完美解決我們所需要的功能,只需要在客戶端的代碼中添加這個模塊即可幌羞。它主要在下面兩個文件里面實現(xiàn)
src/common/LogClient.cc
src/common/LogClient.h
主要原理就是用LogClient先創(chuàng)建一個通往monitor的channel寸谜。假如我們的channel是clog,當你調(diào)用clog->warn這個函數(shù)的時候把你想要打印的日志暫時放到log_queue里面,它隨后會被MonClient的tick線程讀出來属桦,并且發(fā)送到monitor端熊痴,monitor收到之后和其他monitor商量完畢之后就會把該日志分發(fā)給所有的存儲節(jié)點。當然LogChannel對外的接口有
void debug(std::stringstream &s) {
do_log(CLOG_DEBUG, s);
}
void info(std::stringstream &s) {
do_log(CLOG_INFO, s);
}
void warn(std::stringstream &s) {
do_log(CLOG_WARN, s);
}
void error(std::stringstream &s) {
do_log(CLOG_ERROR, s);
}
void sec(std::stringstream &s) {
do_log(CLOG_SEC, s);
}
模塊添加
我以我在ceph client 模塊添加的為例
- Client.h
a.添加頭文件 #include "common/LogClient.h”
b.添加類成員變量:LogClient log_client; LogChannelRef clog;
- Client.cc
a.在Client的構(gòu)造函數(shù)里面初始化上面的兩個成員變量
b.創(chuàng)建通道
c.在Client::init里面設(shè)置monclient的log_clientclog = log_client.create_channel(); clog->set_log_to_monitors(true);
- 執(zhí)行完上面兩步就可以使用了,例如:
stringstream ss; ss << "ivan test ......" ; clog->warn() << ss.str();
歡迎大家提出寶貴意見聂宾!