Cat是大眾點(diǎn)評用于對服務(wù)端應(yīng)用進(jìn)行業(yè)務(wù)監(jiān)控的一整套系統(tǒng)谋旦,具體可以直接參考他們的github有非常詳細(xì)的介紹,這里只是單獨(dú)將Node服務(wù)接入Cat的流程整理出來,并介紹了為Egg編寫的客戶端插件egg-cat-client匙监。
系統(tǒng)支持
OSX (>=10.13)
Alpine linux
CentOS 6
CentOS 7
Ubuntu 14.04 LTS
Ubuntu 16.04 LTS
Ubuntu 18.04 LTS
node版本
node v8+
準(zhǔn)備工作
下載Cat代碼到本地
git clone git@github.com:dianping/cat.git
編譯libcatclient動(dòng)態(tài)庫
查看lib/node.js/binding.gyp
的c庫依賴新荤,發(fā)現(xiàn)node包的安裝需要依賴一個(gè)lcatclient
的動(dòng)態(tài)鏈接庫揽趾,這里需要先編譯出這個(gè)庫并加載到系統(tǒng)中。
{
"targets": [
{
"target_name": "nodecat",
"sources": [
"src/nodecat.cc",
],
"include_dirs": [
"include"
],
"libraries": [
"-lcatclient"
]
}
]
}
- 需要安裝一個(gè)支持C99或者C編譯器苛骨,Mac直接安裝Xcode就可以篱瞎。
- 需要安裝cmake和make,這個(gè)用來構(gòu)建動(dòng)態(tài)鏈接庫的工具痒芝。
- 進(jìn)入
lib/c
目錄并執(zhí)行下面的命令:
1. mkdir -p cmake
2. cd cmake
3. cmake ..
4. make -j
5. make install
上面??執(zhí)行完成后俐筋,libcatclient.so (或Mac下 libcatclient.dylib)
已經(jīng)安裝到LD_LIBRARY_PATH
目錄下,大多數(shù)情況下是 /usr/local/lib
安裝node cat client
npm i @dp-cat/client
cat環(huán)境配置
cat的client所鏈接的cat server并不是在代碼里面進(jìn)行設(shè)置的严衬,而是cat的默認(rèn)系統(tǒng)目錄/data
進(jìn)行配置的:
- 創(chuàng)建
/data/appdatas/cat
目錄并保證讀寫權(quán)限澄者。 - 創(chuàng)建
/data/applogs/cat
目錄并保證讀寫權(quán)限。 - 創(chuàng)建
/data/appdatas/cat/client.xml
配置文件:
<?xml version="1.0" encoding="utf-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:noNamespaceSchemaLocation="config.xsd">
<servers>
<server ip="<cat server ip address>" port="2280" http-port="8080" />
</servers>
</config>
根據(jù)上面??的配置文件请琳,配置cat client所連接的server粱挡。這樣所有的準(zhǔn)備工作就完成了,可以在業(yè)務(wù)代碼中直接使用了俄精。
cat使用
cat中已經(jīng)包含了使用的examples,可以直接查看:
Transaction
var cat = require('@dp-cat/client')
cat.init({
appkey: 'nodecat'
})
cat = new cat.Cat(true)
let t = cat.newTransaction('foo', 'bar')
t.addData("key", "val")
t.addData("context")
t.setStatus(cat.STATUS.SUCCESS)
setTimeout(() => t.complete(), 3000)
Event
var cat = require('@dp-cat/client')
cat.init({
appkey: 'nodecat'
})
// Log a event with success status and empty data.
cat.logEvent("Event", "E1")
// The 3rd parameter (status) is optional, default is "0".
// It can be any of string value.
// The event will be treated as "problem" unless the given status == cat.STATUS.SUCCESS ("0")
// which will be recorded in our problem report.
cat.logEvent("Event", "E2", cat.STATUS.FAIL)
cat.logEvent("Event", "E3", "failed")
// The 4th parameter (data) is optional, default is "".
// It can be any of string value.
cat.logEvent("Event", "E4", "failed", "some debug info")
// The 4th parameter (data) can also be an object
// In this case, the object will be dumped into json.
cat.logEvent("Event", "E5", "failed", {a: 1, b: 2})
Error
var cat = require('@dp-cat/client')
cat.init({
appkey: 'nodecat'
})
cat.logError('ErrorInTransaction', new Error())
這樣我們在cat的web端(http://<cat server ip address>:8080/cat/r)
就可以看到相應(yīng)的數(shù)據(jù)了询筏。
Egg的支持
這里為egg的服務(wù)端封裝了一個(gè)插件egg-cat-client
,可以方便egg的應(yīng)用直接接入cat:
安裝
$ npm i egg-cat-client --save
使用
// {app_root}/config/plugin.js
exports.catClient = {
enable: true,
package: 'egg-cat-client',
};
配置
// {app_root}/config/config.default.js
exports.catClient = {
appKey: '<your application name>'
connection: {
ip:'127.0.0.1', // ip與host同時(shí)存在的話優(yōu)先用ip
host: 'xxx.xxx.xx', //host 和 ip只要填其中一個(gè)即可如果竖慧,
port: '2208',
http-port: '8080'
}
};
// {app_root}/app.js
module.exports = app => {
app.beforeStart(async () => {
app.cat = app.catFactory.createClient(app.config.catClient.appKey, {});
await app.cat.ready(true);
});
};
代碼嵌入
class HomeController extends Controller {
async index() {
this.ctx.body = 'hi, egg';
// 獲取初始化好的cat對象
const cat = this.ctx.app.catClient;
const threadCat = new cat.Cat(true);
//創(chuàng)建一個(gè)transaction實(shí)例
const trans = threadCat.newTransaction('TestTran', 'DDD');
//添加數(shù)據(jù)
trans.addData('key', 'value');
trans.logEvent('EventTransaction', 'E1111');
const subTrans = a.newTransaction('TestSubTran', 'GGGGG');
subTrans.addData('subKey', 'subValue');
trans.setStatus(cat.STATUS.SUCCESS);
setTimeout(function() {
trans.complete();
}, 1000);
// Event
cat.logEvent('Event', 'E1');
cat.logEvent('Event', 'E2', cat.STATUS.FAIL);
cat.logEvent('Event', 'E3', 'failed');
// Error
cat.logError('ErrorInTransaction', new Error());
}
}
module.exports = HomeController;