From 3853ec19f7c283aa207ddc274590a78dca163a43 Mon Sep 17 00:00:00 2001 From: Vaidas Jablonskis Date: Mon, 4 Mar 2024 14:28:03 +0200 Subject: [PATCH] Add initial code instrumentation with honeycomb --- go.mod | 29 ++++- go.sum | 65 ++++++++++ internal/otelx/otel.go | 16 +++ internal/source/ai-brain/assistant.go | 27 ++++- internal/source/ai-brain/brain.go | 20 +++- internal/source/ai-brain/config.go | 2 + internal/source/ai-brain/config_schema.json | 126 +++++++++++--------- 7 files changed, 222 insertions(+), 63 deletions(-) create mode 100644 internal/otelx/otel.go diff --git a/go.mod b/go.mod index fadb2505..1655f9ea 100644 --- a/go.mod +++ b/go.mod @@ -22,6 +22,8 @@ require ( github.com/hashicorp/go-getter v1.7.1 github.com/hashicorp/go-plugin v1.4.10 github.com/hasura/go-graphql-client v0.8.1 + github.com/honeycombio/honeycomb-opentelemetry-go v0.9.0 + github.com/honeycombio/otel-config-go v1.13.1 github.com/huandu/xstrings v1.4.0 github.com/keptn/go-utils v0.20.4 github.com/kubeshop/botkube v0.13.1-0.20240219113106-577e1e800cff @@ -33,6 +35,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.4 + go.opentelemetry.io/otel v1.21.0 golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 golang.org/x/oauth2 v0.15.0 gopkg.in/yaml.v3 v3.0.1 @@ -62,6 +65,7 @@ require ( github.com/benbjohnson/clock v1.3.5 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bytedance/sonic v1.9.1 // indirect + github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect github.com/cloudflare/circl v1.3.7 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -80,6 +84,7 @@ require ( github.com/go-errors/errors v1.4.2 // indirect github.com/go-logr/logr v1.3.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect github.com/go-openapi/swag v0.22.3 // indirect @@ -99,6 +104,7 @@ require ( github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect @@ -116,6 +122,7 @@ require ( github.com/knadh/koanf v1.4.5 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect + github.com/lufia/plan9stats v0.0.0-20231016141302-07b5767bb0ed // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -138,14 +145,20 @@ require ( github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect github.com/prometheus/common v0.44.0 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sanity-io/litter v1.5.5 // indirect + github.com/sethvargo/go-envconfig v0.9.0 // indirect + github.com/shirou/gopsutil/v3 v3.23.10 // indirect + github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/shopspring/decimal v1.3.1 // indirect github.com/spf13/cast v1.5.0 // indirect github.com/spf13/cobra v1.7.0 // indirect github.com/spiffe/spire v1.5.6 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect github.com/ulikunitz/xz v0.5.10 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect @@ -153,12 +166,26 @@ require ( github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/xlab/treeprint v1.2.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect + github.com/yusufpapurcu/wmi v1.2.3 // indirect go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/contrib/instrumentation/host v0.46.1 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0 // indirect - go.opentelemetry.io/otel v1.21.0 // indirect + go.opentelemetry.io/contrib/instrumentation/runtime v0.46.1 // indirect + go.opentelemetry.io/contrib/propagators/b3 v1.21.1 // indirect + go.opentelemetry.io/contrib/propagators/ot v1.21.1 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.44.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.44.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 // indirect go.opentelemetry.io/otel/metric v1.21.0 // indirect + go.opentelemetry.io/otel/sdk v1.21.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.21.0 // indirect go.opentelemetry.io/otel/trace v1.21.0 // indirect + go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect + go.uber.org/multierr v1.11.0 // indirect golang.org/x/arch v0.3.0 // indirect golang.org/x/crypto v0.17.0 // indirect golang.org/x/net v0.19.0 // indirect diff --git a/go.sum b/go.sum index e712cbee..e9df3e15 100644 --- a/go.sum +++ b/go.sum @@ -256,6 +256,8 @@ github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7N github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= @@ -374,6 +376,9 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= @@ -544,6 +549,8 @@ github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJr github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1 h1:6UKoz5ujsI55KNpsJH3UwCq3T8kKbZwNZBNPuTTje8U= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1/go.mod h1:YvJ2f6MplWDhfxiUC3KpyTy76kYUZA4W3pTv/wdKQ9Y= github.com/hashicorp/consul/api v1.13.0/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m72FhPvA8T35KQ= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -601,6 +608,10 @@ github.com/hasura/go-graphql-client v0.8.1 h1:yU4888urgkW4L47cs+QQDXl3YfVaNraUqy github.com/hasura/go-graphql-client v0.8.1/go.mod h1:NVifIwv+YFIUYGLQ7SM2/vBbzS/9rFP4vmIf/vf/zXM= github.com/hjson/hjson-go/v4 v4.0.0 h1:wlm6IYYqHjOdXH1gHev4VoXCaW20HdQAGCxdOEEg2cs= github.com/hjson/hjson-go/v4 v4.0.0/go.mod h1:KaYt3bTw3zhBjYqnXkYywcYctk0A2nxeEFTse3rH13E= +github.com/honeycombio/honeycomb-opentelemetry-go v0.9.0 h1:bAGMaYq2ankgZz2sVlvNpmD78hJX4NcRL8zLa9ZpVbI= +github.com/honeycombio/honeycomb-opentelemetry-go v0.9.0/go.mod h1:+Q3U4m5G1flxRUnAJ2FHIwuQ93mHu1881NpJ7pZLr30= +github.com/honeycombio/otel-config-go v1.13.1 h1:JYERH81ChVB4vH3Jmo8ifAkeKhVRD85uaaLLpm4MzY0= +github.com/honeycombio/otel-config-go v1.13.1/go.mod h1:5hRpKBVO2cMXBaonDmr6KHYB2N/Q5AD3hr7+PVJQOx0= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= @@ -669,6 +680,9 @@ github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= +github.com/lufia/plan9stats v0.0.0-20231016141302-07b5767bb0ed h1:036IscGBfJsFIgJQzlui7nK1Ncm0tp2ktmPj8xO4N/0= +github.com/lufia/plan9stats v0.0.0-20231016141302-07b5767bb0ed/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -776,6 +790,9 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b h1:0LFwY6Q3gMACTjAbMZBjXAqTOzOwFaj2Ld6cjeQ7Rig= +github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= @@ -822,6 +839,14 @@ github.com/sclevine/spec v1.4.0/go.mod h1:LvpgJaFyvQzRvc1kaDs0bulYwzC70PbiYjC4Qn github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/sethvargo/go-envconfig v0.9.0 h1:Q6FQ6hVEeTECULvkJZakq3dZMeBQ3JUpcKMfPQbKMDE= +github.com/sethvargo/go-envconfig v0.9.0/go.mod h1:Iz1Gy1Sf3T64TQlJSvee81qDhf7YIlt8GMUX6yyNFs0= +github.com/shirou/gopsutil/v3 v3.23.10 h1:/N42opWlYzegYaVkWejXWJpbzKv2JDy3mrgGzKsh9hM= +github.com/shirou/gopsutil/v3 v3.23.10/go.mod h1:JIE26kpucQi+innVlAUnIEOSBhBUkirr5b44yr55+WE= +github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= +github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= +github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= +github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= @@ -864,6 +889,10 @@ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= @@ -890,6 +919,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= +github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= @@ -902,22 +933,52 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/contrib/detectors/aws/lambda v0.46.1 h1:MCtkJ76UiXEphmYGj+C2MB20viwYjEHVn+I+2qq7/os= +go.opentelemetry.io/contrib/detectors/aws/lambda v0.46.1/go.mod h1:mb4RYmSIT8466N536PZ1z3FLiBwiwvX81AisUfgqgyE= +go.opentelemetry.io/contrib/instrumentation/host v0.46.1 h1:jLPv7OPP2CROWQ8PaUx3zONn5S4HjCJnH1syT3fnEEc= +go.opentelemetry.io/contrib/instrumentation/host v0.46.1/go.mod h1:7PhaLiZ6K9zbeZNxOdr+DB8tzxWsrjVa9BcCMGuMPeA= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0 h1:KfYpVmrjI7JuToy5k8XV3nkapjWx48k4E4JOtVstzQI= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0/go.mod h1:SeQhzAEccGVZVEy7aH87Nh0km+utSpo1pTv6eMMop48= +go.opentelemetry.io/contrib/instrumentation/runtime v0.46.1 h1:m9ReioVPIffxjJlGNRd0d5poy+9oTro3D+YbiEzUDOc= +go.opentelemetry.io/contrib/instrumentation/runtime v0.46.1/go.mod h1:CANkrsXNzqOKXfOomu2zhOmc1/J5UZK9SGjrat6ZCG0= +go.opentelemetry.io/contrib/propagators/b3 v1.21.1 h1:WPYiUgmw3+b7b3sQ1bFBFAf0q+Di9dvNc3AtYfnT4RQ= +go.opentelemetry.io/contrib/propagators/b3 v1.21.1/go.mod h1:EmzokPoSqsYMBVK4nRnhsfm5mbn8J1eDuz/U1UaQaWg= +go.opentelemetry.io/contrib/propagators/ot v1.21.1 h1:3TN5vkXjKYWp0YdMcnUEC/A+pBPvqz9V3nCS2xmcurk= +go.opentelemetry.io/contrib/propagators/ot v1.21.1/go.mod h1:oy0MYCbS/b3cqUDW37wBWtlwBIsutngS++Lklpgh+fc= go.opentelemetry.io/otel v1.6.3/go.mod h1:7BgNga5fNlF/iZjG06hM3yofffp0ofKCDwSXx1GC4dI= go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.44.0 h1:jd0+5t/YynESZqsSyPz+7PAFdEop0dlN0+PkyHYo8oI= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.44.0/go.mod h1:U707O40ee1FpQGyhvqnzmCJm1Wh6OX6GGBVn0E6Uyyk= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.44.0 h1:bflGWrfYyuulcdxf14V6n9+CoQcu5SAAdHmDPAJnlps= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.44.0/go.mod h1:qcTO4xHAxZLaLxPd60TdE88rxtItPHgHWqOhOGRr0as= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 h1:digkEZCJWobwBqMwC0cwCq8/wkkRy/OowZg5OArWZrM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 h1:VhlEQAPp9R1ktYfrPk5SOryw1e9LDDTZCbIPFrho0ec= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0/go.mod h1:kB3ufRbfU+CQ4MlUcqtW8Z7YEOBeK2DJ6CmR5rYYF3E= go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= +go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= +go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/sdk/metric v1.21.0 h1:smhI5oD714d6jHE6Tie36fPx4WDFIg+Y6RfAY4ICcR0= +go.opentelemetry.io/otel/sdk/metric v1.21.0/go.mod h1:FJ8RAsoPGv/wYMgBdUJXOm+6pzFY3YdljnXtv1SBE8Q= go.opentelemetry.io/otel/trace v1.6.3/go.mod h1:GNJQusJlUgZl9/TQBPKU/Y/ty+0iVB5fjhKeJGZPGFs= go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= +go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= @@ -1102,6 +1163,7 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1132,6 +1194,7 @@ golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1180,6 +1243,8 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/internal/otelx/otel.go b/internal/otelx/otel.go new file mode 100644 index 00000000..db8a85f5 --- /dev/null +++ b/internal/otelx/otel.go @@ -0,0 +1,16 @@ +package otelx + +import ( + "github.com/honeycombio/honeycomb-opentelemetry-go" + "github.com/honeycombio/otel-config-go/otelconfig" +) + +// Init initialises opentelemetry with honeycomb exporter. Returns a shutdown func. +func Init(apiKey, serviceName string, sampleRate int) (func(), error) { + return otelconfig.ConfigureOpenTelemetry( + otelconfig.WithSpanProcessor(honeycomb.NewBaggageSpanProcessor()), + otelconfig.WithHeaders(map[string]string{"X-Honeycomb-Team": apiKey}), + otelconfig.WithServiceName(serviceName), + otelconfig.WithSampler(honeycomb.NewDeterministicSampler(sampleRate)), + ) +} diff --git a/internal/source/ai-brain/assistant.go b/internal/source/ai-brain/assistant.go index 28e0f7e1..2caefce0 100644 --- a/internal/source/ai-brain/assistant.go +++ b/internal/source/ai-brain/assistant.go @@ -10,6 +10,7 @@ import ( "time" "github.com/kubeshop/botkube-cloud-plugins/internal/remote" + "go.opentelemetry.io/otel/attribute" "github.com/kubeshop/botkube/pkg/api" "github.com/kubeshop/botkube/pkg/api/source" @@ -65,7 +66,7 @@ func newAssistant(cfg *Config, log logrus.FieldLogger, out chan source.Event, ku } } -func (i *assistant) handle(in source.ExternalRequestInput) (api.Message, error) { +func (i *assistant) handle(ctx context.Context, in source.ExternalRequestInput) (api.Message, error) { var p Payload err := json.Unmarshal(in.Payload, &p) @@ -78,7 +79,7 @@ func (i *assistant) handle(in source.ExternalRequestInput) (api.Message, error) } go func() { - if err := i.handleThread(context.Background(), &p); err != nil { + if err := i.handleThread(ctx, &p); err != nil { // TODO: It would be great to send the user prompt and error message // back to us for analysis and potential fixing, enhancing our prompt. // can we do that @Blair? @@ -92,17 +93,22 @@ func (i *assistant) handle(in source.ExternalRequestInput) (api.Message, error) // handleThread creates a new OpenAI assistant thread and handles the conversation. func (i *assistant) handleThread(ctx context.Context, p *Payload) error { + ctx, span := tracer.Start(ctx, "aibrain.assistant.handleThread") + defer span.End() + var thread openai.Thread var err error // First we check if we have a cached thread ID for the given message ID. threadID, ok := i.cache.Get(p.MessageID) if ok { + span.AddEvent("Found an existing thread in the internal cache.") err = i.createNewMessage(ctx, threadID, p) if err != nil { return fmt.Errorf("while creating a new message on a thread: %w", err) } } else { + span.AddEvent("Existing thread was not found in the internal cache.") thread, err = i.createNewThread(ctx, p) if err != nil { return fmt.Errorf("while creating a new thread: %w", err) @@ -110,6 +116,11 @@ func (i *assistant) handleThread(ctx context.Context, p *Payload) error { threadID = thread.ID } + span.SetAttributes( + attribute.String("assistant.threadId", threadID), + attribute.String("payload.messageId", p.MessageID), + ) + i.cache.Set(p.MessageID, threadID) run, err := i.openaiClient.CreateRun(ctx, threadID, openai.RunRequest{ @@ -159,6 +170,9 @@ func (i *assistant) handleThread(ctx context.Context, p *Payload) error { } func (i *assistant) createNewThread(ctx context.Context, p *Payload) (openai.Thread, error) { + ctx, span := tracer.Start(ctx, "aibrain.assistant.createNewThread") + defer span.End() + return i.openaiClient.CreateThread(ctx, openai.ThreadRequest{ Metadata: map[string]any{ "messageId": p.MessageID, @@ -174,6 +188,9 @@ func (i *assistant) createNewThread(ctx context.Context, p *Payload) (openai.Thr } func (i *assistant) createNewMessage(ctx context.Context, threadID string, p *Payload) error { + ctx, span := tracer.Start(ctx, "aibrain.assistant.createNewMessage") + defer span.End() + _, err := i.openaiClient.CreateMessage(ctx, threadID, openai.MessageRequest{ Role: openai.ChatMessageRoleUser, Content: p.Prompt, @@ -182,6 +199,9 @@ func (i *assistant) createNewMessage(ctx context.Context, threadID string, p *Pa } func (i *assistant) handleStatusCompleted(ctx context.Context, run openai.Run, p *Payload) error { + ctx, span := tracer.Start(ctx, "aibrain.assistant.handleStatusCompleted") + defer span.End() + limit := 1 msgList, err := i.openaiClient.ListMessage(ctx, run.ThreadID, &limit, nil, nil, nil) if err != nil { @@ -215,6 +235,9 @@ func (i *assistant) handleStatusCompleted(ctx context.Context, run openai.Run, p } func (i *assistant) handleStatusRequiresAction(ctx context.Context, run openai.Run) error { + ctx, span := tracer.Start(ctx, "aibrain.assistant.handleStatusRequiresAction") + defer span.End() + // That should never happen, unless there is a bug or something is wrong with OpenAI APIs. if run.RequiredAction == nil || run.RequiredAction.SubmitToolOutputs == nil { return errors.New("run.RequiredAction or run.RequiredAction.SubmitToolOutputs is nil, that should not happen") diff --git a/internal/source/ai-brain/brain.go b/internal/source/ai-brain/brain.go index 4f651336..c404578f 100644 --- a/internal/source/ai-brain/brain.go +++ b/internal/source/ai-brain/brain.go @@ -6,11 +6,14 @@ import ( "fmt" "sync" + "github.com/kubeshop/botkube-cloud-plugins/internal/otelx" "github.com/kubeshop/botkube/pkg/api" "github.com/kubeshop/botkube/pkg/api/source" "github.com/kubeshop/botkube/pkg/loggerx" pluginx "github.com/kubeshop/botkube/pkg/plugin" + "github.com/sirupsen/logrus" + "go.opentelemetry.io/otel" ) const ( @@ -27,6 +30,8 @@ var ( //go:embed webhook_schema.json IncomingWebhookJSONSchema string + + tracer = otel.Tracer("source.aibrain") ) // Source implements AI source plugin. @@ -83,6 +88,14 @@ func (s *Source) Stream(ctx context.Context, in source.StreamInput) (source.Stre sourceName := in.Context.SourceName + // Set up opentelemetry with honeycomb if enabled. + if cfg.HoneycombAPIKey != "" { + otelServiceName := "plugins-source-" + sourceName + shutdown, err := otelx.Init(cfg.HoneycombAPIKey, otelServiceName, cfg.HoneycombSampleRate) + s.log.WithError(err).Error("failed to initilise otel with honeycomb") + defer shutdown() + } + streamOutput := source.StreamOutput{ Event: make(chan source.Event), } @@ -99,14 +112,17 @@ func (s *Source) Stream(ctx context.Context, in source.StreamInput) (source.Stre } // HandleExternalRequest handles incoming payload and returns an event based on it. -func (s *Source) HandleExternalRequest(_ context.Context, in source.ExternalRequestInput) (source.ExternalRequestOutput, error) { +func (s *Source) HandleExternalRequest(ctx context.Context, in source.ExternalRequestInput) (source.ExternalRequestOutput, error) { + ctx, span := tracer.Start(ctx, "aibrain.Source.HandleExternalRequest") + defer span.End() + s.log.Infof("Handling external request for source: %s", in.Context.SourceName) instance, ok := s.instances.Load(in.Context.SourceName) if !ok { return source.ExternalRequestOutput{}, fmt.Errorf("source %q not found", in.Context.SourceName) } - resp, err := instance.(*assistant).handle(in) + resp, err := instance.(*assistant).handle(ctx, in) if err != nil { return source.ExternalRequestOutput{}, fmt.Errorf("while processing payload: %w", err) } diff --git a/internal/source/ai-brain/config.go b/internal/source/ai-brain/config.go index 22792f7d..a29e5de4 100644 --- a/internal/source/ai-brain/config.go +++ b/internal/source/ai-brain/config.go @@ -18,6 +18,8 @@ type Config struct { Log config.Logger `yaml:"log"` OpenAICloudServiceURL string `yaml:"openAICloudServiceURL"` OpenAIAssistantID string `yaml:"openAIAssistantId"` + HoneycombAPIKey string `yaml:"honeycombAPIKey"` + HoneycombSampleRate int `yaml:"honeycombSampleRate"` } // Validate validates the configuration. diff --git a/internal/source/ai-brain/config_schema.json b/internal/source/ai-brain/config_schema.json index 88c6fbe1..a5dc4605 100644 --- a/internal/source/ai-brain/config_schema.json +++ b/internal/source/ai-brain/config_schema.json @@ -4,66 +4,76 @@ "description": "Calls AI engine with incoming webhook prompts and streams the response.", "type": "object", "properties": { - "openAICloudServiceURL": { - "title": "OpenAI Cloud Service URL", - "type": "string" - }, - "openAIAssistantId": { + "honeycombAPIKey": { "type": "string", - "title": "OpenAI Assistant Id", - "default": "asst_eMM9QaWLi6cajHE4PdG1yU53" + "default": "", + "description": "If provided, then code instrumentation events will be sent to honeycomb.io" }, - "log": { - "title": "Logging", - "description": "Logging configuration for the plugin.", - "type": "object", - "properties": { - "level": { - "title": "Log Level", - "description": "Define log level for the plugin. Ensure that Botkube has plugin logging enabled for standard output.", - "type": "string", - "default": "info", - "oneOf": [ - { - "const": "panic", - "title": "Panic" - }, - { - "const": "fatal", - "title": "Fatal" - }, - { - "const": "error", - "title": "Error" - }, - { - "const": "warn", - "title": "Warning" - }, - { - "const": "info", - "title": "Info" - }, - { - "const": "debug", - "title": "Debug" - }, - { - "const": "trace", - "title": "Trace" - } - ] - }, - "disableColors": { - "type": "boolean", - "default": false, - "description": "If enabled, disables color logging output.", - "title": "Disable Colors" - } - } + "honeycombSampleRate": { + "type": "integer", + "default": 1 } }, - "required": [ - "openAICloudServiceURL" - ] + "openAICloudServiceURL": { + "title": "OpenAI Cloud Service URL", + "type": "string" + }, + "openAIAssistantId": { + "type": "string", + "title": "OpenAI Assistant Id", + "default": "asst_eMM9QaWLi6cajHE4PdG1yU53" + }, + "log": { + "title": "Logging", + "description": "Logging configuration for the plugin.", + "type": "object", + "properties": { + "level": { + "title": "Log Level", + "description": "Define log level for the plugin. Ensure that Botkube has plugin logging enabled for standard output.", + "type": "string", + "default": "info", + "oneOf": [ + { + "const": "panic", + "title": "Panic" + }, + { + "const": "fatal", + "title": "Fatal" + }, + { + "const": "error", + "title": "Error" + }, + { + "const": "warn", + "title": "Warning" + }, + { + "const": "info", + "title": "Info" + }, + { + "const": "debug", + "title": "Debug" + }, + { + "const": "trace", + "title": "Trace" + } + ] + }, + "disableColors": { + "type": "boolean", + "default": false, + "description": "If enabled, disables color logging output.", + "title": "Disable Colors" + } + } + } +}, +"required": [ + "openAICloudServiceURL" +] }