Openstatus www.openstatus.dev

start logging in checker (#1755)

authored by

Thibault Le Ouay and committed by
GitHub
e90079b5 1a082dbe

+299 -79
+174 -2
apps/checker/cmd/server/main.go
··· 4 4 "context" 5 5 "errors" 6 6 "fmt" 7 + "log/slog" 8 + "math/rand/v2" 7 9 "net/http" 8 10 "os" 9 11 "os/signal" ··· 11 13 "time" 12 14 13 15 "github.com/gin-gonic/gin" 16 + "github.com/google/uuid" 14 17 "github.com/openstatushq/openstatus/apps/checker/handlers" 15 18 16 19 "github.com/openstatushq/openstatus/apps/checker/pkg/logger" 17 20 "github.com/openstatushq/openstatus/apps/checker/pkg/tinybird" 18 21 "github.com/rs/zerolog/log" 22 + "go.opentelemetry.io/contrib/bridges/otelslog" 23 + // otelz "go.opentelemetry.io/contrib/bridges/otelzerolog" 24 + "go.opentelemetry.io/otel/log/global" 25 + "go.opentelemetry.io/otel/attribute" 26 + otlploghttp "go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp" 27 + sdklog "go.opentelemetry.io/otel/sdk/log" 28 + "go.opentelemetry.io/otel/sdk/resource" 29 + semconv "go.opentelemetry.io/otel/semconv/v1.24.0" 19 30 ) 20 31 32 + func shouldSample(event map[string]any) bool { 33 + statusCode, _ := event["status_code"].(int) 34 + durationMs, _ := event["duration_ms"].(int) 35 + 36 + // Always capture: server errors 37 + if statusCode >= 500 { 38 + return true 39 + } 40 + 41 + // Always capture: explicit errors 42 + if _, hasError := event["error"]; hasError { 43 + return true 44 + } 45 + 46 + // Always capture: slow requests (above p99 - 2s threshold) 47 + if durationMs > 2000 { 48 + return true 49 + } 50 + 51 + // Higher sampling for client errors (4xx) - 100% 52 + if statusCode >= 400 && statusCode < 500 { 53 + return true 54 + } 55 + 56 + // Random sample successful, fast requests at 20% 57 + return rand.Float64() < 0.2 58 + } 59 + 60 + // MapToAttrs converts a map[string]any to a slice of slog.Attr 61 + func MapToAttrs(m map[string]any) []slog.Attr { 62 + attrs := make([]slog.Attr, 0, len(m)) 63 + for k, v := range m { 64 + attrs = append(attrs, toAttr(k, v)) 65 + } 66 + return attrs 67 + } 68 + 69 + func toAttr(key string, value any) slog.Attr { 70 + switch v := value.(type) { 71 + case string: 72 + return slog.String(key, v) 73 + case int: 74 + return slog.Int(key, v) 75 + case int64: 76 + return slog.Int64(key, v) 77 + case float64: 78 + return slog.Float64(key, v) 79 + case bool: 80 + return slog.Bool(key, v) 81 + case time.Time: 82 + return slog.Time(key, v) 83 + case time.Duration: 84 + return slog.Duration(key, v) 85 + case map[string]any: 86 + return slog.Group(key, mapToAny(v)...) 87 + default: 88 + return slog.Any(key, v) 89 + } 90 + } 91 + 92 + func mapToAny(m map[string]any) []any { 93 + args := make([]any, 0, len(m)*2) 94 + for k, v := range m { 95 + args = append(args, toAttr(k, v)) 96 + } 97 + return args 98 + } 99 + 100 + func Logger() gin.HandlerFunc { 101 + return func(c *gin.Context) { 102 + startTime := time.Now() 103 + 104 + // Generate or get request ID 105 + requestID := c.GetHeader("X-Request-ID") 106 + if requestID == "" { 107 + requestID = uuid.New().String() 108 + } 109 + c.Set("requestId", requestID) 110 + 111 + // Build wide event context at request start 112 + event := map[string]any{ 113 + "timestamp": startTime.Format(time.RFC3339), 114 + "request_id": requestID, 115 + "method": c.Request.Method, 116 + "path": c.Request.URL.Path, 117 + "url": c.Request.Host + c.Request.URL.String(), 118 + "user_agent": c.GetHeader("User-Agent"), 119 + "content_type": c.GetHeader("Content-Type"), 120 + } 121 + c.Set("event", event) 122 + 123 + // Process request 124 + c.Next() 125 + 126 + // After request - capture response details 127 + duration := time.Since(startTime).Milliseconds() 128 + status := c.Writer.Status() 129 + 130 + event["status_code"] = status 131 + event["duration_ms"] = int(duration) 132 + 133 + // var requestErr error 134 + if len(c.Errors) > 0 { 135 + event["outcome"] = "error" 136 + lastErr := c.Errors.Last() 137 + event["error"] = map[string]any{ 138 + "type": "GinError", 139 + "message": lastErr.Error(), 140 + } 141 + } else { 142 + event["outcome"] = "success" 143 + } 144 + 145 + if shouldSample(event) { 146 + attrs := MapToAttrs(event) 147 + slog.LogAttrs(c.Request.Context(),slog.LevelInfo, "request done", attrs...) 148 + } 149 + 150 + log.Debug(). 151 + Int("status_code", status). 152 + Int64("duration_ms", duration). 153 + Str("request_id", requestID). 154 + Msg("Request completed") 155 + } 156 + } 157 + 21 158 func main() { 22 159 ctx, cancel := context.WithCancel(context.Background()) 23 160 defer cancel() ··· 34 171 var region string 35 172 cronSecret := env("CRON_SECRET", "") 36 173 tinyBirdToken := env("TINYBIRD_TOKEN", "") 37 - logLevel := env("LOG_LEVEL", "warn") 174 + logLevel := env("LOG_LEVEL", "info") 38 175 cloudProvider := env("CLOUD_PROVIDER", "fly") 39 - 176 + axiomToken := env("AXIOM_TOKEN", "") 177 + axiomDataset := env("AXIOM_DATASET", "dev") 40 178 switch cloudProvider { 41 179 case "fly": 42 180 region = env("FLY_REGION", env("REGION", "local")) ··· 51 189 } 52 190 logger.Configure(logLevel) 53 191 192 + // Define resource with service name, version, and environment 193 + res := resource.NewWithAttributes( 194 + semconv.SchemaURL, 195 + semconv.ServiceNameKey.String("openstatus-checker"), 196 + semconv.ServiceVersionKey.String("1.0.0"), 197 + attribute.String("environment", "production"), 198 + attribute.String("cloud.provider", cloudProvider), 199 + attribute.String("cloud.region", region), 200 + ) 201 + 202 + // Set up OTLP log exporter for Axiom 203 + exporter, err := otlploghttp.New(ctx, 204 + otlploghttp.WithEndpointURL("https://eu-central-1.aws.edge.axiom.co/v1/logs"), 205 + otlploghttp.WithHeaders(map[string]string{ 206 + "Authorization": "Bearer " + axiomToken, 207 + "X-Axiom-Dataset": axiomDataset, 208 + }), 209 + ) 210 + if err != nil { 211 + log.Fatal().Err(err).Msg("failed to create OTLP exporter") 212 + } 213 + 214 + // Create log provider with resource and batch processor 215 + logProvider := sdklog.NewLoggerProvider( 216 + sdklog.WithResource(res), 217 + sdklog.WithProcessor(sdklog.NewBatchProcessor(exporter)), 218 + 219 + ) 220 + defer logProvider.Shutdown(ctx) 221 + 222 + global.SetLoggerProvider(logProvider) 223 + slog.SetDefault(otelslog.NewLogger("openstatus-checker")) 54 224 httpClient := &http.Client{ 55 225 Timeout: 45 * time.Second, 56 226 } ··· 67 237 } 68 238 69 239 router := gin.New() 240 + router.Use(gin.Recovery()) 241 + router.Use(Logger()) 70 242 router.POST("/checker", h.HTTPCheckerHandler) 71 243 router.POST("/checker/http", h.HTTPCheckerHandler) 72 244 router.POST("/checker/tcp", h.TCPHandler)
+32 -24
apps/checker/go.mod
··· 6 6 connectrpc.com/connect v1.19.1 7 7 github.com/gin-gonic/gin v1.9.1 8 8 github.com/google/uuid v1.6.0 9 - github.com/rs/zerolog v1.32.0 10 - github.com/stretchr/testify v1.10.0 11 - go.opentelemetry.io/otel v1.36.0 9 + github.com/rs/zerolog v1.34.0 10 + github.com/stretchr/testify v1.11.1 11 + go.opentelemetry.io/otel v1.39.0 12 12 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 13 - go.opentelemetry.io/otel/metric v1.36.0 14 - go.opentelemetry.io/otel/sdk v1.36.0 15 - go.opentelemetry.io/otel/sdk/metric v1.36.0 16 - google.golang.org/protobuf v1.36.10 13 + go.opentelemetry.io/otel/metric v1.39.0 14 + go.opentelemetry.io/otel/sdk v1.39.0 15 + go.opentelemetry.io/otel/sdk/metric v1.39.0 16 + google.golang.org/protobuf v1.36.11 17 17 ) 18 18 19 19 //replace github.com/openstatushq/openstatus/packages/proto => ./../../packages/proto ··· 24 24 github.com/cenkalti/backoff/v4 v4.3.0 25 25 github.com/cenkalti/backoff/v5 v5.0.3 26 26 github.com/madflojo/tasks v1.2.1 27 + github.com/vincentfree/opentelemetry/otelzerolog v0.1.1 28 + go.opentelemetry.io/contrib/bridges/otelslog v0.14.0 29 + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.15.0 30 + go.opentelemetry.io/otel/sdk/log v0.15.0 27 31 google.golang.org/api v0.247.0 28 32 ) 29 33 30 34 require ( 31 35 cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect 32 - cloud.google.com/go/compute/metadata v0.8.0 // indirect 36 + cloud.google.com/go/compute/metadata v0.9.0 // indirect 33 37 cloud.google.com/go/iam v1.5.2 // indirect 34 38 github.com/bytedance/sonic v1.11.3 // indirect 39 + github.com/cespare/xxhash/v2 v2.3.0 // indirect 35 40 github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect 36 41 github.com/chenzhuoyu/iasm v0.9.1 // indirect 37 42 github.com/davecgh/go-spew v1.1.1 // indirect ··· 47 52 github.com/google/s2a-go v0.1.9 // indirect 48 53 github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect 49 54 github.com/googleapis/gax-go/v2 v2.15.0 // indirect 50 - github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect 55 + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 // indirect 51 56 github.com/json-iterator/go v1.1.12 // indirect 52 57 github.com/klauspost/cpuid/v2 v2.2.7 // indirect 53 58 github.com/leodido/go-urn v1.4.0 // indirect 54 - github.com/mattn/go-colorable v0.1.13 // indirect 59 + github.com/mattn/go-colorable v0.1.14 // indirect 55 60 github.com/mattn/go-isatty v0.0.20 // indirect 56 61 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 57 62 github.com/modern-go/reflect2 v1.0.2 // indirect 58 - github.com/pelletier/go-toml/v2 v2.2.0 // indirect 63 + github.com/pelletier/go-toml/v2 v2.2.4 // indirect 59 64 github.com/pmezard/go-difflib v1.0.0 // indirect 60 65 github.com/rs/xid v1.6.0 // indirect 61 66 github.com/twitchyliquid64/golang-asm v0.15.1 // indirect 62 67 github.com/ugorji/go/codec v1.2.12 // indirect 63 - go.opentelemetry.io/auto/sdk v1.1.0 // indirect 68 + go.opentelemetry.io/auto/sdk v1.2.1 // indirect 69 + go.opentelemetry.io/contrib/bridges/otelzerolog v0.0.0-20240726205214-b0584291236a // indirect 64 70 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect 65 - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect 66 - go.opentelemetry.io/otel/trace v1.36.0 // indirect 67 - go.opentelemetry.io/proto/otlp v1.5.0 // indirect 71 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 // indirect 72 + go.opentelemetry.io/otel/log v0.15.0 // indirect 73 + go.opentelemetry.io/otel/log/logtest v0.15.0 // indirect 74 + go.opentelemetry.io/otel/trace v1.39.0 // indirect 75 + go.opentelemetry.io/proto/otlp v1.9.0 // indirect 68 76 golang.org/x/arch v0.7.0 // indirect 69 - golang.org/x/crypto v0.41.0 // indirect 70 - golang.org/x/net v0.43.0 // indirect 71 - golang.org/x/oauth2 v0.30.0 // indirect 72 - golang.org/x/sync v0.16.0 // indirect 73 - golang.org/x/sys v0.35.0 // indirect 74 - golang.org/x/text v0.28.0 // indirect 77 + golang.org/x/crypto v0.46.0 // indirect 78 + golang.org/x/net v0.48.0 // indirect 79 + golang.org/x/oauth2 v0.32.0 // indirect 80 + golang.org/x/sync v0.19.0 // indirect 81 + golang.org/x/sys v0.39.0 // indirect 82 + golang.org/x/text v0.32.0 // indirect 75 83 golang.org/x/time v0.12.0 // indirect 76 84 google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect 77 - google.golang.org/genproto/googleapis/api v0.0.0-20250818200422-3122310a409c // indirect 78 - google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c // indirect 79 - google.golang.org/grpc v1.74.2 // indirect 85 + google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 // indirect 86 + google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 // indirect 87 + google.golang.org/grpc v1.77.0 // indirect 80 88 gopkg.in/yaml.v3 v3.0.1 // indirect 81 89 )
+81 -53
apps/checker/go.sum
··· 4 4 cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= 5 5 cloud.google.com/go/cloudtasks v1.13.7 h1:H2v8GEolNtMFfYzUpZBaZbydqU7drpyo99GtAgA+m4I= 6 6 cloud.google.com/go/cloudtasks v1.13.7/go.mod h1:H0TThOUG+Ml34e2+ZtW6k6nt4i9KuH3nYAJ5mxh7OM4= 7 - cloud.google.com/go/compute/metadata v0.8.0 h1:HxMRIbao8w17ZX6wBnjhcDkW6lTFpgcaobyVfZWqRLA= 8 - cloud.google.com/go/compute/metadata v0.8.0/go.mod h1:sYOGTp851OV9bOFJ9CH7elVvyzopvWQFNNghtDQ/Biw= 7 + cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= 8 + cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= 9 9 cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8= 10 10 cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE= 11 11 connectrpc.com/connect v1.19.1 h1:R5M57z05+90EfEvCY1b7hBxDVOUl45PrtXtAV2fOC14= ··· 18 18 github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= 19 19 github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= 20 20 github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= 21 + github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= 22 + github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 21 23 github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= 22 24 github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= 23 25 github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= ··· 25 27 github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= 26 28 github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0= 27 29 github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= 30 + github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f h1:Y8xYupdHxryycyPlc9Y+bSQAYZnetRJ70VMVKm5CKI0= 31 + github.com/cncf/xds/go v0.0.0-20251022180443-0feb69152e9f/go.mod h1:HlzOvOjVBOfTGSRXRyY0OiCS/3J1akRGQQpRO/7zyF4= 28 32 github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 29 33 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 30 34 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 31 35 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 36 + github.com/envoyproxy/go-control-plane v0.13.5-0.20251024222203-75eaa193e329 h1:K+fnvUM0VZ7ZFJf0n4L/BRlnsb9pL/GuDG6FqaH+PwM= 37 + github.com/envoyproxy/go-control-plane/envoy v1.35.0 h1:ixjkELDE+ru6idPxcHLj8LBVc2bFP7iBytj353BoHUo= 38 + github.com/envoyproxy/go-control-plane/envoy v1.35.0/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs= 39 + github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= 40 + github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= 32 41 github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= 33 42 github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= 34 43 github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= ··· 66 75 github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= 67 76 github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo= 68 77 github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc= 69 - github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg= 70 - github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ= 78 + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 h1:NmZ1PKzSTQbuGHw9DGPFomqkkLWMC+vZCkfs+FHv1Vg= 79 + github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3/go.mod h1:zQrxl1YP88HQlA6i9c63DSVPFklWpGX4OWAc9bFuaH4= 71 80 github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= 72 81 github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= 73 82 github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= ··· 82 91 github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= 83 92 github.com/madflojo/tasks v1.2.1 h1:0HMN1RCVf6yDjrlIbthkET1KCB+gxknQG3/SLO+HHj4= 84 93 github.com/madflojo/tasks v1.2.1/go.mod h1:/WMv6u3Xb5eyy+aIM76ildaIT166GOxN/jya9oI7dyo= 85 - github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= 86 94 github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= 95 + github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= 96 + github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= 87 97 github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 88 98 github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 89 99 github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= ··· 93 103 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 94 104 github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= 95 105 github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= 96 - github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo= 97 - github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= 106 + github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= 107 + github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= 98 108 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 109 + github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= 110 + github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= 99 111 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 100 112 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 101 - github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= 102 - github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= 103 - github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= 113 + github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= 114 + github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= 104 115 github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= 105 116 github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= 106 - github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= 107 - github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= 117 + github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= 118 + github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= 108 119 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 109 120 github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 110 121 github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 111 - github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= 112 122 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 113 123 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 114 124 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 115 125 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 116 126 github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= 117 - github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 118 - github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 119 - github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 120 - github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 127 + github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= 128 + github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= 121 129 github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= 122 130 github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= 123 131 github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= 124 132 github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= 125 - go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= 126 - go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= 133 + github.com/vincentfree/opentelemetry/otelzerolog v0.1.1 h1:JwLECM8a+sxQGtFjREmkUzfXlQGmmeIqq9THUbMfuLo= 134 + github.com/vincentfree/opentelemetry/otelzerolog v0.1.1/go.mod h1:nm1JiUG5YGpuAQMqoLLoU50oBBGxJ7R58Zpcp5cJ6LQ= 135 + go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= 136 + go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= 137 + go.opentelemetry.io/contrib/bridges/otelslog v0.14.0 h1:eypSOd+0txRKCXPNyqLPsbSfA0jULgJcGmSAdFAnrCM= 138 + go.opentelemetry.io/contrib/bridges/otelslog v0.14.0/go.mod h1:CRGvIBL/aAxpQU34ZxyQVFlovVcp67s4cAmQu8Jh9mc= 139 + go.opentelemetry.io/contrib/bridges/otelzerolog v0.0.0-20240726205214-b0584291236a h1:8EYSlvUrF1q+5XFBpUAz1XkYg3XAyBSqru0d1IZdLlk= 140 + go.opentelemetry.io/contrib/bridges/otelzerolog v0.0.0-20240726205214-b0584291236a/go.mod h1:IrTzekhe/C6xdedbc0jIDhWMMPvXiF63Lj6JaVogekU= 127 141 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ= 128 142 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo= 129 - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= 130 - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= 131 - go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= 132 - go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= 143 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 h1:ssfIgGNANqpVFCndZvcuyKbl0g+UAVcbBcqGkG28H0Y= 144 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0/go.mod h1:GQ/474YrbE4Jx8gZ4q5I4hrhUzM6UPzyrqJYV2AqPoQ= 145 + go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= 146 + go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= 147 + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.15.0 h1:EKpiGphOYq3CYnIe2eX9ftUkyU+Y8Dtte8OaWyHJ4+I= 148 + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.15.0/go.mod h1:nWFP7C+T8TygkTjJ7mAyEaFaE7wNfms3nV/vexZ6qt0= 133 149 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0 h1:opwv08VbCZ8iecIWs+McMdHRcAXzjAeda3uG2kI/hcA= 134 150 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.34.0/go.mod h1:oOP3ABpW7vFHulLpE8aYtNBodrHhMTrvfxUXGvqm7Ac= 135 - go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE= 136 - go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= 137 - go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs= 138 - go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= 139 - go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis= 140 - go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= 141 - go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= 142 - go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= 143 - go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= 144 - go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= 151 + go.opentelemetry.io/otel/log v0.15.0 h1:0VqVnc3MgyYd7QqNVIldC3dsLFKgazR6P3P3+ypkyDY= 152 + go.opentelemetry.io/otel/log v0.15.0/go.mod h1:9c/G1zbyZfgu1HmQD7Qj84QMmwTp2QCQsZH1aeoWDE4= 153 + go.opentelemetry.io/otel/log/logtest v0.15.0 h1:porNFuxAjodl6LhePevOc3n7bo3Wi3JhGXNWe7KP8iU= 154 + go.opentelemetry.io/otel/log/logtest v0.15.0/go.mod h1:c8epqBXGHgS1LiNgmD+LuNYK9lSS3mqvtMdxLsfJgLg= 155 + go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= 156 + go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= 157 + go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= 158 + go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= 159 + go.opentelemetry.io/otel/sdk/log v0.15.0 h1:WgMEHOUt5gjJE93yqfqJOkRflApNif84kxoHWS9VVHE= 160 + go.opentelemetry.io/otel/sdk/log v0.15.0/go.mod h1:qDC/FlKQCXfH5hokGsNg9aUBGMJQsrUyeOiW5u+dKBQ= 161 + go.opentelemetry.io/otel/sdk/log/logtest v0.14.0 h1:Ijbtz+JKXl8T2MngiwqBlPaHqc4YCaP/i13Qrow6gAM= 162 + go.opentelemetry.io/otel/sdk/log/logtest v0.14.0/go.mod h1:dCU8aEL6q+L9cYTqcVOk8rM9Tp8WdnHOPLiBgp0SGOA= 163 + go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= 164 + go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= 165 + go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= 166 + go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= 167 + go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= 168 + go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= 145 169 golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= 146 170 golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc= 147 171 golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= 148 - golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= 149 - golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= 150 - golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= 151 - golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= 152 - golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= 153 - golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= 154 - golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= 155 - golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 172 + golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= 173 + golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= 174 + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= 175 + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= 176 + golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= 177 + golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= 178 + golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY= 179 + golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= 180 + golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= 181 + golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= 156 182 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 157 183 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 158 184 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 159 185 golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 160 - golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= 161 - golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 162 - golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= 163 - golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= 186 + golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= 187 + golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= 188 + golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= 189 + golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= 164 190 golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= 165 191 golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= 192 + gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= 193 + gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= 166 194 google.golang.org/api v0.247.0 h1:tSd/e0QrUlLsrwMKmkbQhYVa109qIintOls2Wh6bngc= 167 195 google.golang.org/api v0.247.0/go.mod h1:r1qZOPmxXffXg6xS5uhx16Fa/UFY8QU/K4bfKrnvovM= 168 196 google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4= 169 197 google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s= 170 - google.golang.org/genproto/googleapis/api v0.0.0-20250818200422-3122310a409c h1:AtEkQdl5b6zsybXcbz00j1LwNodDuH6hVifIaNqk7NQ= 171 - google.golang.org/genproto/googleapis/api v0.0.0-20250818200422-3122310a409c/go.mod h1:ea2MjsO70ssTfCjiwHgI0ZFqcw45Ksuk2ckf9G468GA= 172 - google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c h1:qXWI/sQtv5UKboZ/zUk7h+mrf/lXORyI+n9DKDAusdg= 173 - google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c/go.mod h1:gw1tLEfykwDz2ET4a12jcXt4couGAm7IwsVaTy0Sflo= 174 - google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4= 175 - google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM= 176 - google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= 177 - google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= 198 + google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 h1:7LRqPCEdE4TP4/9psdaB7F2nhZFfBiGJomA5sojLWdU= 199 + google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto= 200 + google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2 h1:2I6GHUeJ/4shcDpoUlLs/2WPnhg7yJwvXtqcMJt9liA= 201 + google.golang.org/genproto/googleapis/rpc v0.0.0-20251213004720-97cd9d5aeac2/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= 202 + google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= 203 + google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= 204 + google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= 205 + google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= 178 206 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 179 207 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 180 208 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
+12
apps/checker/handlers/tcp.go
··· 86 86 trigger = req.Trigger 87 87 } 88 88 89 + e, f := c.Get("event") 90 + if f { 91 + t := e.(map[string]any) 92 + t["checker"] = map[string]string{ 93 + "uri": req.URI, 94 + "workspace_id": req.WorkspaceID, 95 + "monitor_id":req.MonitorID, 96 + "trigger": trigger, 97 + } 98 + c.Set("event", t) 99 + } 100 + 89 101 var response checker.TCPResponse 90 102 91 103 var retry int