From 4f8b792f508e31ec22f85051e82a26594b15e152 Mon Sep 17 00:00:00 2001 From: Jacob Aronoff Date: Fri, 23 Sep 2022 15:27:45 -0400 Subject: [PATCH 1/8] Add scrape configs endpoint --- cmd/otel-allocator/discovery/discovery.go | 10 ++++++++++ cmd/otel-allocator/main.go | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/cmd/otel-allocator/discovery/discovery.go b/cmd/otel-allocator/discovery/discovery.go index 2c0393f619..853e72a8b7 100644 --- a/cmd/otel-allocator/discovery/discovery.go +++ b/cmd/otel-allocator/discovery/discovery.go @@ -47,6 +47,16 @@ func NewManager(log logr.Logger, ctx context.Context, logger log.Logger, options } } +func (m *Manager) GetScrapeConfigs() map[string]*config.ScrapeConfig { + jobToScrapeConfig := map[string]*config.ScrapeConfig{} + for _, c := range m.configsMap { + for _, scrapeConfig := range c.ScrapeConfigs { + jobToScrapeConfig[scrapeConfig.JobName] = scrapeConfig + } + } + return jobToScrapeConfig +} + func (m *Manager) ApplyConfig(source allocatorWatcher.EventSource, cfg *config.Config) error { m.configsMap[source] = cfg diff --git a/cmd/otel-allocator/main.go b/cmd/otel-allocator/main.go index 80d8ec4743..7513dfdaef 100644 --- a/cmd/otel-allocator/main.go +++ b/cmd/otel-allocator/main.go @@ -3,6 +3,8 @@ package main import ( "context" "encoding/json" + "github.com/ghodss/yaml" + yaml2 "gopkg.in/yaml.v2" "net/http" "net/url" "os" @@ -152,6 +154,7 @@ func newServer(log logr.Logger, allocator allocation.Allocator, discoveryManager } router := mux.NewRouter().UseEncodedPath() router.Use(s.PrometheusMiddleware) + router.HandleFunc("/scrape_configs", s.ScrapeConfigsHandler).Methods("GET") router.HandleFunc("/jobs", s.JobHandler).Methods("GET") router.HandleFunc("/jobs/{job_id}/targets", s.TargetsHandler).Methods("GET") router.Path("/metrics").Handler(promhttp.Handler()) @@ -190,6 +193,23 @@ func (s *server) Shutdown(ctx context.Context) error { return s.server.Shutdown(ctx) } +func (s *server) ScrapeConfigsHandler(w http.ResponseWriter, r *http.Request) { + configs := s.discoveryManager.GetScrapeConfigs() + configBytes, err := yaml2.Marshal(configs) + if err != nil { + errorHandler(err, w, r) + } + jsonConfig, err := yaml.YAMLToJSON(configBytes) + if err != nil { + errorHandler(err, w, r) + } + w.Header().Set("Content-Type", "application/json") + _, err = w.Write(jsonConfig) + if err != nil { + errorHandler(err, w, r) + } +} + func (s *server) JobHandler(w http.ResponseWriter, r *http.Request) { displayData := make(map[string]allocation.LinkJSON) for _, v := range s.allocator.TargetItems() { From 2594ae5ec04f4a92160a981210703d2c2cc46abc Mon Sep 17 00:00:00 2001 From: Jacob Aronoff Date: Tue, 27 Sep 2022 13:06:51 -0400 Subject: [PATCH 2/8] Fix a borked chan --- Makefile | 2 +- cmd/otel-allocator/go.mod | 8 ++++---- cmd/otel-allocator/watcher/file.go | 5 +++++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 09ce4b790a..41868d0f31 100644 --- a/Makefile +++ b/Makefile @@ -184,7 +184,7 @@ container-push: .PHONY: container-target-allocator container-target-allocator: - docker build -t ${TARGETALLOCATOR_IMG} cmd/otel-allocator + docker buildx build --platform linux/amd64 -t ${TARGETALLOCATOR_IMG} cmd/otel-allocator .PHONY: start-kind start-kind: diff --git a/cmd/otel-allocator/go.mod b/cmd/otel-allocator/go.mod index 93fafa28ef..83d2ee1b68 100644 --- a/cmd/otel-allocator/go.mod +++ b/cmd/otel-allocator/go.mod @@ -3,13 +3,17 @@ module github.com/open-telemetry/opentelemetry-operator/cmd/otel-allocator go 1.19 require ( + github.com/buraksezer/consistent v0.9.0 + github.com/cespare/xxhash/v2 v2.1.2 github.com/fsnotify/fsnotify v1.5.1 + github.com/ghodss/yaml v1.0.0 github.com/go-kit/log v0.2.0 github.com/go-logr/logr v1.2.0 github.com/gorilla/mux v1.8.0 github.com/prometheus-operator/prometheus-operator v0.53.1 github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.53.1 github.com/prometheus-operator/prometheus-operator/pkg/client v0.53.1 + github.com/prometheus/client_golang v1.11.0 github.com/prometheus/common v0.32.1 github.com/prometheus/prometheus v1.8.2-0.20211214150951-52c693a63be1 github.com/spf13/pflag v1.0.5 @@ -42,8 +46,6 @@ require ( github.com/aws/aws-sdk-go v1.44.41 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect - github.com/buraksezer/consistent v0.9.0 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe // indirect github.com/containerd/containerd v1.5.7 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -59,7 +61,6 @@ require ( github.com/envoyproxy/protoc-gen-validate v0.6.2 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/fatih/color v1.12.0 // indirect - github.com/ghodss/yaml v1.0.0 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect github.com/go-logr/zapr v1.2.0 // indirect github.com/go-openapi/analysis v0.20.0 // indirect @@ -123,7 +124,6 @@ require ( github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus-community/prom-label-proxy v0.4.1-0.20211215142838-1eac0933d512 // indirect github.com/prometheus/alertmanager v0.23.1-0.20210914172521-e35efbddb66a // indirect - github.com/prometheus/client_golang v1.11.0 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common/sigv4 v0.1.0 // indirect github.com/prometheus/procfs v0.7.3 // indirect diff --git a/cmd/otel-allocator/watcher/file.go b/cmd/otel-allocator/watcher/file.go index 6adc3c33e9..6a15ce532b 100644 --- a/cmd/otel-allocator/watcher/file.go +++ b/cmd/otel-allocator/watcher/file.go @@ -12,6 +12,7 @@ import ( type FileWatcher struct { configFilePath string watcher *fsnotify.Watcher + closer chan bool } func newConfigMapWatcher(logger logr.Logger, config config.CLIConfig) (FileWatcher, error) { @@ -24,6 +25,7 @@ func newConfigMapWatcher(logger logr.Logger, config config.CLIConfig) (FileWatch return FileWatcher{ configFilePath: *config.ConfigFilePath, watcher: fileWatcher, + closer: make(chan bool), }, nil } @@ -37,6 +39,8 @@ func (f *FileWatcher) Start(upstreamEvents chan Event, upstreamErrors chan error go func() { for { select { + case _ = <-f.closer: + return case fileEvent := <-f.watcher.Events: if fileEvent.Op == fsnotify.Create { upstreamEvents <- Event{ @@ -52,5 +56,6 @@ func (f *FileWatcher) Start(upstreamEvents chan Event, upstreamErrors chan error } func (f *FileWatcher) Close() error { + f.closer <- true return f.watcher.Close() } From b231e3a44071e0179bd424b20c3fa86a8b818482 Mon Sep 17 00:00:00 2001 From: Jacob Aronoff Date: Wed, 28 Sep 2022 17:52:07 -0400 Subject: [PATCH 3/8] Fix some defaults --- Makefile | 2 +- cmd/otel-allocator/config/config.go | 1 - pkg/collector/container.go | 8 ++++++++ pkg/collector/reconcile/service.go | 1 + pkg/collector/reconcile/service_test.go | 16 ++++++++++++++++ 5 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 41868d0f31..d9fa681284 100644 --- a/Makefile +++ b/Makefile @@ -175,7 +175,7 @@ set-test-image-vars: # Build the container image, used only for local dev purposes .PHONY: container container: - docker build -t ${IMG} --build-arg VERSION_PKG=${VERSION_PKG} --build-arg VERSION=${VERSION} --build-arg VERSION_DATE=${VERSION_DATE} --build-arg OTELCOL_VERSION=${OTELCOL_VERSION} --build-arg TARGETALLOCATOR_VERSION=${TARGETALLOCATOR_VERSION} --build-arg AUTO_INSTRUMENTATION_JAVA_VERSION=${AUTO_INSTRUMENTATION_JAVA_VERSION} --build-arg AUTO_INSTRUMENTATION_NODEJS_VERSION=${AUTO_INSTRUMENTATION_NODEJS_VERSION} --build-arg AUTO_INSTRUMENTATION_PYTHON_VERSION=${AUTO_INSTRUMENTATION_PYTHON_VERSION} --build-arg AUTO_INSTRUMENTATION_DOTNET_VERSION=${AUTO_INSTRUMENTATION_DOTNET_VERSION} . + docker buildx build --platform linux/amd64 -t ${IMG} --build-arg VERSION_PKG=${VERSION_PKG} --build-arg VERSION=${VERSION} --build-arg VERSION_DATE=${VERSION_DATE} --build-arg OTELCOL_VERSION=${OTELCOL_VERSION} --build-arg TARGETALLOCATOR_VERSION=${TARGETALLOCATOR_VERSION} --build-arg AUTO_INSTRUMENTATION_JAVA_VERSION=${AUTO_INSTRUMENTATION_JAVA_VERSION} --build-arg AUTO_INSTRUMENTATION_NODEJS_VERSION=${AUTO_INSTRUMENTATION_NODEJS_VERSION} --build-arg AUTO_INSTRUMENTATION_PYTHON_VERSION=${AUTO_INSTRUMENTATION_PYTHON_VERSION} --build-arg AUTO_INSTRUMENTATION_DOTNET_VERSION=${AUTO_INSTRUMENTATION_DOTNET_VERSION} . # Push the container image, used only for local dev purposes .PHONY: container-push diff --git a/cmd/otel-allocator/config/config.go b/cmd/otel-allocator/config/config.go index 05d0e38405..5891db381d 100644 --- a/cmd/otel-allocator/config/config.go +++ b/cmd/otel-allocator/config/config.go @@ -66,7 +66,6 @@ func Load(file string) (Config, error) { } func unmarshal(cfg *Config, configFile string) error { - yamlFile, err := os.ReadFile(configFile) if err != nil { return err diff --git a/pkg/collector/container.go b/pkg/collector/container.go index 5c0548feb4..5fbb7ad529 100644 --- a/pkg/collector/container.go +++ b/pkg/collector/container.go @@ -78,6 +78,14 @@ func Container(cfg config.Config, logger logr.Logger, otelcol v1alpha1.OpenTelem }, }) + if otelcol.Spec.TargetAllocator.Enabled { + // We need to add a SHARD here so the collector is able to keep after the hashmod operation + envVars = append(envVars, corev1.EnvVar{ + Name: "SHARD", + Value: "0", + }) + } + var livenessProbe *corev1.Probe if config, err := adapters.ConfigFromString(otelcol.Spec.Config); err == nil { if probe, err := adapters.ConfigToContainerProbe(config); err == nil { diff --git a/pkg/collector/reconcile/service.go b/pkg/collector/reconcile/service.go index 1fbb6337c6..896c99a356 100644 --- a/pkg/collector/reconcile/service.go +++ b/pkg/collector/reconcile/service.go @@ -235,6 +235,7 @@ func expectedServices(ctx context.Context, params Params, expected []corev1.Serv updated.ObjectMeta.Labels[k] = v } updated.Spec.Ports = desired.Spec.Ports + updated.Spec.Selector = desired.Spec.Selector patch := client.MergeFrom(existing) diff --git a/pkg/collector/reconcile/service_test.go b/pkg/collector/reconcile/service_test.go index 9334c7d53e..f200a166bc 100644 --- a/pkg/collector/reconcile/service_test.go +++ b/pkg/collector/reconcile/service_test.go @@ -165,7 +165,23 @@ func TestExpectedServices(t *testing.T) { assert.True(t, exists) assert.Equal(t, instanceUID, actual.OwnerReferences[0].UID) assert.Contains(t, actual.Spec.Ports, extraPorts) + }) + t.Run("should update service on version change", func(t *testing.T) { + serviceInstance := service("test-collector", params().Instance.Spec.Ports) + createObjectIfNotExists(t, "test-collector", &serviceInstance) + newService := service("test-collector", params().Instance.Spec.Ports) + newService.Spec.Selector["app.kubernetes.io/version"] = "Newest" + err := expectedServices(context.Background(), params(), []v1.Service{newService}) + assert.NoError(t, err) + + actual := v1.Service{} + exists, err := populateObjectIfExists(t, &actual, types.NamespacedName{Namespace: "default", Name: "test-collector"}) + + assert.NoError(t, err) + assert.True(t, exists) + assert.Equal(t, instanceUID, actual.OwnerReferences[0].UID) + assert.Equal(t, "Newest", actual.Spec.Selector["app.kubernetes.io/version"]) }) } From f263d9f84b3f7e5018aa7e2acc8cc8ba27562dd3 Mon Sep 17 00:00:00 2001 From: Jacob Aronoff Date: Wed, 28 Sep 2022 17:58:21 -0400 Subject: [PATCH 4/8] comments and cleaning --- cmd/otel-allocator/config/config.go | 1 + cmd/otel-allocator/main.go | 4 ++++ pkg/collector/container.go | 3 ++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/cmd/otel-allocator/config/config.go b/cmd/otel-allocator/config/config.go index 5891db381d..05d0e38405 100644 --- a/cmd/otel-allocator/config/config.go +++ b/cmd/otel-allocator/config/config.go @@ -66,6 +66,7 @@ func Load(file string) (Config, error) { } func unmarshal(cfg *Config, configFile string) error { + yamlFile, err := os.ReadFile(configFile) if err != nil { return err diff --git a/cmd/otel-allocator/main.go b/cmd/otel-allocator/main.go index 7513dfdaef..16a64e702a 100644 --- a/cmd/otel-allocator/main.go +++ b/cmd/otel-allocator/main.go @@ -193,6 +193,9 @@ func (s *server) Shutdown(ctx context.Context) error { return s.server.Shutdown(ctx) } +// ScrapeConfigsHandler returns the available scrape configuration discovered by the target allocator. +// The target allocator first marshals these configurations such that the underlying prometheus marshalling is used. +// After that, the YAML is converted in to a JSON format for consumers to use. func (s *server) ScrapeConfigsHandler(w http.ResponseWriter, r *http.Request) { configs := s.discoveryManager.GetScrapeConfigs() configBytes, err := yaml2.Marshal(configs) @@ -203,6 +206,7 @@ func (s *server) ScrapeConfigsHandler(w http.ResponseWriter, r *http.Request) { if err != nil { errorHandler(err, w, r) } + // We don't use the jsonHandler method because we don't want our bytes to be re-encoded w.Header().Set("Content-Type", "application/json") _, err = w.Write(jsonConfig) if err != nil { diff --git a/pkg/collector/container.go b/pkg/collector/container.go index 5fbb7ad529..df1dd65bc1 100644 --- a/pkg/collector/container.go +++ b/pkg/collector/container.go @@ -79,7 +79,8 @@ func Container(cfg config.Config, logger logr.Logger, otelcol v1alpha1.OpenTelem }) if otelcol.Spec.TargetAllocator.Enabled { - // We need to add a SHARD here so the collector is able to keep after the hashmod operation + // We need to add a SHARD here so the collector is able to keep targets after the hashmod operation which is + // added by default by the operator generator. envVars = append(envVars, corev1.EnvVar{ Name: "SHARD", Value: "0", From 329a630544ea7a9e320a7d4b08072a55b1d96a85 Mon Sep 17 00:00:00 2001 From: Jacob Aronoff Date: Thu, 29 Sep 2022 10:37:07 -0400 Subject: [PATCH 5/8] Goimports --- Makefile | 4 ++-- apis/v1alpha1/zz_generated.deepcopy.go | 2 +- cmd/otel-allocator/main.go | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index d9fa681284..09ce4b790a 100644 --- a/Makefile +++ b/Makefile @@ -175,7 +175,7 @@ set-test-image-vars: # Build the container image, used only for local dev purposes .PHONY: container container: - docker buildx build --platform linux/amd64 -t ${IMG} --build-arg VERSION_PKG=${VERSION_PKG} --build-arg VERSION=${VERSION} --build-arg VERSION_DATE=${VERSION_DATE} --build-arg OTELCOL_VERSION=${OTELCOL_VERSION} --build-arg TARGETALLOCATOR_VERSION=${TARGETALLOCATOR_VERSION} --build-arg AUTO_INSTRUMENTATION_JAVA_VERSION=${AUTO_INSTRUMENTATION_JAVA_VERSION} --build-arg AUTO_INSTRUMENTATION_NODEJS_VERSION=${AUTO_INSTRUMENTATION_NODEJS_VERSION} --build-arg AUTO_INSTRUMENTATION_PYTHON_VERSION=${AUTO_INSTRUMENTATION_PYTHON_VERSION} --build-arg AUTO_INSTRUMENTATION_DOTNET_VERSION=${AUTO_INSTRUMENTATION_DOTNET_VERSION} . + docker build -t ${IMG} --build-arg VERSION_PKG=${VERSION_PKG} --build-arg VERSION=${VERSION} --build-arg VERSION_DATE=${VERSION_DATE} --build-arg OTELCOL_VERSION=${OTELCOL_VERSION} --build-arg TARGETALLOCATOR_VERSION=${TARGETALLOCATOR_VERSION} --build-arg AUTO_INSTRUMENTATION_JAVA_VERSION=${AUTO_INSTRUMENTATION_JAVA_VERSION} --build-arg AUTO_INSTRUMENTATION_NODEJS_VERSION=${AUTO_INSTRUMENTATION_NODEJS_VERSION} --build-arg AUTO_INSTRUMENTATION_PYTHON_VERSION=${AUTO_INSTRUMENTATION_PYTHON_VERSION} --build-arg AUTO_INSTRUMENTATION_DOTNET_VERSION=${AUTO_INSTRUMENTATION_DOTNET_VERSION} . # Push the container image, used only for local dev purposes .PHONY: container-push @@ -184,7 +184,7 @@ container-push: .PHONY: container-target-allocator container-target-allocator: - docker buildx build --platform linux/amd64 -t ${TARGETALLOCATOR_IMG} cmd/otel-allocator + docker build -t ${TARGETALLOCATOR_IMG} cmd/otel-allocator .PHONY: start-kind start-kind: diff --git a/apis/v1alpha1/zz_generated.deepcopy.go b/apis/v1alpha1/zz_generated.deepcopy.go index e41120b723..f2b8397930 100644 --- a/apis/v1alpha1/zz_generated.deepcopy.go +++ b/apis/v1alpha1/zz_generated.deepcopy.go @@ -539,4 +539,4 @@ func (in *ScaleSubresourceStatus) DeepCopy() *ScaleSubresourceStatus { out := new(ScaleSubresourceStatus) in.DeepCopyInto(out) return out -} \ No newline at end of file +} diff --git a/cmd/otel-allocator/main.go b/cmd/otel-allocator/main.go index 16a64e702a..69a4b16057 100644 --- a/cmd/otel-allocator/main.go +++ b/cmd/otel-allocator/main.go @@ -3,20 +3,20 @@ package main import ( "context" "encoding/json" - "github.com/ghodss/yaml" - yaml2 "gopkg.in/yaml.v2" "net/http" "net/url" "os" "os/signal" "syscall" + "github.com/ghodss/yaml" gokitlog "github.com/go-kit/log" "github.com/go-logr/logr" "github.com/gorilla/mux" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promhttp" + yaml2 "gopkg.in/yaml.v2" _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" ctrl "sigs.k8s.io/controller-runtime" From 33341bd064f23fe9d9186b256cd9eb3f64eae2e0 Mon Sep 17 00:00:00 2001 From: Jacob Aronoff Date: Mon, 3 Oct 2022 11:17:06 -0400 Subject: [PATCH 6/8] Pass linting --- cmd/otel-allocator/main.go | 28 ++++++++++++++++------------ cmd/otel-allocator/watcher/file.go | 2 +- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/cmd/otel-allocator/main.go b/cmd/otel-allocator/main.go index 5d9f7d7139..7edae40de4 100644 --- a/cmd/otel-allocator/main.go +++ b/cmd/otel-allocator/main.go @@ -208,23 +208,23 @@ func (s *server) Shutdown(ctx context.Context) error { } // ScrapeConfigsHandler returns the available scrape configuration discovered by the target allocator. -// The target allocator first marshals these configurations such that the underlying prometheus marshalling is used. +// The target allocator first marshals these configurations such that the underlying prometheus marshaling is used. // After that, the YAML is converted in to a JSON format for consumers to use. func (s *server) ScrapeConfigsHandler(w http.ResponseWriter, r *http.Request) { configs := s.discoveryManager.GetScrapeConfigs() configBytes, err := yaml2.Marshal(configs) if err != nil { - errorHandler(err, w, r) + s.errorHandler(err, w) } jsonConfig, err := yaml.YAMLToJSON(configBytes) if err != nil { - errorHandler(err, w, r) + s.errorHandler(err, w) } // We don't use the jsonHandler method because we don't want our bytes to be re-encoded w.Header().Set("Content-Type", "application/json") _, err = w.Write(jsonConfig) if err != nil { - errorHandler(err, w, r) + s.errorHandler(err, w) } } @@ -233,7 +233,7 @@ func (s *server) JobHandler(w http.ResponseWriter, r *http.Request) { for _, v := range s.allocator.TargetItems() { displayData[v.JobName] = allocation.LinkJSON{Link: v.Link.Link} } - jsonHandler(s.logger, w, displayData) + s.jsonHandler(w, displayData) } // PrometheusMiddleware implements mux.MiddlewareFunc. @@ -257,33 +257,37 @@ func (s *server) TargetsHandler(w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) jobId, err := url.QueryUnescape(params["job_id"]) if err != nil { - errorHandler(w) + s.errorHandler(err, w) return } if len(q) == 0 { displayData := allocation.GetAllTargetsByJob(jobId, compareMap, s.allocator) - jsonHandler(s.logger, w, displayData) + s.jsonHandler(w, displayData) } else { tgs := allocation.GetAllTargetsByCollectorAndJob(q[0], jobId, compareMap, s.allocator) // Displays empty list if nothing matches if len(tgs) == 0 { - jsonHandler(s.logger, w, []interface{}{}) + s.jsonHandler(w, []interface{}{}) return } - jsonHandler(s.logger, w, tgs) + s.jsonHandler(w, tgs) } } -func errorHandler(w http.ResponseWriter) { +func (s *server) errorHandler(err error, w http.ResponseWriter) { w.WriteHeader(500) + jsonErr := json.NewEncoder(w).Encode(err) + if jsonErr != nil { + s.logger.Error(jsonErr, "failed to encode error message") + } } -func jsonHandler(logger logr.Logger, w http.ResponseWriter, data interface{}) { +func (s *server) jsonHandler(w http.ResponseWriter, data interface{}) { w.Header().Set("Content-Type", "application/json") err := json.NewEncoder(w).Encode(data) if err != nil { - logger.Error(err, "failed to encode data for http response") + s.logger.Error(err, "failed to encode data for http response") } } diff --git a/cmd/otel-allocator/watcher/file.go b/cmd/otel-allocator/watcher/file.go index e984904edf..069b9ac483 100644 --- a/cmd/otel-allocator/watcher/file.go +++ b/cmd/otel-allocator/watcher/file.go @@ -53,7 +53,7 @@ func (f *FileWatcher) Start(upstreamEvents chan Event, upstreamErrors chan error go func() { for { select { - case _ = <-f.closer: + case <-f.closer: return case fileEvent := <-f.watcher.Events: if fileEvent.Op == fsnotify.Create { From 1e44ab8ade41ecb923e7bad03a22108133581316 Mon Sep 17 00:00:00 2001 From: Jacob Aronoff Date: Mon, 3 Oct 2022 11:25:39 -0400 Subject: [PATCH 7/8] Reuse and docs --- cmd/otel-allocator/README.md | 35 +++++++++++++++++++++++++++++++++++ cmd/otel-allocator/main.go | 15 ++++++--------- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/cmd/otel-allocator/README.md b/cmd/otel-allocator/README.md index bff32f383b..f4b4d53fda 100644 --- a/cmd/otel-allocator/README.md +++ b/cmd/otel-allocator/README.md @@ -12,7 +12,42 @@ This configuration will be resolved to target configurations and then split acro TargetAllocators expose the results as [HTTP_SD endpoints](https://prometheus.io/docs/prometheus/latest/http_sd/) split by collector. +Currently, the Target Allocator handles the sharding of targets. The operator sets the `$SHARD` variable to 0 to allow +collectors to keep targets generated by a Prometheus CRD. Using Prometheus sharding and target allocator sharding is not +recommended currently and may lead to unknown results. +[See this thread for more information](https://github.com/open-telemetry/opentelemetry-operator/pull/1124#discussion_r984683577) + #### Endpoints +`/scrape_configs`: + +```json +{ + "job1": { + "follow_redirects": true, + "honor_timestamps": true, + "job_name": "job1", + "metric_relabel_configs": [], + "metrics_path": "/metrics", + "scheme": "http", + "scrape_interval": "1m", + "scrape_timeout": "10s", + "static_configs": [] + }, + "job2": { + "follow_redirects": true, + "honor_timestamps": true, + "job_name": "job2", + "metric_relabel_configs": [], + "metrics_path": "/metrics", + "relabel_configs": [], + "scheme": "http", + "scrape_interval": "1m", + "scrape_timeout": "10s", + "kubernetes_sd_configs": [] + } +} +``` + `/jobs`: ```json diff --git a/cmd/otel-allocator/main.go b/cmd/otel-allocator/main.go index 7edae40de4..85e1ca4c45 100644 --- a/cmd/otel-allocator/main.go +++ b/cmd/otel-allocator/main.go @@ -214,17 +214,17 @@ func (s *server) ScrapeConfigsHandler(w http.ResponseWriter, r *http.Request) { configs := s.discoveryManager.GetScrapeConfigs() configBytes, err := yaml2.Marshal(configs) if err != nil { - s.errorHandler(err, w) + s.errorHandler(w, err) } jsonConfig, err := yaml.YAMLToJSON(configBytes) if err != nil { - s.errorHandler(err, w) + s.errorHandler(w, err) } // We don't use the jsonHandler method because we don't want our bytes to be re-encoded w.Header().Set("Content-Type", "application/json") _, err = w.Write(jsonConfig) if err != nil { - s.errorHandler(err, w) + s.errorHandler(w, err) } } @@ -257,7 +257,7 @@ func (s *server) TargetsHandler(w http.ResponseWriter, r *http.Request) { params := mux.Vars(r) jobId, err := url.QueryUnescape(params["job_id"]) if err != nil { - s.errorHandler(err, w) + s.errorHandler(w, err) return } @@ -276,12 +276,9 @@ func (s *server) TargetsHandler(w http.ResponseWriter, r *http.Request) { } } -func (s *server) errorHandler(err error, w http.ResponseWriter) { +func (s *server) errorHandler(w http.ResponseWriter, err error) { w.WriteHeader(500) - jsonErr := json.NewEncoder(w).Encode(err) - if jsonErr != nil { - s.logger.Error(jsonErr, "failed to encode error message") - } + s.jsonHandler(w, err) } func (s *server) jsonHandler(w http.ResponseWriter, data interface{}) { From 18f80443d3e303cacdb29dbb1be872818b2e53a5 Mon Sep 17 00:00:00 2001 From: Jacob Aronoff Date: Mon, 3 Oct 2022 14:20:31 -0400 Subject: [PATCH 8/8] Update pkg/collector/container.go Co-authored-by: Anthony Mirabella --- pkg/collector/container.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/collector/container.go b/pkg/collector/container.go index df1dd65bc1..e61a6b6384 100644 --- a/pkg/collector/container.go +++ b/pkg/collector/container.go @@ -80,7 +80,10 @@ func Container(cfg config.Config, logger logr.Logger, otelcol v1alpha1.OpenTelem if otelcol.Spec.TargetAllocator.Enabled { // We need to add a SHARD here so the collector is able to keep targets after the hashmod operation which is - // added by default by the operator generator. + // added by default by the Prometheus operator's config generator. + // All collector instances use SHARD == 0 as they only receive targets + // allocated to them and should not use the Prometheus hashmod-based + // allocation. envVars = append(envVars, corev1.EnvVar{ Name: "SHARD", Value: "0",