valyala/fasthttp

opentelemetry / tracing support - q&a

Open

#940 创建于 2021年1月5日

在 GitHub 查看
 (22 评论) (13 反应) (1 负责人)Go (21,741 star) (1,755 fork)batch import
help wanted

描述

Hi, we want to enable open telemetry in fasthttp. Actually we started to write a helper library, somehow we can support tracing for the requests written like below:

func getUserFasthttp(ctx context.Context, id string) string {
	req := fasthttp.AcquireRequest()
	res := fasthttp.AcquireResponse()
	defer fasthttp.ReleaseRequest(req)
	defer fasthttp.ReleaseResponse(res)

	req.SetRequestURI("http://10.43.200.175:30425/hello")

	span := tracing.StartSpan(ctx, req, "test")
	err := fasthttp.Do(req, res)
	tracing.EndSpan(span, res.StatusCode(), err)

	if err != nil {
		panic(err)
	}

	return "test"
}

but, if developers choose to use fasthttp.Get/Post approach, we could not add telemetry data:

func getUserFasthttpWithGet(ctx context.Context, id string) string {
	span := tracing.StartSpan(ctx, nil, "test")
	var responseBody []byte
	status, _, err := fasthttp.Get(responseBody, "http://test/hello")
	tracing.EndSpan(span, status, err)

	if err != nil {
		panic(err)
	}

	return "test"
}

Because we could not access to the internal Request/Response struct.

We thought that we can add another method to fasthttp source code with tracing support, or, we can add hooks to thoose methods in below:

client.go line 826

func clientGetURL(dst []byte, url string, c clientDoer) (statusCode int, body []byte, err error) {
	req := AcquireRequest()

        // here we can run hooks
        //hook(req)

	statusCode, body, err = doRequestFollowRedirectsBuffer(req, dst, url, c)

	ReleaseRequest(req)
	return statusCode, body, err
}

client.go line 926

func doRequestFollowRedirectsBuffer(req *Request, dst []byte, url string, c clientDoer) (statusCode int, body []byte, err error) {
	resp := AcquireResponse()
	bodyBuf := resp.bodyBuffer()
	resp.keepBodyBuffer = true
	oldBody := bodyBuf.B
	bodyBuf.B = dst

	statusCode, _, err = doRequestFollowRedirects(req, resp, url, defaultMaxRedirectsCount, c)

        // here we can run hooks
        //hook(req)

	body = bodyBuf.B
	bodyBuf.B = oldBody
	resp.keepBodyBuffer = false
	ReleaseResponse(resp)

	return statusCode, body, err
}

The hook() functions might be used in several ways for example, telemetry support, request/resp logging, header manipulation etc...

What are your thoughts?

贡献者指南