diff --git a/core/go.mod b/core/go.mod index 647b5f3ab..9e8f694ec 100644 --- a/core/go.mod +++ b/core/go.mod @@ -7,7 +7,6 @@ require ( buf.build/gen/go/open-feature/flagd/grpc/go v1.3.0-20231031123731-ac2ec0f39838.2 buf.build/gen/go/open-feature/flagd/protocolbuffers/go v1.31.0-20231031123731-ac2ec0f39838.2 connectrpc.com/connect v1.14.0 - connectrpc.com/otelconnect v0.6.0 github.com/diegoholiveira/jsonlogic/v3 v3.4.0 github.com/fsnotify/fsnotify v1.7.0 github.com/golang/mock v1.6.0 @@ -23,8 +22,10 @@ require ( github.com/zeebo/xxh3 v1.0.2 go.opentelemetry.io/otel v1.21.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.44.0 + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.44.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 go.opentelemetry.io/otel/exporters/prometheus v0.44.0 go.opentelemetry.io/otel/metric v1.21.0 go.opentelemetry.io/otel/sdk v1.21.0 @@ -71,7 +72,6 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect diff --git a/core/go.sum b/core/go.sum index 390647be6..9628ed37c 100644 --- a/core/go.sum +++ b/core/go.sum @@ -394,12 +394,8 @@ cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1V cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M= cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= -connectrpc.com/connect v1.13.0 h1:lGs5maZZzWOOD+PFFiOt5OncKmMsk9ZdPwpy5jcmaYg= -connectrpc.com/connect v1.13.0/go.mod h1:uHAFHtYgeSZJxXrkN1IunDpKghnTXhYbVh0wW4StPW0= connectrpc.com/connect v1.14.0 h1:PDS+J7uoz5Oui2VEOMcfz6Qft7opQM9hPiKvtGC01pA= connectrpc.com/connect v1.14.0/go.mod h1:uoAq5bmhhn43TwhaKdGKN/bZcGtzPW1v+ngDTn5u+8s= -connectrpc.com/otelconnect v0.6.0 h1:VJAdQL9+sgdUw9+7+J+jq8pQo/h1S7tSFv2+vDcR7bU= -connectrpc.com/otelconnect v0.6.0/go.mod h1:jdcs0uiwXQVmSMgTJ2dAaWR5VbpNd7QKNkuoH7n86RA= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= @@ -465,7 +461,6 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -617,8 +612,6 @@ github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuz github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= -github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= @@ -634,8 +627,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= -github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= +github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= github.com/open-feature/open-feature-operator/apis v0.2.38-0.20231117101310-726a7f714906 h1:OUZVFPJgFytNSi3nxqy8nCKAlOlqdrqF4+eIGOaLSl8= github.com/open-feature/open-feature-operator/apis v0.2.38-0.20231117101310-726a7f714906/go.mod h1:YtdYEXJHo9iKwmchxbwGGsmu33FbugMQ8lKGarA9UYM= github.com/open-feature/schemas v0.2.8 h1:oA75hJXpOd9SFgmNI2IAxWZkwzQPUDm7Jyyh3q489wM= @@ -647,20 +640,14 @@ github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZ github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= -github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= -github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= -github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= -github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI= -github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= @@ -721,10 +708,14 @@ 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/prometheus v0.44.0 h1:08qeJgaPC0YEBu2PQMbqU3rogTlyzpjhCI2b58Yn00w= go.opentelemetry.io/otel/exporters/prometheus v0.44.0/go.mod h1:ERL2uIeBtg4TxZdojHUwzZfIFlUIjZtxubT5p4h1Gjg= go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= @@ -753,8 +744,6 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY= -golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1274,8 +1263,6 @@ google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCD google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw= -google.golang.org/grpc v1.60.0 h1:6FQAR0kM31P6MRdeluor2w2gPaS4SVNrD/DNTxrQ15k= -google.golang.org/grpc v1.60.0/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= @@ -1294,7 +1281,6 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= @@ -1321,28 +1307,16 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY= -k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0= k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A= k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA= -k8s.io/apimachinery v0.28.4 h1:zOSJe1mc+GxuMnFzD4Z/U1wst50X28ZNsn5bhgIIao8= -k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg= k8s.io/apimachinery v0.29.0 h1:+ACVktwyicPz0oc6MTMLwa2Pw3ouLAfAon1wPLtG48o= k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMeis= -k8s.io/client-go v0.28.4 h1:Np5ocjlZcTrkyRJ3+T3PkXDpe4UpatQxj85+xjaD2wY= -k8s.io/client-go v0.28.4/go.mod h1:0VDZFpgoZfelyP5Wqu0/r/TRYcLYuJ2U1KEeoaPa1N4= k8s.io/client-go v0.29.0 h1:KmlDtFcrdUzOYrBhXHgKw5ycWzc3ryPX5mQe0SkG3y8= k8s.io/client-go v0.29.0/go.mod h1:yLkXH4HKMAywcrD82KMSmfYg2DlE8mepPR4JGSo5n38= -k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= -k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= -k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= -k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= -k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= -k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= @@ -1352,8 +1326,6 @@ sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigw sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= -sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= diff --git a/core/pkg/runtime/from_config.go b/core/pkg/runtime/from_config.go index ae60dd24b..59914f5b8 100644 --- a/core/pkg/runtime/from_config.go +++ b/core/pkg/runtime/from_config.go @@ -21,9 +21,7 @@ const svcName = "flagd" // Config is the configuration structure derived from startup arguments. type Config struct { - MetricExporter string ManagementPort uint16 - OtelCollectorURI string ServiceCertPath string ServiceKeyPath string ServicePort uint16 @@ -36,22 +34,17 @@ type Config struct { // FromConfig builds a runtime from startup configurations // nolint: funlen func FromConfig(logger *logger.Logger, version string, config Config) (*Runtime, error) { - telCfg := telemetry.Config{ - MetricsExporter: config.MetricExporter, - CollectorTarget: config.OtelCollectorURI, - } - // register error handling for OpenTelemetry telemetry.RegisterErrorHandling(logger) // register trace provider for the runtime - err := telemetry.BuildTraceProvider(context.Background(), logger, svcName, version, telCfg) + err := telemetry.BuildTraceProvider(context.Background(), logger, svcName, version) if err != nil { return nil, fmt.Errorf("error building trace provider: %w", err) } // build metrics recorder with startup configurations - recorder, err := telemetry.BuildMetricsRecorder(context.Background(), svcName, version, telCfg) + recorder, err := telemetry.BuildMetricsRecorder(context.Background(), logger, svcName, version) if err != nil { return nil, fmt.Errorf("error building metrics recorder: %w", err) } @@ -94,7 +87,6 @@ func FromConfig(logger *logger.Logger, version string, config Config) (*Runtime, CertPath: config.ServiceCertPath, SocketPath: config.ServiceSocketPath, CORS: config.CORS, - Options: telemetry.BuildConnectOptions(telCfg), }, SyncImpl: iSyncs, }, nil diff --git a/core/pkg/telemetry/builder.go b/core/pkg/telemetry/builder.go index e818852c9..065e94ece 100644 --- a/core/pkg/telemetry/builder.go +++ b/core/pkg/telemetry/builder.go @@ -3,15 +3,15 @@ package telemetry import ( "context" "fmt" - "time" + "os" - "connectrpc.com/connect" - "connectrpc.com/otelconnect" "github.com/open-feature/flagd/core/pkg/logger" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc" + "go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp" "go.opentelemetry.io/otel/exporters/otlp/otlptrace" "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc" + "go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp" "go.opentelemetry.io/otel/exporters/prometheus" "go.opentelemetry.io/otel/propagation" "go.opentelemetry.io/otel/sdk/metric" @@ -19,20 +19,27 @@ import ( "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.18.0" "go.uber.org/zap" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" ) const ( - metricsExporterOtel = "otel" - exportInterval = 2 * time.Second + otelExporterOtlpMetricsProtocol = "OTEL_EXPORTER_OTLP_METRICS_PROTOCOL" + otelExporterOtlpProtocol = "OTEL_EXPORTER_OTLP_PROTOCOL" + otelExporterOtlpTracesProtocol = "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL" + otelMetricsExporter = "OTEL_METRICS_EXPORTER" + otelTracesExporter = "OTEL_TRACES_EXPORTER" + + otelExporterNone = "none" + otelExporterOtlp = "otlp" + otelExporterPrometheus = "prometheus" + + otelExporterOtlpProtocolGrpc = "grpc" + otelExporterOtlpProtocolHTTPProtobuf = "http/protobuf" ) -// Config of the telemetry runtime. These are expected to be mapped to start-up arguments -type Config struct { - MetricsExporter string - CollectorTarget string -} +var ( + nilMetricReader metric.Reader + nilTraceExporter trace.SpanExporter +) func RegisterErrorHandling(log *logger.Logger) { otel.SetErrorHandler(otelErrorsHandler{ @@ -42,10 +49,10 @@ func RegisterErrorHandling(log *logger.Logger) { // BuildMetricsRecorder is a helper to build telemetry.MetricsRecorder based on configurations func BuildMetricsRecorder( - ctx context.Context, svcName string, svcVersion string, config Config, + ctx context.Context, logger *logger.Logger, svcName string, svcVersion string, ) (*MetricsRecorder, error) { // Build metric reader based on configurations - mReader, err := buildMetricReader(ctx, config) + mReader, err := buildMetricReader(ctx, logger) if err != nil { return nil, fmt.Errorf("failed to setup metric reader: %w", err) } @@ -55,22 +62,13 @@ func BuildMetricsRecorder( if err != nil { return nil, fmt.Errorf("failed to setup resource identifier: %w", err) } - return NewOTelRecorder(mReader, rsc, svcName), nil } // BuildTraceProvider build and register the trace provider and propagator for the caller runtime. This method -// attempt to register a global TracerProvider backed by batch SpanProcessor.Config. CollectorTarget can be used to -// provide the grpc collector target. Providing empty target results in skipping provider & propagator registration. -// This results in tracers having NoopTracerProvider and propagator having No-Op TextMapPropagator performing no action -func BuildTraceProvider(ctx context.Context, logger *logger.Logger, svc string, svcVersion string, cfg Config) error { - if cfg.CollectorTarget == "" { - logger.Debug("skipping trace provider setup as collector target is not set." + - " Traces will use NoopTracerProvider provider and propagator will use no-Op TextMapPropagator") - return nil - } - - exporter, err := buildOtlpExporter(ctx, cfg.CollectorTarget) +// attempt to register a global TracerProvider backed by batch SpanProcessor.Config. +func BuildTraceProvider(ctx context.Context, logger *logger.Logger, svc string, svcVersion string) error { + exporter, err := buildOtlpExporter(ctx, logger) if err != nil { return err } @@ -90,65 +88,70 @@ func BuildTraceProvider(ctx context.Context, logger *logger.Logger, svc string, return nil } -// BuildConnectOptions is a helper to build connect options based on telemetry configurations -func BuildConnectOptions(cfg Config) []connect.HandlerOption { - options := []connect.HandlerOption{} - - // add interceptor if configuration is available for collector - if cfg.CollectorTarget != "" { - options = append(options, connect.WithInterceptors( - otelconnect.NewInterceptor(otelconnect.WithTrustRemote()), - )) - } - - return options -} - // buildMetricReader builds a metric reader based on provided configurations -func buildMetricReader(ctx context.Context, cfg Config) (metric.Reader, error) { - if cfg.MetricsExporter == "" { +func buildMetricReader(ctx context.Context, logger *logger.Logger) (metric.Reader, error) { + switch k, v := getOtelExporter(logger, otelMetricsExporter); v { + case otelExporterNone: + logger.Debug(fmt.Sprintf("skipping setup for metrics due to %s=%s", k, v)) + return nilMetricReader, nil + case otelExporterOtlp: + break + case otelExporterPrometheus: return buildDefaultMetricReader() + default: + logger.Debug(fmt.Sprintf("skipping unsupported value for %s=%s", k, v)) + return nilMetricReader, nil } - // Handle metric reader override - if cfg.MetricsExporter != metricsExporterOtel { - return nil, fmt.Errorf("provided metrics operator %s is not supported. currently only support %s", - cfg.MetricsExporter, metricsExporterOtel) - } - - // Otel override require target configuration - if cfg.CollectorTarget == "" { - return nil, fmt.Errorf("metric exporter is set(%s) without providing otel collector target."+ - " collector target is required for this option", cfg.MetricsExporter) - } - - // Non-blocking, insecure grpc connection - conn, err := grpc.DialContext(ctx, cfg.CollectorTarget, grpc.WithTransportCredentials(insecure.NewCredentials())) - if err != nil { - return nil, fmt.Errorf("error creating client connection: %w", err) + var exporter metric.Exporter + var err error + + switch k, v := getOtelExporterProtocol(logger, otelExporterOtlpMetricsProtocol, otelExporterOtlpProtocol); v { + case otelExporterOtlpProtocolGrpc: + exporter, err = otlpmetricgrpc.New(ctx) + case otelExporterOtlpProtocolHTTPProtobuf: + exporter, err = otlpmetrichttp.New(ctx) + default: + logger.Debug(fmt.Sprintf("skipping unsupported value %s for %s", v, k)) + return nilMetricReader, nil } // Otel metric exporter - otelExporter, err := otlpmetricgrpc.New(ctx, otlpmetricgrpc.WithGRPCConn(conn)) if err != nil { return nil, fmt.Errorf("error creating otel metric exporter: %w", err) } - - return metric.NewPeriodicReader(otelExporter, metric.WithInterval(exportInterval)), nil + return metric.NewPeriodicReader(exporter), nil } // buildOtlpExporter is a helper to build grpc backed otlp trace exporter -func buildOtlpExporter(ctx context.Context, collectorTarget string) (*otlptrace.Exporter, error) { - // Non-blocking, insecure grpc connection - conn, err := grpc.DialContext(ctx, collectorTarget, grpc.WithTransportCredentials(insecure.NewCredentials())) - if err != nil { - return nil, fmt.Errorf("error creating client connection: %w", err) +func buildOtlpExporter(ctx context.Context, logger *logger.Logger) (trace.SpanExporter, error) { + switch k, v := getOtelExporter(logger, otelTracesExporter); v { + case otelExporterNone: + logger.Debug(fmt.Sprintf("skipping setup for traces due to %s=%s", k, v)) + return nilTraceExporter, nil + case otelExporterOtlp: + break + default: + logger.Debug(fmt.Sprintf("skipping unsupported value for %s=%s", k, v)) + return nilTraceExporter, nil } - traceClient := otlptracegrpc.NewClient(otlptracegrpc.WithGRPCConn(conn)) - exporter, err := otlptrace.New(ctx, traceClient) + var client otlptrace.Client + var err error + + switch k, v := getOtelExporterProtocol(logger, otelExporterOtlpTracesProtocol, otelExporterOtlpProtocol); v { + case otelExporterOtlpProtocolGrpc: + client = otlptracegrpc.NewClient() + case otelExporterOtlpProtocolHTTPProtobuf: + client = otlptracehttp.NewClient() + default: + logger.Debug(fmt.Sprintf("skipping unsupported value %s for %s", v, k)) + return nilTraceExporter, nil + } + + exporter, err := otlptrace.New(ctx, client) if err != nil { - return nil, fmt.Errorf("error starting otel exporter: %w", err) + return nil, fmt.Errorf("error starting otel v: %w", err) } return exporter, nil } @@ -189,3 +192,23 @@ func (h otelErrorsHandler) Handle(err error) { msg := fmt.Sprintf("OpenTelemetry Error: %s", err.Error()) h.logger.WithFields(zap.String("component", "otel")).Debug(msg) } + +func getOtelExporter(logger *logger.Logger, signalEnvVar string) (string, string) { + if v := os.Getenv(signalEnvVar); v != "" { + logger.Debug(fmt.Sprintf("resolved %s=%s", signalEnvVar, v)) + return signalEnvVar, v + } + return "", otelExporterOtlp +} + +func getOtelExporterProtocol(logger *logger.Logger, signalEnvVar string, commonEnvVar string) (string, string) { + if v := os.Getenv(signalEnvVar); v != "" { + logger.Debug(fmt.Sprintf("resolved %s=%s", signalEnvVar, v)) + return signalEnvVar, v + } + if v := os.Getenv(commonEnvVar); v != "" { + logger.Debug(fmt.Sprintf("resolved %s=%s", commonEnvVar, v)) + return commonEnvVar, v + } + return "", otelExporterOtlpProtocolGrpc +} diff --git a/core/pkg/telemetry/builder_test.go b/core/pkg/telemetry/builder_test.go index 3f0853760..d057d30bd 100644 --- a/core/pkg/telemetry/builder_test.go +++ b/core/pkg/telemetry/builder_test.go @@ -3,6 +3,7 @@ package telemetry import ( "context" "fmt" + "os" "testing" "time" @@ -19,10 +20,7 @@ import ( func TestBuildMetricsRecorder(t *testing.T) { // Simple happy-path test - recorder, err := BuildMetricsRecorder(context.Background(), "service", "0.0.1", Config{ - MetricsExporter: "otel", - CollectorTarget: "localhost:8080", - }) + recorder, err := BuildMetricsRecorder(context.Background(), logger.NewLogger(nil, false), "service", "0.0.1") require.Nil(t, err, "expected no error, but got: %v", err) require.NotNilf(t, recorder, "expected recorder to be non-nil") @@ -33,49 +31,42 @@ func TestBuildMetricReader(t *testing.T) { tests := []struct { name string - cfg Config + env map[string]string error bool }{ { name: "Default configurations produce default reader", - cfg: Config{}, + env: map[string]string{}, error: false, }, - { - name: "Metric exporter overriding require valid overriding parameter", - cfg: Config{ - MetricsExporter: "unsupported", - }, - error: true, - }, - { - name: "Metric exporter overriding require valid configuration combination", - cfg: Config{ - MetricsExporter: metricsExporterOtel, - CollectorTarget: "", // collector target is unset - }, - error: true, - }, { name: "Metric exporter overriding with valid configurations", - cfg: Config{ - MetricsExporter: metricsExporterOtel, - CollectorTarget: "localhost:8080", + env: map[string]string{ + "OTEL_EXPORTER_OTLP_ENDPOINT": "localhost:8080", + "OTEL_EXPORTER_OTLP_PROTOCOL": "grpc", + "OTEL_METRICS_EXPORTER": "otlp", }, error: false, }, } for _, test := range tests { - reader, err := buildMetricReader(gCtx, test.cfg) + for k, v := range test.env { + _ = os.Setenv(k, v) + } + + reader, err := buildMetricReader(gCtx, logger.NewLogger(nil, false)) if test.error { require.NotNil(t, err, "test %s expected non-nil error", test.name) - continue + } else { + require.Nilf(t, err, "test %s expected no error, but got: %v", test.name, err) + require.NotNil(t, reader, "test %s expected non-nil reader", test.name) } - require.Nilf(t, err, "test %s expected no error, but got: %v", test.name, err) - require.NotNil(t, reader, "test %s expected non-nil reader", test.name) + for k := range test.env { + _ = os.Unsetenv(k) + } } } @@ -84,59 +75,117 @@ func TestBuildSpanProcessor(t *testing.T) { tests := []struct { name string - cfg Config + env map[string]string error bool }{ { name: "Valid configurations yield a valid processor", - cfg: Config{ - CollectorTarget: "localhost:8080", + env: map[string]string{ + "OTEL_EXPORTER_OTLP_ENDPOINT": "localhost:8080", + "OTEL_EXPORTER_OTLP_PROTOCOL": "grpc", + "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT": "", + "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL": "", }, error: false, }, { - name: "Empty configurations does not result in error", - cfg: Config{}, + name: "Valid configurations yield a valid processor", + env: map[string]string{ + "OTEL_EXPORTER_OTLP_ENDPOINT": "localhost:8080", + "OTEL_EXPORTER_OTLP_PROTOCOL": "http/protobuf", + "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT": "", + "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL": "", + }, + error: false, + }, + { + name: "Valid configurations yield a valid processor", + env: map[string]string{ + "OTEL_EXPORTER_OTLP_ENDPOINT": "", + "OTEL_EXPORTER_OTLP_PROTOCOL": "", + "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT": "localhost:8080", + "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL": "grpc", + }, + error: false, + }, + { + name: "Valid configurations yield a valid processor", + env: map[string]string{ + "OTEL_EXPORTER_OTLP_ENDPOINT": "", + "OTEL_EXPORTER_OTLP_PROTOCOL": "", + "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT": "localhost:8080", + "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL": "http/protobuf", + }, + error: false, + }, + { + name: "Valid configurations yield a valid processor", + env: map[string]string{ + "OTEL_EXPORTER_OTLP_ENDPOINT": "localhost:8080", + "OTEL_EXPORTER_OTLP_PROTOCOL": "", + "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT": "", + "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL": "grpc", + }, + error: false, + }, + { + name: "Valid configurations yield a valid processor", + env: map[string]string{ + "OTEL_EXPORTER_OTLP_ENDPOINT": "localhost:8080", + "OTEL_EXPORTER_OTLP_PROTOCOL": "", + "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT": "", + "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL": "http/protobuf", + }, + error: false, + }, + { + name: "Valid configurations yield a valid processor", + env: map[string]string{ + "OTEL_EXPORTER_OTLP_ENDPOINT": "", + "OTEL_EXPORTER_OTLP_PROTOCOL": "grpc", + "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT": "localhost:8080", + "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL": "", + }, error: false, }, - } - - for _, test := range tests { - err := BuildTraceProvider(gCtx, logger.NewLogger(nil, false), "svc", "0.0.1", test.cfg) - - if test.error { - require.NotNil(t, err, "test %s expected non-nil error", test.name) - continue - } - - require.Nilf(t, err, "test %s expected no error, but got: %v", test.name, err) - } -} - -func TestBuildConnectOptions(t *testing.T) { - tests := []struct { - name string - cfg Config - optionCount int - }{ { - name: "No options for empty/default configurations", - cfg: Config{}, - optionCount: 0, + name: "Valid configurations yield a valid processor", + env: map[string]string{ + "OTEL_EXPORTER_OTLP_ENDPOINT": "", + "OTEL_EXPORTER_OTLP_PROTOCOL": "http/protobuf", + "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT": "localhost:8080", + "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL": "", + }, + error: false, }, { - name: "Connect option is set when telemetry target is set", - cfg: Config{ - CollectorTarget: "localhost:8080", + name: "Empty configurations does not result in error", + env: map[string]string{ + "OTEL_EXPORTER_OTLP_ENDPOINT": "", + "OTEL_EXPORTER_OTLP_PROTOCOL": "", + "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT": "", + "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL": "", }, - optionCount: 1, + error: false, }, } for _, test := range tests { - options := BuildConnectOptions(test.cfg) + for k, v := range test.env { + _ = os.Setenv(k, v) + } + + err := BuildTraceProvider(gCtx, logger.NewLogger(nil, false), "svc", "0.0.1") - require.Len(t, options, test.optionCount, "option count mismatch for test %s", test.name) + if test.error { + require.NotNil(t, err, "test %s expected non-nil error", test.name) + } else { + require.Nilf(t, err, "test %s expected no error, but got: %v", test.name, err) + } + + for k := range test.env { + _ = os.Unsetenv(k) + } } } diff --git a/docs/reference/flagd-cli/flagd_start.md b/docs/reference/flagd-cli/flagd_start.md index 66296c196..2ac42fb7b 100644 --- a/docs/reference/flagd-cli/flagd_start.md +++ b/docs/reference/flagd-cli/flagd_start.md @@ -11,18 +11,16 @@ flagd start [flags] ### Options ``` - -C, --cors-origin strings CORS allowed origins, * will allow all origins - -h, --help help for start - -z, --log-format string Set the logging format, e.g. console or json (default "console") - -m, --management-port int32 Port for management operations (default 8014) - -t, --metrics-exporter string Set the metrics exporter. Default(if unset) is Prometheus. Can be override to otel - OpenTelemetry metric exporter. Overriding to otel require otelCollectorURI to be present - -o, --otel-collector-uri string Set the grpc URI of the OpenTelemetry collector for flagd runtime. If unset, the collector setup will be ignored and traces will not be exported. - -p, --port int32 Port to listen on (default 8013) - -c, --server-cert-path string Server side tls certificate path - -k, --server-key-path string Server side tls key path - -d, --socket-path string Flagd socket path. With grpc the service will become available on this address. With http(s) the grpc-gateway proxy will use this address internally. - -s, --sources string JSON representation of an array of SourceConfig objects. This object contains 2 required fields, uri (string) and provider (string). Documentation for this object: https://flagd.dev/reference/sync-configuration/#source-configuration - -f, --uri .yaml/.yml/.json Set a sync provider uri to read data from, this can be a filepath, URL (HTTP and gRPC) or FeatureFlag custom resource. When flag keys are duplicated across multiple providers the merge priority follows the index of the flag arguments, as such flags from the uri at index 0 take the lowest precedence, with duplicated keys being overwritten by those from the uri at index 1. Please note that if you are using filepath, flagd only supports files with .yaml/.yml/.json extension. + -C, --cors-origin strings CORS allowed origins, * will allow all origins + -h, --help help for start + -z, --log-format string Set the logging format, e.g. console or json (default "console") + -m, --management-port int32 Port for management operations (default 8014) + -p, --port int32 Port to listen on (default 8013) + -c, --server-cert-path string Server side tls certificate path + -k, --server-key-path string Server side tls key path + -d, --socket-path string Flagd socket path. With grpc the service will become available on this address. With http(s) the grpc-gateway proxy will use this address internally. + -s, --sources string JSON representation of an array of SourceConfig objects. This object contains 2 required fields, uri (string) and provider (string). Documentation for this object: https://flagd.dev/reference/sync-configuration/#source-configuration + -f, --uri .yaml/.yml/.json Set a sync provider uri to read data from, this can be a filepath, URL (HTTP and gRPC) or FeatureFlag custom resource. When flag keys are duplicated across multiple providers the merge priority follows the index of the flag arguments, as such flags from the uri at index 0 take the lowest precedence, with duplicated keys being overwritten by those from the uri at index 1. Please note that if you are using filepath, flagd only supports files with .yaml/.yml/.json extension. ``` ### Options inherited from parent commands diff --git a/docs/reference/monitoring.md b/docs/reference/monitoring.md index 6f957650b..6accfb3cb 100644 --- a/docs/reference/monitoring.md +++ b/docs/reference/monitoring.md @@ -63,10 +63,16 @@ flagd expose following traces, ## Export to OTEL collector -flagd can be configured to connect to [OTEL collector](https://opentelemetry.io/docs/collector/). This requires startup -flag `metrics-exporter` to be `otel` and a valid `otel-collector-uri`. For example, +flagd can be configured to export telemetry to the [OpenTelemetry (OTel) Collector](https://opentelemetry.io/docs/collector/) using standard +[OTel SDK environment variables](https://opentelemetry.io/docs/concepts/sdk-configuration/otlp-exporter-configuration). For example, -`flagd start --uri file:/flags.json --metrics-exporter otel --otel-collector-uri localhost:4317` +```shell +export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 +export OTEL_EXPORTER_OTLP_PROTOCOL=grpc +export OTEL_METRICS_EXPORTER=otlp + +flagd start --uri file:/flags.json +``` ### Configure local collector setup diff --git a/flagd/cmd/start.go b/flagd/cmd/start.go index f46358810..caefedacc 100644 --- a/flagd/cmd/start.go +++ b/flagd/cmd/start.go @@ -18,9 +18,7 @@ import ( const ( corsFlagName = "cors-origin" logFormatFlagName = "log-format" - metricsExporter = "metrics-exporter" managementPortFlagName = "management-port" - otelCollectorURI = "otel-collector-uri" portFlagName = "port" serverCertPathFlagName = "server-cert-path" serverKeyPathFlagName = "server-key-path" @@ -57,17 +55,10 @@ func init() { "https://flagd.dev/reference/sync-configuration/#source-configuration", ) flags.StringP(logFormatFlagName, "z", "console", "Set the logging format, e.g. console or json") - flags.StringP(metricsExporter, "t", "", "Set the metrics exporter. Default(if unset) is Prometheus."+ - " Can be override to otel - OpenTelemetry metric exporter. Overriding to otel require otelCollectorURI to"+ - " be present") - flags.StringP(otelCollectorURI, "o", "", "Set the grpc URI of the OpenTelemetry collector "+ - "for flagd runtime. If unset, the collector setup will be ignored and traces will not be exported.") _ = viper.BindPFlag(corsFlagName, flags.Lookup(corsFlagName)) _ = viper.BindPFlag(logFormatFlagName, flags.Lookup(logFormatFlagName)) - _ = viper.BindPFlag(metricsExporter, flags.Lookup(metricsExporter)) _ = viper.BindPFlag(managementPortFlagName, flags.Lookup(managementPortFlagName)) - _ = viper.BindPFlag(otelCollectorURI, flags.Lookup(otelCollectorURI)) _ = viper.BindPFlag(portFlagName, flags.Lookup(portFlagName)) _ = viper.BindPFlag(serverCertPathFlagName, flags.Lookup(serverCertPathFlagName)) _ = viper.BindPFlag(serverKeyPathFlagName, flags.Lookup(serverKeyPathFlagName)) @@ -121,9 +112,7 @@ var startCmd = &cobra.Command{ // Build Runtime ----------------------------------------------------------- rt, err := runtime.FromConfig(logger, Version, runtime.Config{ CORS: viper.GetStringSlice(corsFlagName), - MetricExporter: viper.GetString(metricsExporter), ManagementPort: viper.GetUint16(managementPortFlagName), - OtelCollectorURI: viper.GetString(otelCollectorURI), ServiceCertPath: viper.GetString(serverCertPathFlagName), ServiceKeyPath: viper.GetString(serverKeyPathFlagName), ServicePort: viper.GetUint16(portFlagName),