From a86f4ede8d022739e249553c14eb80583bd3758f Mon Sep 17 00:00:00 2001 From: lianggao Date: Fri, 10 Jan 2025 15:12:13 +0800 Subject: [PATCH] =?UTF-8?q?add-http=5Fresponse=20=E6=B7=BB=E5=8A=A0trace?= =?UTF-8?q?=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- conf/input.http_response/http_response.toml | 8 +++- go.mod | 2 +- go.sum | 2 + inputs/http_response/http_response.go | 45 ++++++++++++++++++++- 4 files changed, 54 insertions(+), 3 deletions(-) diff --git a/conf/input.http_response/http_response.toml b/conf/input.http_response/http_response.toml index a44363cd..c4f7cd96 100644 --- a/conf/input.http_response/http_response.toml +++ b/conf/input.http_response/http_response.toml @@ -9,7 +9,6 @@ [[instances]] targets = [ # "http://localhost", -# "https://www.baidu.com" ] ## append some labels for series @@ -30,6 +29,13 @@ targets = [ ## Set response_timeout (default 5 seconds) # response_timeout = "5s" +## enalbe http trace(defaults to false) +## add traceid for traceing +## add http_response_remote_addr for remote add and port +## add fields http_response_dns_time -> http_response_connect_time -> http_response_tls_time -> http_response_first_response_time -> http_response_end_response_time +## all the fields add equal to http_response_response_time +#trace = false + ## Whether to follow redirects from the server (defaults to false) # follow_redirects = false diff --git a/go.mod b/go.mod index 6a127d19..2b432b0b 100644 --- a/go.mod +++ b/go.mod @@ -247,7 +247,7 @@ require ( github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/gopacket v1.1.19 - github.com/google/uuid v1.4.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/gophercloud/gophercloud v1.0.0 // indirect diff --git a/go.sum b/go.sum index 42dcb2b1..020ad3cc 100644 --- a/go.sum +++ b/go.sum @@ -1182,6 +1182,8 @@ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= diff --git a/inputs/http_response/http_response.go b/inputs/http_response/http_response.go index 846995ab..3f9a25ca 100644 --- a/inputs/http_response/http_response.go +++ b/inputs/http_response/http_response.go @@ -1,12 +1,14 @@ package http_response import ( + "crypto/tls" "errors" "fmt" "io" "log" "net" "net/http" + "net/http/httptrace" "net/url" "regexp" "strings" @@ -18,6 +20,7 @@ import ( "flashcat.cloud/categraf/pkg/httpx" "flashcat.cloud/categraf/pkg/netx" "flashcat.cloud/categraf/types" + "github.com/google/uuid" ) const ( @@ -44,6 +47,7 @@ type Instance struct { ExpectResponseRegularExpression string `toml:"expect_response_regular_expression"` ExpectResponseStatusCode *int `toml:"expect_response_status_code"` ExpectResponseStatusCodes string `toml:"expect_response_status_codes"` + Trace *bool `toml:"trace"` config.HTTPProxy client httpClient @@ -192,7 +196,13 @@ func (ins *Instance) gather(slist *types.SampleList, target string) { log.Println("D! http_response... target:", target) } - labels := map[string]string{"target": target} + var labels map[string]string + if ins.Trace != nil && *ins.Trace { + traceid := uuid.New().String() + labels = map[string]string{"target": target, "traceid": traceid} + } else { + labels = map[string]string{"target": target} + } fields := map[string]interface{}{} // Add extra tags in batches if m, ok := ins.Mappings[target]; ok { @@ -248,9 +258,42 @@ func (ins *Instance) httpGather(target string) (map[string]string, map[string]in // Start Timer start := time.Now() + dns_time := start + conn_time := start + tls_time := start + first_res_time := start + + if ins.Trace != nil && *ins.Trace { + trace := &httptrace.ClientTrace{ + // request + DNSDone: func(info httptrace.DNSDoneInfo) { + dns_time = time.Now() + fields["dns_time"] = time.Since(start).Seconds() + }, + ConnectDone: func(network, addr string, err error) { + conn_time = time.Now() + tags["remote_addr"] = addr + fields["connect_time"] = time.Since(dns_time).Seconds() + }, + TLSHandshakeDone: func(info tls.ConnectionState, err error) { + tls_time = time.Now() + fields["tls_time"] = time.Since(conn_time).Seconds() + }, + GotFirstResponseByte: func() { + first_res_time = time.Now() + if tls_time == start { + fields["first_response_time"] = time.Since(conn_time).Seconds() + } else { + fields["first_response_time"] = time.Since(tls_time).Seconds() + } + }, + } + request = request.WithContext(httptrace.WithClientTrace(request.Context(), trace)) + } resp, err := ins.client.Do(request) // metric: response_time + fields["end_response_time"] = time.Since(first_res_time).Seconds() fields["response_time"] = time.Since(start).Seconds() // If an error in returned, it means we are dealing with a network error, as