grpc-go的stat/HandleRPC中可以访问有关请求和响应有效负载的信息。

huangapple go评论73阅读模式
英文:

Access information about the request and response payloads in grpc-go's stat/HandleRPC

问题

我正在使用stats/HandleRPC()来记录有关RPC持续时间的一些指标,当我收到stats/End数据时,我想要使用一些从传入和传出负载中提取的信息对指标进行标记。实现这一目标的最佳方法是什么?

func (h *myStatsHandler) HandleRPC(ctx context.Context, rpcStats stats.RPCStats) {
	switch stat := rpcStats.(type) {
	case *stats.End:
		durationMs := stat.EndTime.Sub(stat.BeginTime).Seconds() * 1000.0
		// 在发送这个值之前,我需要知道例如请求负载中特定键的值,或者响应是否为nil
	}
}
英文:

I am using stats/HandleRPC() to emit some metrics about the RPC duration, when I receive the stats/End data, and I want to tag the metrics with some information that can be extracted from the incoming and outgoing payloads. What would be the best way to achieve this?

func (h *myStatsHandler) HandleRPC(ctx context.Context, rpcStats stats.RPCStats) {
	switch stat := rpcStats.(type) {
	case *stats.End:
		durationMs := stat.EndTime.Sub(stat.BeginTime).Seconds() * 1000.0
		// Now before sending this value, I need to know, for example the value of a specific key in the request payload, or whether the response is nil or not 
	}
}

答案1

得分: 1

在你的TagRPC实现中,你可以创建一个结构体并将其指针添加到上下文中。然后,在连续调用HandleRPC时,在其中添加信息。因此,如果你需要从仅在*stats.InPayload调用中可用的Payload中获取某些内容,你可以将其提取出来并存储在你添加到上下文中的结构体中,然后在后续调用HandleRPC时再次访问它。

type recorderCtxKey struct{}

type recorder struct {
	size   int64
}

func (sl *statsHandler) TagRPC(ctx context.Context, info *stats.RPCTagInfo) context.Context {
	return context.WithValue(ctx, rpcStatCtxKey{}, &recorder{})
}

func (h *statsHandler) HandleRPC(ctx context.Context, rpcStats stats.RPCStats) {
    switch stat := rpcStats.(type) {
    case *stats.InPayload:
        r, _ := ctx.Value(recorderContextKey{}).(*Recorder)
        r.size += stat.WireLength
    case *stats.End:
        durationMs := stat.EndTime.Sub(stat.BeginTime).Seconds() * 1000.0
        r, _ := ctx.Value(recorderContextKey{}).(*Recorder)
        # 使用 r.size #
    }
}
英文:

In your implementation of TagRPC, you can create a struct and add a pointer to it to the context. Then add information in it over the successive calls to HandleRPC. So if you need something from the Payload that's only available in the *stats.InPayload invocation, you can pull it out and store it in the struct you added to the context, and then access it later when HandleRPC is called again with *stats.End

type recorderCtxKey struct{}

type recorder struct {
	size   int64
}

func (sl *statsHandler) TagRPC(ctx context.Context, info *stats.RPCTagInfo) context.Context {
	return context.WithValue(ctx, rpcStatCtxKey{}, &recorder{})
}

func (h *statsHandler) HandleRPC(ctx context.Context, rpcStats stats.RPCStats) {
    switch stat := rpcStats.(type) {
    case *stats.InPayload:
        r, _ := ctx.Value(recorderContextKey{}).(*Recorder)
        r.size += stat.WireLength
    case *stats.End:
        durationMs := stat.EndTime.Sub(stat.BeginTime).Seconds() * 1000.0
        r, _ := ctx.Value(recorderContextKey{}).(*Recorder)
        # use r.size #
    }
}

huangapple
  • 本文由 发表于 2022年6月19日 08:41:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/72673612.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定