valyala/fasthttp

opentelemetry / tracing support - q&a

Open

#940 opened on Jan 5, 2021

View on GitHub
 (22 comments) (13 reactions) (1 assignee)Go (21,741 stars) (1,755 forks)batch import
help wanted

Description

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?

Contributor guide