Commit 9160789b authored by Matthew Holt's avatar Matthew Holt

telemetry: Make http_user_agent a normalized field

This way we store a short 8-byte hash of the UA instead of the full
string; exactly the same way we store TLS ClientHello info.
parent df7cdc3f
...@@ -65,9 +65,10 @@ func (h *tlsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { ...@@ -65,9 +65,10 @@ func (h *tlsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.listener.helloInfosMu.RUnlock() h.listener.helloInfosMu.RUnlock()
ua := r.Header.Get("User-Agent") ua := r.Header.Get("User-Agent")
uaHash := telemetry.FastHash([]byte(ua))
// report this request's UA in connection with this ClientHello // report this request's UA in connection with this ClientHello
go telemetry.AppendUnique("tls_client_hello_ua:"+caddytls.ClientHelloInfo(info).Key(), ua) go telemetry.AppendUnique("tls_client_hello_ua:"+caddytls.ClientHelloInfo(info).Key(), uaHash)
var checked, mitm bool var checked, mitm bool
if r.Header.Get("X-BlueCoat-Via") != "" || // Blue Coat (masks User-Agent header to generic values) if r.Header.Get("X-BlueCoat-Via") != "" || // Blue Coat (masks User-Agent header to generic values)
......
...@@ -354,7 +354,9 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { ...@@ -354,7 +354,9 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if len(ua) > 512 { if len(ua) > 512 {
ua = ua[:512] ua = ua[:512]
} }
go telemetry.AppendUnique("http_user_agent", ua) uaHash := telemetry.FastHash([]byte(ua)) // this is a normalized field
go telemetry.SetNested("http_user_agent", uaHash, ua)
go telemetry.AppendUnique("http_user_agent_count", uaHash)
go telemetry.Increment("http_request_count") go telemetry.Increment("http_request_count")
// copy the original, unchanged URL into the context // copy the original, unchanged URL into the context
......
...@@ -516,7 +516,7 @@ func (info ClientHelloInfo) Key() string { ...@@ -516,7 +516,7 @@ func (info ClientHelloInfo) Key() string {
if !info.CompressionMethodsUnknown { if !info.CompressionMethodsUnknown {
compressionMethods = fmt.Sprintf("%x", info.CompressionMethods) compressionMethods = fmt.Sprintf("%x", info.CompressionMethods)
} }
return fastHash([]byte(fmt.Sprintf("%x-%x-%s-%s-%x-%x", return telemetry.FastHash([]byte(fmt.Sprintf("%x-%x-%s-%s-%x-%x",
info.Version, info.CipherSuites, extensions, info.Version, info.CipherSuites, extensions,
compressionMethods, info.Curves, info.Points))) compressionMethods, info.Curves, info.Points)))
} }
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
package telemetry package telemetry
import ( import (
"fmt"
"hash/fnv"
"log" "log"
"strings" "strings"
...@@ -276,6 +278,15 @@ func atomicAdd(key string, amount int) { ...@@ -276,6 +278,15 @@ func atomicAdd(key string, amount int) {
bufferMu.Unlock() bufferMu.Unlock()
} }
// FastHash hashes input using a 32-bit hashing algorithm
// that is fast, and returns the hash as a hex-encoded string.
// Do not use this for cryptographic purposes.
func FastHash(input []byte) string {
h := fnv.New32a()
h.Write(input)
return fmt.Sprintf("%x", h.Sum32())
}
// isDisabled returns whether key is // isDisabled returns whether key is
// a disabled metric key. ALL collection // a disabled metric key. ALL collection
// functions should call this and not // functions should call this and not
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment