cloudwego / hertz

Go HTTP framework with high-performance and strong-extensibility for building micro-services.
https://www.cloudwego.io
Apache License 2.0
5.28k stars 515 forks source link

基于现有的 Tracer 设计,如何监控 inflight 指标? #1094

Closed sunhailin-Leo closed 5 months ago

sunhailin-Leo commented 6 months ago

Describe the Question

疑惑点:想问一下 hertz server(hertz/pkg/protocol/http1/server.go at develop · cloudwego/hertz) 这一段逻辑前置在 req.ReadHeader(https://github.com/cloudwego/hertz/blob/develop/pkg/protocol/http1/server.go#L195)是有什么 tracer 设计上的考虑嘛? 问题:由于上面的疑惑点会导致无法监控 inflight 指标(想监控请求中的条数)

Expected behavior

如何能够监控到 inflight request 指标?

Hertz version:

v0.8.1

Environment:

go1.21.7

li-jin-gou commented 6 months ago
  1. 为了细粒度买点,所以在很前置的位置开始了
  2. 参考 https://www.cloudwego.io/zh/docs/hertz/tutorials/observability/instrumentation/ 在 ReadBodyFinish 完成时扩展一个 tracer 读取 body & 解析数据获得条数。可以看看 https://www.cloudwego.io/zh/docs/hertz/tutorials/observability/tracing/https://www.cloudwego.io/zh/docs/hertz/tutorials/framework-exten/monitor/
sunhailin-Leo commented 6 months ago
  1. 为了细粒度买点,所以在很前置的位置开始了
  2. 参考 https://www.cloudwego.io/zh/docs/hertz/tutorials/observability/instrumentation/ 在 ReadBodyFinish 完成时扩展一个 tracer 读取 body & 解析数据获得条数。可以看看 https://www.cloudwego.io/zh/docs/hertz/tutorials/observability/tracing/https://www.cloudwego.io/zh/docs/hertz/tutorials/framework-exten/monitor/

// genLabels make labels values. func genLabels(c *app.RequestContext) prometheus.Labels { labels := make(prometheus.Labels) labels[labelMethod] = defaultValIfEmpty(string(c.Request.Method()), unknownLabelValue) labels[labelStatusCode] = defaultValIfEmpty(strconv.Itoa(c.Response.Header.StatusCode()), unknownLabelValue) labels[labelPath] = defaultValIfEmpty(c.FullPath(), unknownLabelValue)

return labels

}

// Start record the start of server handling request from client. func (s ServerTracer) Start(ctx context.Context, c app.RequestContext) context.Context { // inflight gaugeIncDec(s.serverHandledInFlight, true, genLabels(c))

return ctx

}

// Finish record the ending of server handling request from client. func (s ServerTracer) Finish(_ context.Context, c app.RequestContext) { if c.GetTraceInfo().Stats().Level() == stats.LevelDisabled { return }

httpStart := c.GetTraceInfo().Stats().GetEvent(stats.HTTPStart)
httpFinish := c.GetTraceInfo().Stats().GetEvent(stats.HTTPFinish)
if httpFinish == nil || httpStart == nil {
    return
}
cost := httpFinish.Time().Sub(httpStart.Time())
_ = counterAdd(s.serverHandledCounter, 1, genLabels(c))
_ = histogramObserve(s.serverHandledHistogram, cost, genLabels(c))
gaugeIncDec(s.serverHandledInFlight, false, genLabels(c))

}

li-jin-gou commented 6 months ago

cc @rogerogers 帮看下哈,这里是不是要判断一下所处的阶段

li-jin-gou commented 6 months ago

得在 Finish 里获取数据,埋点只是记录耗时...

sunhailin-Leo commented 6 months ago

得在 Finish 里获取数据,埋点只是记录耗时...

sunhailin-Leo commented 6 months ago

@li-jin-gou

rogerogers commented 6 months ago

目前 start 获取不到 path 信息

sunhailin-Leo commented 6 months ago

目前 start 获取不到 path 信息

那现阶段有比较好的解决方案嘛?🤔

rogerogers commented 6 months ago

@li-jin-gou

这种中间件的方式,用 hertz 中间件也可以实现类似的

sunhailin-Leo commented 6 months ago

@li-jin-gou

这种中间件的方式,用 hertz 中间件也可以实现类似的

那暂时先按这种方式实现先迁移吧。