deepflow icon indicating copy to clipboard operation
deepflow copied to clipboard

[BUG]GRPC协议UnaryServer请求,Server端接口返回err不为nil情况下agent无法采集到grpc Header信息里面自定义信息

Open yang1992 opened this issue 1 year ago • 5 comments

Search before asking

  • [X] I had searched in the issues and found no similar feature requirement.

DeepFlow Component

Agent

What you expected to happen

deepflow-agent版本:v6.5分支分支 https://github.com/deepflowio/deepflow/blob/v6.5/agent/src/flow_generator/protocol_logs/http.rs

GRPC协议UnaryServer请求当,服务端接口返回resp, err 1、当err == nil: 拦截grpc接口请求,GRPC的Data响应前,执行类似grpc.SendHeader(ctx, metadata.Pairs("self-code", "500")) 能采集到self_code,ck对应的表里面展示attribute_names和attribute_values有相应self_code字段 2、当err != nil : 拦截grpc接口请求,在GRPC的标准的grpc-status和grpc-messages Header信息返回前,执行类似grpc.SendHeader(ctx, metadata.Pairs("self-code", "500")) 不能采集到self_code,ck对应的表里面无展示attribute_names和attribute_values无相应self_code字段 deepflow-agent的pod无相关错误日志,通过wireshark抓包确定确实发送了对应的Header数据,按照代码逻辑应该解析出L7ProtocolInfo然后合并attributes,通过wireshark观察抓包结果 1和2的区别主要是: 1的包里面协议里面展示的是GRPC,并且DATA和Header在一起,2的Header是分包的

担心是解析不出来,看了http.rs源代码header加了content-length都不起作用,是不是服务端第一次单独返回grpc.SendHeader的数据时候并没有确定self.proto类型???

How to reproduce

func ExtractUnaryServerErrorInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo,
	handler grpc.UnaryHandler) (interface{}, error) {

	resp, err := handler(ctx, req)
	if err != nil {
                // 这种方式采集不到额外信息
		grpc.SendHeader(ctx, metadata.Pairs("self-code", "500"))
		return resp, err
	}
        
       // ............................        
       // ...........................
      // 解析 resp提取错误码 code
        md := metadata.Pairs("self-code", code)
      // 这种方式可以采集额外信息
	grpc.SendHeader(ctx, md)
	return resp, err
}

DeepFlow version

Name: deepflow-server community edition Branch: v6.5 CommitID: https://github.com/deepflowio/deepflow/commit/8555e64f065b19a98a207ee99dd46880c978ab6e RevCount: 10792 Compiler: go version go1.21.12 linux/amd64 CompileTime: 2024-08-01 15:36:18

Defaulted container "deepflow-agent" out of: deepflow-agent, configure-sysctl (init) 10793-74069ad272adad8fb53259b8d973830c0fdf7a58 Name: deepflow-agent community edition Branch: v6.5 CommitId: https://github.com/deepflowio/deepflow/commit/74069ad272adad8fb53259b8d973830c0fdf7a58 RevCount: 10793 Compiler: rustc 1.77.1 (7cf61ebde 2024-03-27) CompileTime: 2024-08-02 03:12:26

DeepFlow agent list

ID NAME TYPE CTRL_IP CTRL_MAC STATE GROUP EXCEPTIONS REVISION UPGRADE_REVISION 1 master-c57a7-0-V1 K8S_VM 10.107.19.118 fe:fc:fe:a4:5a:c0 NORMAL default v6.5 10793 2 master-15d62-0-V4 K8S_VM 10.2.24.51 fe:fc:fe:97:6d:f0 NORMAL default v6.5 10793 3 master-b17e6-2-V3 K8S_VM 10.2.24.53 fe:fc:fe:2c:18:f9 NORMAL default v6.5 10793 4 master-41874-1-V2 K8S_VM 10.2.24.52 fe:fc:fe:0c:2a:26 NORMAL default v6.5 10793

Kubernetes CNI

NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE calico-system calico-node 1 1 1 1 1 kubernetes.io/os=linux 12d kube-system kube-proxy 1 1 1 1 1 kubernetes.io/os=linux 12d kube-system open-local-agent 1 1 1 1 1 12d

[root@master-15d62-0 fancy]# calicoctl version Client Version: v3.26.1 Git commit: b1d192c95 Cluster Version: v3.26.1 Cluster Type: typha,kdd,k8s,operator,bgp,kubeadm

Operation-System/Kernel version

4.18.0-372.32.1.90.po1.x86_64

Anything else

No response

Are you willing to submit a PR?

  • [ ] Yes I am willing to submit a PR!

Code of Conduct

yang1992 avatar Aug 15 '24 09:08 yang1992

使用grpc.SetTrailer(ctx, md)就可以采集到了

yang1992 avatar Aug 15 '24 13:08 yang1992

感觉像key赋值的代码有bug: https://github.com/deepflowio/deepflow/blob/60d40f292c7d5255f8d4c907a071bf320591dc33/agent/src/flow_generator/protocol_logs/http.rs#L1421-L1429 解析出来的attribute_names的key小概率情况下会和value对应不上的情况: key的取值应该取的是f.field_name的拷贝,而非一个Cow类型的key,或者key.to_owned().replace("-", "_"),

期望解析出:

attribute_names:           ['rpc_service','xxx_code','xxx_msg']
attribute_values:          ['xxx.xx', 'xxx', '500', "xxx error"]

结果解析出:

attribute_names:           ['rpc_service','xxx_code','xxx_code','xxx_code']
attribute_values:          ['xxx.xx', 'xxx', '500', "xxx error", "500"]

解析出value和key存在对应不上的情况

@TomatoMr

yang1992 avatar Aug 16 '24 05:08 yang1992

感觉像key赋值的代码有bug:

https://github.com/deepflowio/deepflow/blob/60d40f292c7d5255f8d4c907a071bf320591dc33/agent/src/flow_generator/protocol_logs/http.rs#L1421-L1429

解析出来的attribute_names的key小概率情况下会和value对应不上的情况: key的取值应该取的是f.field_name的拷贝,而非一个Cow类型的key,或者key.to_owned().replace("-", "_"), 期望解析出:

attribute_names:           ['rpc_service','xxx_code','xxx_msg']
attribute_values:          ['xxx.xx', 'xxx', '500', "xxx error"]

结果解析出:

attribute_names:           ['rpc_service','xxx_code','xxx_code','xxx_code']
attribute_values:          ['xxx.xx', 'xxx', '500', "xxx error", "500"]

解析出value和key存在对应不上的情况

@TomatoMr

@yang1992 您好,

attribute_names: ['rpc_service','xxx_code','xxx_code','xxx_code'] attribute_values: ['xxx.xx', 'xxx', '500', "xxx error", "500"]

  1. 关于 attributes 对不上的问题: 这里的 attributes 的 name 和 value 的数量是对不上的,这是笔误,还是说这就是“对不上”的部分?因为 attribute 的 key 和 value 是成对出现的,所以不太可能会出现数量上对不上。
  2. 如果需要将自定义的 header 字段加到 attributes 中,需要配置 static_config.l7-protocol-advanced-features.extra-log-fieldshttps://github.com/deepflowio/deepflow/blob/v6.5/server/agent_config/example.yaml#L1180,如果已经配置了但还有问题,我们可以继续讨论,或者把配置也贴上来看看。
  3. 关于 key的取值应该取的是 f.field_name 的拷贝,而非一个 Cow 类型的 key,或者 key.to_owned().replace("-", "_")的问题: key.replace("-", "_") 返回的是一个 String 了,不是一个 Cow 类型的 key,不需要先 key.to_owned()
  4. 另外是否有使用 wasm 插件之类的自定义写入一些 attributes,还有我们在合并请求响应的时候,都没有对 attributes 去重,所以有可能会有重复的 attribute。

TomatoMr avatar Aug 19 '24 09:08 TomatoMr

感觉像key赋值的代码有bug: https://github.com/deepflowio/deepflow/blob/60d40f292c7d5255f8d4c907a071bf320591dc33/agent/src/flow_generator/protocol_logs/http.rs#L1421-L1429

解析出来的attribute_names的key小概率情况下会和value对应不上的情况: key的取值应该取的是f.field_name的拷贝,而非一个Cow类型的key,或者key.to_owned().replace("-", "_"), 期望解析出:

attribute_names:           ['rpc_service','xxx_code','xxx_msg']
attribute_values:          ['xxx.xx', 'xxx', '500', "xxx error"]

结果解析出:

attribute_names:           ['rpc_service','xxx_code','xxx_code','xxx_code']
attribute_values:          ['xxx.xx', 'xxx', '500', "xxx error", "500"]

解析出value和key存在对应不上的情况 @TomatoMr

@yang1992 您好,

attribute_names: ['rpc_service','xxx_code','xxx_code','xxx_code'] attribute_values: ['xxx.xx', 'xxx', '500', "xxx error", "500"]

  1. 关于 attributes 对不上的问题: 这里的 attributes 的 name 和 value 的数量是对不上的,这是笔误,还是说这就是“对不上”的部分?因为 attribute 的 key 和 value 是成对出现的,所以不太可能会出现数量上对不上。
  2. 如果需要将自定义的 header 字段加到 attributes 中,需要配置 static_config.l7-protocol-advanced-features.extra-log-fields:https://github.com/deepflowio/deepflow/blob/v6.5/server/agent_config/example.yaml#L1180,如果已经配置了但还有问题,我们可以继续讨论,或者把配置也贴上来看看。
  3. 关于 key的取值应该取的是 f.field_name 的拷贝,而非一个 Cow 类型的 key,或者 key.to_owned().replace("-", "_")的问题: key.replace("-", "_") 返回的是一个 String 了,不是一个 Cow 类型的 key,不需要先 key.to_owned()
  4. 另外是否有使用 wasm 插件之类的自定义写入一些 attributes,还有我们在合并请求响应的时候,都没有对 attributes 去重,所以有可能会有重复的 attribute。

问题1 是values和name值对不上 问题2 配置了,不然不会采集到 问题3 修改了这个确定没有啥作用 问题4 HTTP2 没有自定义wasm

上面答复没有解决问题,我测试出来了,grpc的接口调用如果复用了连接(非stream,就是调用req/resp但是req请求复用了连接conn),attributes里面写入可能会乱序导致我上面说的问题,不复用连接的场景下不会出现上面这个问题

针对这种问题,有什么更好的采集方法没有,HTTP2的wasm插件上吐attributes数据能解决这个问题不,使用HTTP2的wasm插件需要解析HTTP2压缩头部,GoHttp2Uprobe性能好像会差一些?

@TomatoMr

yang1992 avatar Aug 19 '24 10:08 yang1992

grpc请求复用conn,conn Reuse场景下,多个grpc请求的返回结果是不是有可能粘在一起, @TomatoMr @yinjiping

yang1992 avatar Oct 25 '24 02:10 yang1992