Package: huifu-cat-sdk
Cat Client for Pythonpycat同时支持 python2 (>=2.7) 和 python3 (>=3.5)。但这也意味着centos6默认情况下是不被支持的（因为内置的 python 版本是 2.6.6）。尽管如此，你仍可以通过升级内置 python 版本或使用 virtualenv 的方式使用pycat。安装通过 pip 安装pipinstallhuifu-cat-sdk通过 setuptools 安装pythonsetup.pyinstall准备工作启动 cat 客户端前的准备工作创建/data/appdatas/cat目录 (这个路径是固定的，所以你可能需要使用 Docker)确保你具有这个目录的读写权限。创建/data/applogs/cat目录 (可选)这个目录是用于存放运行时日志的，这将会对调试提供很大帮助，同样需要读写权限。创建/data/appdatas/cat/client.xml，内容如下<?xml version="1.0" encoding="utf-8"?><configxmlns:xsi="http://www.w3.org/2001/XMLSchema"xsi:noNamespaceSchemaLocation="config.xsd"><servers><serverip="<cat server ip address>"port="2280"http-port="8080"/></servers></config>不要忘记把<cat server IP address>替换成你自己的服务器地址哦！初始化通过下面的代码来初始化pycat：cat.init("appkey")appkey 只能包含英文字母 (a-z, A-Z)、数字 (0-9)、下划线 (_) 和中划线 (-)协程模式由于我们在ccat中使用ThreadLocal存储 Transaction 的栈，并用于构建消息树，同时pycat高度依赖ccat。因此在协程模式下，如gevent,greenlet，由于同一个线程里的线程会交替执行，我们暂不提供消息树功能。在这些情况下，你需要通过下述代码来关闭消息树功能。cat.init("appkey",logview=False)这样我们就会禁用 ccat 的上下文管理器，从而禁用消息树功能。注意：FastAPI 中 async def 定义的路由处理函数和被 Depends 包裹的函数只在主线程中执行，而 def 定义的函数则分别在不同的线程里执行。调试日志有时你会想要打开调试日志。注意调试日志会被输出到控制台中。cat.init("appkey",debug=True)Quickstartimportcatimporttimecat.init("appkey")withcat.Transaction("foo","bar")ast:try:t.add_data("a=1")# 一般不使用cat.set_trace_id("trace_id_xxx")# 设置当前请求TraceId整个，链路唯一idcat.set_attributes({"xxx":"xxx"})# 上送自定义参数，类型为字典，scope为单个请求cat.set_baggages({"xxx":"xxx"})# 上送自定义参数，类型为字典，scope为整条链路cat.log_event("hook","before")# 基础函数打印信息cat.log_biz_result("code","msg","status")# 打印业务返回信息cat.log_tag_for_api(request.url.path,{"xxx":"xxx"})# 给当前接口加标签cat.log_tag_for_next_call(request.url.path,{"xxx":"xxx"})# 给下一个调用的接口加标签# do somethingexceptExceptionase:cat.log_exception(e)# 打印错误日志finally:cat.metric("api-count").log_for_count(quantity)# 埋点计次cat.metric("api-count").log_for_count_map(quantity,customParams)# 埋点计次，支持上送自定义参数，类型为字典cat.metric("api-duration").log_for_sum(quantity,customParams)# sumcat.metric("metric").log_for_avg(quantity,customParams)# avgcat.log_event("hook","after")time.sleep(1)API ListTransactiont=cat.Transaction("Trans","t3")t.complete()为了避免忘记关闭 Transaction，我们强烈建议使用 try-finally 代码块包裹 transaction，并在 finally 代码块中执行 complete。try:t=cat.Transaction("Trans","t3")finally:t.complete()我们同时提供了装饰器和上下文管理器的用法，可以自动关闭 Transaction。这也是我们推荐的使用方法。via decorator@cat.transaction("Trans","T2")deftest():'''Use with decorator'''cat.log_event("Event","E2")如果被装饰的函数出现什么问题，Transaction 的状态会被置为FAILED，并且无论有没有 Exception 被抛出，Transaction 都会被自动关闭。唯一的问题就是如果使用装饰器模式的话，你拿不到 Transaction 对象。via context managerwithcat.Transaction("Transaction","T1")ast:cat.log_event("Event","E1")try:do_something()exceptException:t.set_status(cat.CAT_ERROR)t.add_data("hello world!")如果在with管理的上下文中出现了什么问题，Transaction 的状态会被置为FAILED，并且无论有没有 Exception 被抛出，Transaction 都会被自动关闭。虽然这有些复杂，但你可以拿到 transaction 对象。Transaction apis我们提供了一系列 API 来对 Transaction 进行修改。add_dataset_statusset_durationset_duration_startset_timestampcomplete这些 API 可以被很方便的使用，如下代码所示：try:trans=cat.Transaction("Trans","T3")trans.add_data("content")trans.add_data("key","val")trans.set_status("error")trans.set_duration(500)trans.set_duration_start(time.time()*1000-30*1000)trans.set_timestamp(time.time()*1000-30*1000)finally:# NOTE don't forget to complete the Transaction!trans.complete()在使用 Transaction 提供的 API 时，你可能需要注意以下几点：你可以调用add_data多次，他们会被&连接起来。同时指定duration和durationStart是没有意义的，尽管我们在样例中这样做了。不要忘记完成 transaction！否则你会得到一个毁坏的消息树以及内存泄漏！Eventcat.log_event# Log a event with success status and empty data.cat.log_event("Event","E1")# The 3rd parameter (status) is optional, default is "0".# It can be any of string value.# The event will be treated as a "problem" unless the given status == cat.CAT_CUSSESS ("0")# which will be recorded in our problem report.cat.log_event("Event","E2",cat.CAT_ERROR)cat.log_event("Event","E3","failed")# The 4th parameter (data) is optional, default is "".# It can be any of string value.cat.log_event("Event","E4","failed","some debug info")cat.log_exception记录一个 ExceptionException 是一种特殊的 Event，默认情况下，type = Exception，name = exc.__class__.__name__由于 Exception 通常出现在 except 代码块中，错误堆栈信息也会被自动收集和上报。try:raiseException("I'm a exception")exceptExceptionase:cat.log_exception(e)# We will collect error traces automatically in most cases# But you can also customize the trace info.try:1/0exceptExceptionase:cat.log_exception(e,traceback.format_exc())# Even out of an except block.e=Exception("something goes wrong")cat.log_exception(e,"customized trace info")cat.log_error记录一个 ErrorError 是一个轻量级的 Exception，默认情况下，type = Exception，name通过第一个参数指定。# Same as cat.log_event("Exception", "e1")cat.log_error("e1")# Error traces will be collected when you use it in an except block.try:1/0exceptException:cat.log_error("e2")# customize your own error traces through the 2nd parameter which is optional.cat.log_error("e3","this is my error stack info")Metric# Countercat.metric("metric1").count()# default is 1cat.metric("metric1").count(5)# Durationcat.metric("metric2").duration(100)cat.metric