Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added net/http-tracer #84

Closed

Conversation

FreekingDean
Copy link

This adds a generic handler for a net/http server.

I think it may be good to have gorilla use this as the core tracer in the future.

@FreekingDean
Copy link
Author

Hmm the failure in here seems like is related to elasticsearch? Is this a known testing issue?


return func(writer http.ResponseWriter, req *http.Request) {

// bail our if tracing isn't enabled.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

our -> out

@FreekingDean
Copy link
Author

@furmmon Is this something that would be worth using or should I fork?

@FreekingDean
Copy link
Author

By fork I meant to say put this into its own package ***


// span will create a span for the given request.
func (h *HttpTracer) trace(req *http.Request) (*http.Request, *tracer.Span) {
resource := req.Method + " " + req.URL.Path

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will create a unique resource for each new path, which can become problematic as soon as you have path parameters (eg. "/article/:id") in some routes, as is the case for most APIs nowadays.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you are correct, but is there a way to do that with the default go handler? I'm not sure Go's net/http package natively supports pattern matching the way httprouter and gorilla/mux do.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK, net/http doesn't implement pattern matching and named path parameters as most 3rd party go routers do. I therefore think that with the current go ecosystem, we need one integration per HTTP router (cf. my current PR to integrate github.com/julienschmidt/httprouter, or any of the other router integrations), your implementation would still work for the default http mux, but not as a generic go http integration.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes sense. This is not as much a replacement/catchall then, and instead just something that works with the base net/http functions. I wonder if we should use this from the other two to build the span & have a resource builder func that can build the pattern for the endpoint.

\braindump

Copy link
Member

@raphaelgavache raphaelgavache Jul 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello, thank you for that PR FreekingDean. I actually found a nice pattern matching function in net/url. You can try this on the playground:

package main

import (
	"fmt"
	"net/url"
)

func main() {
	u, _ := url.Parse("/books?author=:author&subject=")
	fmt.Println(u.Path)
        // /books
	u, _ = url.Parse("/search?q=net%2Furl&rlz=1C5CHFA_enUS730US731&oq=net%2Furl&aqs=chrome..69i57j69i58j69i61l3j69i59.1391j0j7&sourceid=chrome&ie=UTF-8#q=golang+parse+url+path")
	fmt.Println(u.Path)
        // /search
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @furmmon! That is awesome. I think the main issue would be resource pattern matching when a parameter is in the path: www.api.com/apps/:app_id/get_resource_info In this case the methods I provide would not be sufficient to pull out the relevant path and instead create a new resource for each call to that endpoint:

/apps/1/get_resource_info
/apps/2/get_resource_info
/apps/3/get_resource_info

In this case I think it may be best to have path be absolute in this base case (IE the way I described) but also allow individual libraries to supply the path. (For use with gomux & httprouter)

Copy link
Member

@raphaelgavache raphaelgavache Jul 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

edit - comment outdated

Copy link
Member

@raphaelgavache raphaelgavache left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @FreekingDean for that Pull Request. Nice work, I've added some little comments. Could you also rebase on the current prod branch, it should pass the test.

func Example() {
mux := http.NewServeMux()
mux.Handle("/users", handler)
mux.Handle("/anything", handler)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

handler can't be used as a http.Handler, use http.HandlerFunc(handler) it will create an http.Handler struct

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

return r
}

ctx := tracer.ContextWithSpan(r.Context(), span)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This way of setting the span into the context is deprecated, we changed to
ctx := span.Context(r.Context())

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


// span will create a span for the given request.
func (h *HttpTracer) trace(req *http.Request) (*http.Request, *tracer.Span) {
resource := req.Method + " " + req.URL.Path
Copy link
Member

@raphaelgavache raphaelgavache Jul 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

edit - comment outdated

@FreekingDean
Copy link
Author

closing in favor of #102

@FreekingDean FreekingDean deleted the feature-add-generic-http-tracer branch August 17, 2017 17:02
jdgordon pushed a commit to jdgordon/dd-trace-go that referenced this pull request May 31, 2022
…ataDog#84)

* uds: chage Mutex to RWMutex for fast already-connected path

PR DataDog#62 added in a `Mutex` around the Unix socket writer's `Write` method,
to protect the logic that conditionally connected the socket if there
was not one already. However, because of the lock placement, it
serialises all statsd writes globally, which is likely to be a
performance bottleneck for highly parallel systems.

This commit turns that Mutex into a `RWMutex`. In the case where there is
already a socket set, only a `RLock` is needed. In the case where the
socket needs to be connected, the a full `Lock` is performed to protect
the swapping of `w.conn`.

Note that this change, I believe, will make `SetWriteTimeout`
meaningless; multiple goroutines will call `conn.SetWriteDeadline` in
parallel, and the behaviour of that is to extend the deadline for future
_and all in-flight_ requests. If new calls to `SetWriteDeadline` keep
getting made, the deadline on an existing blocked call to `Write` will
be continuously extended. I'm not really sure how to fix this or whether
it's worth fixing though.

* [rebase] moving uds to uds_blocking for rebase

* [uds][blocking] fixing bad struct name after rebase
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants