1.General description
我們知道,使用日志系統(tǒng)是為了使系統(tǒng)變得更健壯,能夠應(yīng)對(duì)各種錯(cuò)誤并能從錯(cuò)誤中較快地恢復(fù)。一個(gè)大型的分布式系統(tǒng)生成的日志數(shù)量是巨大的,所以需要一個(gè)有效的工具對(duì)其進(jìn)行管理。Scribe就是這樣一個(gè)日志收集服務(wù)器,使用它可以對(duì)大型的系統(tǒng)進(jìn)行監(jiān)控。它是Facebook的一個(gè)開源組件,使用的是Facebook另一個(gè)框架—Thrift。Thrift 在我的理解就是一個(gè)高效的跨語言 rpc 框架,所以它可以支持通過 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk, and OCaml 給服務(wù)器匯報(bào)。
總的來說,Scribe由兩部分組成:central Scribe server 和 local Scribe server。在分布式系統(tǒng)中,每個(gè)結(jié)點(diǎn)都會(huì)有一個(gè)local Scribe server運(yùn)行在上面,收集此結(jié)點(diǎn)的日志信息,并將其發(fā)送給central Scribe server。這里的central和local是相對(duì)的,是針對(duì)一個(gè)組內(nèi)的。
2. Download and Install
Scribe并不大,但其安裝是一個(gè)非常繁瑣的過程。通過我不斷的努力,最終還是沒有安裝成功(源代的example不能正常運(yùn)行)。雖說沒有產(chǎn)出的勞動(dòng)是徒勞的,但這也不是絕對(duì)的,至少對(duì)其具體的安裝過程倒是耳熟能詳了。
Scribe運(yùn)行于Linux系統(tǒng)下,試驗(yàn)中我所使用的是Ubuntu 9.10,通過虛擬機(jī)安裝的。Scribe安裝前需要很多Environment Dependency,具體如下所示:

(1)安裝ruby:
install: sudo apt-get install ruby-full build-essential
test: ruby -v 顯示 版本 號(hào)
which ruby 顯示安裝的位置
新建一個(gè)test.rb文件,里面輸入如下內(nèi)容:
#!/usr/bin/env ruby
puts "hello world!"
然后進(jìn)入該目錄,輸入如下命令:./test.rb。如果ruby安裝成功則會(huì)
輸出hello world!
(2)安裝python:
一般來講,Ubuntu系統(tǒng)里已經(jīng)安裝了python。查看是否已經(jīng)安裝,使用如下
命令:python 顯示安裝的版本號(hào)
which python 顯示安裝的位置
系統(tǒng)自帶的,其安裝目錄是在/usr/bin下。如果是自安裝的,則會(huì)在
/usr/local/bin下。就如接下來要安裝的Thrift和Scribe。
(3)安裝libevent:
下載http://www./linux/accidence/20100218/22428.html
tar xzfv libevent-1.4.8-stable.tar.gz
cd libevent-1.4.8-stable
./configure
make
make install
(4)安裝剩下的dependency:
sudo apt-get install libboost-dev=1.38.1 flex bison libtool automake autoconf pkg-
config && wget -O thrift.tgz
"http://gitweb./?p=thrift.git;a=snapshot;h=HEAD;sf=tgz"
&& tar -xzf thrift.tgz && cd thrift &&./bootstrap.sh && ./configure && make
&& sudo make install
&& cd contrib/fb303/ && ./bootstrap.sh && sudo make && sudo make install
實(shí)際上是將多條命令合為一條而已。
至此為止,所有的依賴已經(jīng)安裝完成。
(5 )安裝Scribe
首先下載Scribe,這里我所使用的是Scribe2.2。接下來的安裝就非常簡單了:
./bootstrap.sh
make
make install
至此為止,Scribe就成功安裝上了。接下來就可以跑Example內(nèi)的例子了。
3. Example:
網(wǎng)上關(guān)于Scribe的資料較少,所以閱讀源代碼是一個(gè)很有效的途徑。在此之前先運(yùn)行Example內(nèi)的例子。
源代碼里所給的example很簡單,但大體上了模擬了其運(yùn)行的過程,分三個(gè)部分。可參考里面的README文件:
Configurarion(配置)、Running Scribe Server(運(yùn)行服務(wù)器)、Logging messages(記錄日志)
3.1 配置:
Scribe Server是通過配置文件啟動(dòng)的。

null:丟棄所有消息
multi:給所有multi類型的store傳遞消息
file:將消息寫入文件
thriftfile:類似于file,但寫入的文件類型為thrift TfileTransport文件
network:將消息轉(zhuǎn)發(fā)給另外一個(gè)scribe server
buffer:包含兩個(gè)子store(主、次),在主store工作時(shí),直接使用主store記錄日志,只
有當(dāng)主store不可用時(shí),才使用次store記錄。而且一旦主store恢復(fù)工作,次
stroe記錄的日志將轉(zhuǎn)移到主store。
bucket:包含一系列的其他類型的stroe,具體使用哪個(gè)是由所定義的Hash函數(shù)決定的
3.2 運(yùn)行Scribe Server:

1)啟動(dòng):進(jìn)入到Scribe源碼中的根目錄,執(zhí)行如下命令
scribed examples/example1.conf
如果scribe安裝成功的話,則會(huì)出現(xiàn)如下提示信息:

2) 查看狀態(tài):在另外一個(gè)終端執(zhí)行如下命令:
./scribe_ctrl status
ALIVE
3)停止:開啟另外一個(gè)終端,執(zhí)行如下命令:
./scribe_ctrl stop
在另外一個(gè)終端會(huì)看到狀態(tài)信息:
“STATUS: STOPPING"
3.3 記錄日志:
1)Example1:向已經(jīng)啟動(dòng)的Server發(fā)送消息,驗(yàn)證是否被記錄下來。
Server啟動(dòng)后,開啟另外一個(gè)終端向Server發(fā)送信息:使用scribe_cat
mkdir /tmp/scribetest
echo "hello world"| ./scribe_cat test
這時(shí)你很可能會(huì)出現(xiàn)如下錯(cuò)誤提示:

也就是說python導(dǎo)入模塊scribe失敗,但我們打開/usr/lib/python2.6/site-packages,發(fā)現(xiàn)里面是有scribe的模塊的,所以很可能是PYTHONPATH沒有配置正確。使用如下命令進(jìn)行配置:
進(jìn)入到/etc目錄,然后輸入命令gedit profile(profile文件為系統(tǒng)的每個(gè)用戶設(shè)置環(huán)境信息,當(dāng)用戶第一次登錄時(shí),該文件被執(zhí)行),在此文件中添加如下內(nèi)容:
export PYTHONPATH= ”/usr/lib/python2.6/site-packages”
然后注銷重新登錄。
輸入echo $PYTHONPATH命令進(jìn)行測試。
再次執(zhí)行echo命令,查看結(jié)果:
cat /tmp/scribetest/test/test_current
或者直接打開查看。—hello world!
2) Example2:啟動(dòng)中心服務(wù)器和客戶端服務(wù)器,然后開啟一個(gè)終端并輸入三條命令,并查看結(jié)果:
mkdir /tmp/scribetest2
scribed examples/example2central.conf
scribed examples/example2client.conf
echo "test message" | ./scribe_cat -h localhost:1464 test2
echo "this message will be ignored" | ./scribe_cat -h localhost:1464 ignore_me
echo "123:this message will be bucketed" | ./scribe_cat -h localhost:1464 bucket_me
查看結(jié)果:
cat /tmp/scribetest/test2/test2_current
cat /tmp/scribetest/bucket*/bucket_me_current
./scribe_ctrl status 1463
./scribe_ctrl status 1464
./scribe_ctrl counters 1463 #查看中心服務(wù)器的統(tǒng)計(jì)數(shù)據(jù)
./scribe_ctrl counters 1464 #查看客戶端服務(wù)器的統(tǒng)計(jì)數(shù)據(jù)

當(dāng)客戶端服務(wù)器講收到的信息發(fā)送給中心服務(wù)器后,會(huì)刪除本地的存儲(chǔ)。
結(jié)果顯示:客戶端收到三條消息,發(fā)送了三條消息;
服務(wù)器端收到三條消息,忽略了一條消息。
3) Example3:如同Example2啟動(dòng)中心服務(wù)器和客戶端服務(wù)器,但本例測試的是在中心服務(wù)器突然down掉的情況下,客戶端服務(wù)器的緩沖存儲(chǔ)功能。
echo "test message 1" | ./scribe_cat -h localhost:1464 test3 #發(fā)送消息1
cat /tmp/scribetest/test3/test3_current #結(jié)果:test message 1
./scribe_ctrl stop 1463 #down掉中心服務(wù)器
./scribe_ctrl status 1463 #結(jié)果:Failed to get status
echo "test message 2" | ./scribe_cat -h localhost:1464 test3 #發(fā)送消息2
./scribe_ctrl status 1464 #結(jié)果:WARNING - Failed to connect
echo "test message 3" | ./scribe_cat -h localhost:1464 test3 #發(fā)送消息3
scribed examples/example2central.conf #重新啟動(dòng)中心服務(wù)器
./scribe_ctrl status 1463 #結(jié)果:ALIVE
./scribe_ctrl status 1464 #結(jié)果:ALIVE
cat /tmp/scribetest/test3/test3_current
#結(jié)果:
test message 1
test message 2
test message 3
全部正常接收
4.Source Analyse:
4.1 整體類圖:

4.2 store 和 storeConf

4.3 scribeHandler和storeQueue

4.4 配置文件的解析
在server啟動(dòng)的過程中,會(huì)調(diào)用StoreConf中的parseConfig函數(shù),具體實(shí)現(xiàn)是先調(diào)用readConfig函數(shù)將配置文件的內(nèi)容逐行讀入到一個(gè)隊(duì)列中,然后再調(diào)用parseStore函數(shù)從隊(duì)列中逐行解析,并將解析的內(nèi)容存入StoreConf中的兩個(gè)Map變量: values和stores。
|
類型
|
解釋
|
values
|
std::map<std::string, std::string>
|
每個(gè)store里的<參數(shù),值>對(duì)
|
stores
|
std::map<std::string, pStoreConf>
|
存放所有的store
|
4.5 Server的啟動(dòng)過程的流程圖:
Main函數(shù)是入口點(diǎn),端口號(hào)port和配置文件config_file作為聲明一個(gè)server實(shí)例:
new scribeHandler(port, config_file);然后執(zhí)行一系列的初始化工作,初始化的流程圖如下:

4.6 Log過程的流程圖:
客戶端調(diào)用Log(messages)函數(shù)發(fā)送消息,通過thrift框架的實(shí)現(xiàn),遠(yuǎn)程方法
scribeHandler:: Log(const vector<LogEntry>& messages)函數(shù)被調(diào)用,過程如下:

Reference:
http://github.com/facebook/scribe
http://hi.baidu.com/you5a_com/blog/item/ed62ee3fd1228d0bbba167d5.html
http://snippets./2009/07/29/howto-install-scribe-the-facebook-log-system-on-debian/
http:///product-scribe-facebooks-scalable-logging-system
http:///posts/facebook-scribe-server-documentation-and-tutorials#comments