Cat是大众点评用于对服务端应用进行业务监控的一整套系统,具体可以直接参考他们的github有非常详细的介绍,这里只是单独将Node服务接入Cat的流程整理出来,并介绍了为Egg编写的客户端插件egg-cat-client。
系统支持
OSX (>=10.13)
Alpine linux
CentOS 6
CentOS 7
Ubuntu 14.04 LTS
Ubuntu 16.04 LTS
Ubuntu 18.04 LTS
node版本
node v8+
准备工作
下载Cat代码到本地
git clone git@github.com:dianping/cat.git
编译libcatclient动态库
查看lib/node.js/binding.gyp
的c库依赖,发现node包的安装需要依赖一个lcatclient
的动态链接库,这里需要先编译出这个库并加载到系统中。
{
"targets": [
{
"target_name": "nodecat",
"sources": [
"src/nodecat.cc",
],
"include_dirs": [
"include"
],
"libraries": [
"-lcatclient"
]
}
]
}
- 需要安装一个支持C99或者C编译器,Mac直接安装Xcode就可以。
- 需要安装cmake和make,这个用来构建动态链接库的工具。
- 进入
lib/c
目录并执行下面的命令:
1. mkdir -p cmake
2. cd cmake
3. cmake ..
4. make -j
5. make install
上面👆执行完成后,libcatclient.so (或Mac下 libcatclient.dylib)
已经安装到LD_LIBRARY_PATH
目录下,大多数情况下是 /usr/local/lib
安装node cat client
npm i @dp-cat/client
cat环境配置
cat的client所链接的cat server并不是在代码里面进行设置的,而是cat的默认系统目录/data
进行配置的:
- 创建
/data/appdatas/cat
目录并保证读写权限。 - 创建
/data/applogs/cat
目录并保证读写权限。 - 创建
/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>
根据上面👆的配置文件,配置cat client所连接的server。这样所有的准备工作就完成了,可以在业务代码中直接使用了。
cat使用
cat中已经包含了使用的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)
就可以看到相应的数据了。
Egg的支持
这里为egg的服务端封装了一个插件egg-cat-client
,可以方便egg的应用直接接入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同时存在的话优先用ip
host: 'xxx.xxx.xx', //host 和 ip只要填其中一个即可如果,
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);
//创建一个transaction实例
const trans = threadCat.newTransaction('TestTran', 'DDD');
//添加数据
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;