fasthttp icon indicating copy to clipboard operation
fasthttp copied to clipboard

opentelemetry / tracing support - q&a

Open mstrYoda opened this issue 4 years ago • 22 comments

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?

mstrYoda avatar Jan 05 '21 13:01 mstrYoda

+1

previousdeveloper avatar Jan 05 '21 16:01 previousdeveloper

Where would you suggest to add these hook properties? On Client/HostClient or on Request?

erikdubbelboer avatar Jan 06 '21 15:01 erikdubbelboer

Where would you suggest to add these hook properties? On Client/HostClient or on Request?

It needs both request and response, so we need somewhere which we can access both at the same time. I will dive source code and read more carefully, but currently I'm not sure.

Do you have any suggestion about it? I might do an example pr for it.

mstrYoda avatar Jan 06 '21 17:01 mstrYoda

I guess if you want to be able to run the hook even on fasthttp.Get it needs to be some global variable. Maybe an atomic.Value. If you can try making a pull request that would be nice.

erikdubbelboer avatar Jan 06 '21 18:01 erikdubbelboer

May be you can add context to Request Struct, just like net/http request, we can use that context to do traceing

aschenmaker avatar May 27 '21 09:05 aschenmaker

Any updates on this?

gaby avatar Feb 05 '23 00:02 gaby