c语言sscanf函数的用法是什么
257
2024-01-26
1 简介 DeepFlow 利用 eBPF 采集并解析应用协议,实现了零侵扰的分布式追踪和指标数据的采集DeepFlow 已经内置支持了十多种应用协议的解析,并且还在持续增加中但我们发现实际业务环境中情况会更加复杂:开发会坚持返回 HTTP 200 同时将错误。
信息放到自定义 JSON 结构中,大量 RPC 的 Payload 部分使用 Protobuf、Thrift 等依赖 Schema 进行解码的序列化方式,调用的处理流程中发生了跨线程导致 eBPF AutoTr
acing 断链 针对这些复杂场景,DeepFlow 实现了一套零侵扰的 WebAssembly 插件机制,使得开发人员可针对自己的业务环境定制化 DeepFlow 的协议解析能力本文将分享两个案例,来介绍 DeepFlow 中的 Wasm 插件能力。
02 案例 - 解析 JSON 中的错误信息 在本例中,被监控 HTTP API 的响应消息为 JSON 格式,当 API 出错时 HTTP 协议的状态码可能仍然是 200,确切的错误信息通过 JSON 中的 OPT_STATUS 等字段返回
{ "OPT_STATUS":"AUTH_HEADER_ERROR",//不等于SUCCESS时表示调用失败 "DESCRIPTION":"请传递正确的验证头信息",//详细错误信息 ...//其他返回字段 }
查阅 API 文档后我们得知,OPT_STATUS的值不等于SUCCESS时表示 API 调用失败在常规的 DeepFlow 解析流程中,会按照如下方式构造 HTTP 调用日志的各个字段: response_code:赋值为 HTTP 响应头中的状态码,例如 200、404、500 等。
response_status:状态码小于 400 时认为正常,4XX 认为是客户端异常,5XX 认为是服务端异常 response_exception:赋值为 HTTP 异常状态码对应的英文解释,例如 404 时此字段赋值为 Not Found
response_result:当 HTTP 状态码为异常时赋值为整个 HTTP Payload 当我们安装了 Wasm 插件后,我们可以在上述解析的基础上,将失败 API 的调用日志中的如下字段进行覆写,以实现正确体现业务错误的效果:
response_code:当 JSON 中 OPT_STATUS != SUCCESS、且 HTTP 状态码小于 400 时,此值覆写为 500 response_status:按照新的 response_code 重新赋值,例如 500 时赋值为服务端异常
response_exception:当 JSON 中的 OPT_STATUS != SUCCESS时覆写为 DESCRIPTION 字段的值 response_result:当 response_code 大于等于 400 时赋值为整个 JSON Payload
我们将 Wasm 插件代码放到了这个 GitHub 仓库[1]中上述 API 行为描述的实际上是 DeepFlow 企业版中的 statistics 服务,下面演示将此 Wasm 插件注入到 DeepFlow Agent 以后,对 DeepFlow 企业版服务的自我观测效果。
首先我们在命令行中触发一次 statistics 服务的 API 调用:#请求 curlhttps://cloud.deepflow.yunshan.net/api/statistics/v1/stats/querier/DBDescription/ShowDatabases #HTTP响应头 HTTP/2401 da
te:Tue,22Aug20230129GMT content-type:application/json content-length:152 #HTTP响应体 { "DATA":false, "DESCRIPTION":"请传递正确的验证头信息", "ERR":null, "LEVEL":0, "OPT_STATUS":"AUTH_HEADER_ERROR" }
上述 API 响应中,HTTP 的状态码为 401,OPT_STATUS=AUTH_HEADER_ERROR。我们能在 DeepFlow 页面正确的看到客户端异常指标:
01-client_error_metrics 在 DeepFlow 调用日志页面,可以看到客户端异常的调用日志的详情信息,整个 JSON body 放在了response_result里面:
02-request_log 对该调用发起追踪,能看到是因为fauths返回的 401 异常:
03-tracing 下面是详细的调用链。第一步发起 DNS 请求:
04-dns 第二步调用后端服务验证 License:
05-license 第三步发起 DNS 请求 fauths 服务的地址:
06-dns 第四步调用 fauth 的 /auth API 验证权限,中间需要访问 Redis 获取用户信息:
07-fauth
08-redis 03 案例 - 提取流水号并用于分布式追踪 在金融行业的核心交易系统中,服务之间通常通过在 RPC 中传递一个流水号来实现分布式追踪本例中我们编写了一个演示 Demo 服务,它演示了一个简单的 gRPC 客户端和服务端。
我们知道 gRPC 的消息体是使用 Protobuf 序列化的,本例将演示如何利用 DeepFlow 的 Wasm 插件机制解析这个 Demo 中的 Protobuf 消息,获取其中的流水号,并最终实现分布式追踪。
Wasm 插件的代码可以在这个 GitHub 仓库[2]中找到 本例中的 gRPC 消息定义如下:serviceGame{ rpcGame(OrderRequest)returns(OrderResponse); } messageOrderRequest{ stringbusiness_id=1235; } messageOrderResponse{ stringmsg=1235; }
在 Wasm 插件中,我们将 gRPC Payload 中的 business_id 字段的值赋值到 trace_id 中,用于分布式调用链追踪同时会将 business_id 及 msg 等原始字段在调用日志的 Na。
tive tag 中存储一份,分别对应 attribute.business_id 及 attribute.msg,可用于业务查看更详细的交易信息 我们将 gRPC Demo 部署在 cloud.deepflow 环境中 Sandbox K8s 集群里,安装好 Wasm 插件后,在 DeepFlow 页面直接过滤 l7_protocol = Custom 即可看到这个私有协议的指标和调用日志数据:。
08-metrics
09-request-log
10-tracing 04 如何使用 Golang SDK 开发插件 Wasm 插件可使用多种语言开发,目前 DeepFlow 对 Golang 提供了一个 SDK,开发可以参考文档[3]其中核心的步骤如下:。
新建一个 go 项目, 并且拉取 Golang SDK gomodinitProjectName&&gogetgithub.com/deepflowio/deepflow-wasm-go-sdk在插件中实现协议解析逻辑
packagemain import( "github.com/deepflowio/deepflow-wasm-go-sdk/sdk" ) funcmain(){ sdk.Warn("pluginloaded") sdk.SetPa
rser(SomeParser{}) } typeSomeParserstruct{ } func(pSomeParser)HookIn()[]sdk.HookBitmap{ return[]sdk.HookBitmap{ //一般只需要hook协议解析 sdk.HOOK_POINT_PAYLOAD_PARSE, } } func(pdnsParser)OnHttpReq(ctx*sdk.HttpReqCtx)sdk.HttpAction{ returnsdk.ActionNext() } func(pdnsParser)OnHttpResp(ctx*sdk.HttpRespCtx)sdk.HttpAction{ returnsdk.ActionNext() } func(pdnsParser)OnCheckPayload(ctx*sdk.ParseCtx)(uint8,string){ //这里是协议判断的逻辑,返回0表示失败 //return0,"" return1,"someprotocol" } func(pdnsParser)OnParsePayload(ctx*sdk.ParseCtx)sdk.ParseAction{ //这里是解析协议的逻辑 ifctx.L4!=sdk.TCP||ctx.L7!=1{ returnsdk.ActionNext() } returnsdk.ActionNext() }
编译为 Wasm 插件tinygobuild-owasm.wasm-targetwasi-panic=trap-scheduler=none-no-debug*.go05 如何在 DeepFlow 中部署插件
将编译好的插件上传至 deepflow-server deepflow-ctlplugincreate--typewasm--imagewasm.wasm--namewasm-demo-1修改 deepflow-agent 的组配置,添加需要加载的插件
static_config: ebpf: #对于deepflow-agent原生不支持的协议,eBPF数据需要添加端口白名单才能上报 kprobe-whitelist: port-list:9999 #如果配置了l7-protocol-enabled,别忘了放行Custom类型的协议 l7-protocol-enabled: -Custom #otherprotocol wasm-plugins: -wasm-demo-1//对应deepflow-ctl上传插件的名称
注:目前修改此配置后 deepflow-agent 会自动重启 检查插件是否正确加载kubectl-ndeepflowlogs-fdeepflow-agent-xxxxx|grep-iplugin
11-check 我们看到插件 main 函数里的 warn 日志正常输出,说明插件加载成功了 06 总结 DeepFlow Wasm 插件机制提供了一个可编程的、安全的、资源消耗可控的运行沙箱,它是整个 DeepFlow Pipeline 机制的重要一环。
它的使用场景包括:增强原生支持的协议:在原生协议的解析能力基础之上,提取更多的业务信息支持私有协议的解析:特别是从 Protobuf、Thrift 等依赖 Schema 的 Payload 内容中提取业务字段
零侵扰分布式追踪:通过解析调用中的事务全局 ID,用于实现分布式追踪自定义脱敏:对 MySQL、Redis 等协议中的业务敏感信息进行抹除 未来,我们还会基于 Wasm 插件提供更强大的可编程性例如:。
自定义过滤:对调用日志进行基于 URL、Endpoint 等字段的过滤自定义采样:通过对 TraceID 等追踪字段的分析,决定是否对调用日志进行采样丢弃 07 什么是 DeepFlow DeepFlow[4] 开源项目旨在为复杂的云原生应用提供深度可观测性。
DeepFlow 基于 eBPF 实现了零插桩(Zero Code)、全覆盖(Full Stack)的指标、追踪、日志采集,并通过智能标签技术实现了所有观测数据的全关联(Universal Tagging)和高效存取。
使用 DeepFlow,可以让云原生应用自动具有深度可观测性,从而消除开发者不断插桩的沉重负担,并为 DevOps/SRE 团队提供从代码到基础设施的监控及诊断能力。 编辑:黄飞
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~