-
Notifications
You must be signed in to change notification settings - Fork 617
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
Add unique request id #292
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a good idea. A couple of comments:
- I don't see the code that handles the access logging.
- Please update the NOTICES.txt file for each vendored library.
However, unless the unique request id format is fully configurable and pluggable I'd prefer if you just write a function which generates a UUID instead of pulling the library in for that one function.
proxy/http_headers_test.go
Outdated
"X-Forwarded-Proto": []string{"http"}, | ||
"X-Forwarded-Port": []string{"1234"}, | ||
"X-Real-Ip": []string{"1.2.3.4"}, | ||
"X-Unique-Request-Id": []string{""}, // XXX nedd to figure out how to regexp match |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You add a func UUID()
to the proxy which you can mock.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made changes you suggest.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logging can be made by using $header.ConfiguredHeaderName format already present in fabio.
fabio.properties
Outdated
@@ -353,6 +353,13 @@ | |||
# proxy.header.tls.value = | |||
|
|||
|
|||
# proxy.header.uniquerequesti configures the header for the adding unique request id. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
config/config.go
Outdated
@@ -57,6 +57,7 @@ type Proxy struct { | |||
TLSHeader string | |||
TLSHeaderValue string | |||
GZIPContentTypes *regexp.Regexp | |||
UniqueRequestID string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think RequestID
is enough since they need to be unique for this to make sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shortened option name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you move the UUID code into uuid/uuid.go
and put into the header a copyright notice where you copied this from, please? Also, update the NOTICES.txt file with a reference to that project and the license needs to be compatible (MIT, BSD, ...).
you're also correct with the logging. |
Almost there. For testing I suggest you add a // UUID returns a unique id in uuid format.
// If UUID is nil, uuid.NewV4() is used.
UUID func() string Then create in the func NewV4() string {
return EncodeHex(NewRandom())
} Now you can mock this in the test. |
One thing I'd like to know though and maybe you can add a benchmark for this is how many UUIDs this approach can generate? Is this using a pseudo random number generator which can generate enough entropy for thousands of req/sec or will this become a limiting factor for the throughput? If yes, then we need to find a better way. |
There are users with 20k req/sec (or more) on a single instance. I won't name you in public but you know who you are :) |
Think I found a winner ... it's not RFC 1422 compliant but it does generate unique IDs and it does it very fast. The other standard UUID packages around github do won't meet the 20k/s request requirement. Code package main
import (
"fmt"
"testing"
guuid "github.com/google/uuid"
muuid "github.com/m4rw3r/uuid"
fuuid "github.com/rogpeppe/fastuuid"
suuid "github.com/satori/go.uuid"
)
func BenchmarkV4Google(b *testing.B) {
for i := 0; i < b.N; i++ {
guuid.NewRandom()
}
}
func BenchmarkV4Satori(b *testing.B) {
for i := 0; i < b.N; i++ {
suuid.NewV4()
}
}
func BenchmarkV4m4rw3r(b *testing.B) {
for i := 0; i < b.N; i++ {
muuid.V4()
}
}
func BenchmarkFastUUIDRaw(b *testing.B) {
g := fuuid.MustNewGenerator()
for i := 0; i < b.N; i++ {
g.Next()
}
}
func BenchmarkFastUUIDFormatted(b *testing.B) {
g := fuuid.MustNewGenerator()
for i := 0; i < b.N; i++ {
_ = fmt.Sprintf("%x", g.Next())
}
} Results
Even with the formatting being done by the relatively heavy |
@leprechau very cool. Thx for digging. Want to add a fast formatter? That lib is also small enough to be vendored in. |
@magiconair Done. I put the formatter and test here: https://github.com/leprechau/uuid-test |
Wow! Great research! I'll definitely use fastest library. |
@magiconair Do I need to make some more improvements? |
Sorry. Got sidetracked. Looking now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some small changes but other than that this looks quite good!
Could you add an integration test as well? You can either copy the TestProxyProducesCorrectXffHeader
or refactor/rename it slightly so that it tests for more than one header. I'd like to make sure that this doesn't get lost during some refactoring.
fabio.properties
Outdated
@@ -353,6 +353,13 @@ | |||
# proxy.header.tls.value = | |||
|
|||
|
|||
# proxy.header.requestid configures the header for the adding request id. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
proxy.header.requestid configures the header for the adding a unique request id.
proxy/http_headers.go
Outdated
// addRequestID Set header with name from `cfg.RequestID` to UUID value | ||
// | ||
func addRequestID(r *http.Request, p *HTTPProxy) { | ||
if p.Config.RequestID != "" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add this to the addHeaders()
function and move your test to the TestAddHeaders()
fn as well, please? This isn't complex enough for a separate fn/test IMO.
if p.Config.RequestID != "" {
id := p.UUID
if id == nil {
id = uuid.NewUUID
}
r.Header.Set(p.Config.RequestID, id())
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have did it in separate function because it need HTTPProxy, which is not available in addHeaders.
Changing addHeaders signature lead to massive change of it unit tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Then just inline the couple lines into the HTTP proxy and use the integration test to test it.
Looks good. One last request. Can you split this up into just two commits? One for the vendored in library and one for the feature change? I don't want to squash those two. |
Once you're done pls force push the change so that it replaces the current list of commits. |
specifying header name for adding unique ID to each http request proxied by fabio. This header value can be logged in fabio access log and used for request processing tracking across different request handling applications.
This patch add proxy.header.requestid configuration option for specifying header name for adding unique ID to each http request proxied by fabio. This header value can be logged in fabio access log and used for request processing tracking across different request handling applications.
merged it. |
@bkmit Thanks for your patience :) |
@magiconair Many thanks for your patience! This was my first public golang development (micro) project! |
For that the quality was quite high! Hats off. |
This patch add proxy.header.uniquerequestid configuration option for
specifying header name for adding unique ID to each http request proxied by
fabio.
This header value can be logged in fabio access log and used for request
processing tracking across different applications.