Skip to content

Commit 9770b1f

Browse files
author
Israel Blancas
authored
Merge branch 'main' into 3370
2 parents 40161be + 05228b9 commit 9770b1f

File tree

6 files changed

+285
-36
lines changed

6 files changed

+285
-36
lines changed

.chloggen/scrape-config-probe.yaml

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
2+
change_type: enhancement
3+
4+
# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action)
5+
component: target allocator
6+
7+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
8+
note: enables support for pulling scrape config and probe CRDs in the target allocator
9+
10+
# One or more tracking issues related to the change
11+
issues: [1842]
12+
13+
# (Optional) One or more lines of additional information to render under the primary note.
14+
# These lines will be padded with 2 spaces and then inserted directly into the document.
15+
# Use pipe (|) for multiline entries.
16+
subtext:

cmd/otel-allocator/config/config.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,13 @@ type Config struct {
6161
type PrometheusCRConfig struct {
6262
Enabled bool `yaml:"enabled,omitempty"`
6363
PodMonitorSelector *metav1.LabelSelector `yaml:"pod_monitor_selector,omitempty"`
64+
PodMonitorNamespaceSelector *metav1.LabelSelector `yaml:"pod_monitor_namespace_selector,omitempty"`
6465
ServiceMonitorSelector *metav1.LabelSelector `yaml:"service_monitor_selector,omitempty"`
6566
ServiceMonitorNamespaceSelector *metav1.LabelSelector `yaml:"service_monitor_namespace_selector,omitempty"`
66-
PodMonitorNamespaceSelector *metav1.LabelSelector `yaml:"pod_monitor_namespace_selector,omitempty"`
67+
ScrapeConfigSelector *metav1.LabelSelector `yaml:"scrape_config_selector,omitempty"`
68+
ScrapeConfigNamespaceSelector *metav1.LabelSelector `yaml:"scrape_config_namespace_selector,omitempty"`
69+
ProbeSelector *metav1.LabelSelector `yaml:"probe_selector,omitempty"`
70+
ProbeNamespaceSelector *metav1.LabelSelector `yaml:"probe_namespace_selector,omitempty"`
6771
ScrapeInterval model.Duration `yaml:"scrape_interval,omitempty"`
6872
}
6973

cmd/otel-allocator/watcher/promOperator.go

+89-18
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import (
2222
"time"
2323

2424
"github.com/blang/semver/v4"
25-
"github.com/go-kit/log"
25+
gokitlog "github.com/go-kit/log"
2626
"github.com/go-kit/log/level"
2727
"github.com/go-logr/logr"
2828
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
@@ -53,6 +53,9 @@ const (
5353
)
5454

5555
func NewPrometheusCRWatcher(ctx context.Context, logger logr.Logger, cfg allocatorconfig.Config) (*PrometheusCRWatcher, error) {
56+
// TODO: Remove this after go 1.23 upgrade
57+
promLogger := level.NewFilter(gokitlog.NewLogfmtLogger(os.Stderr), level.AllowWarn())
58+
slogger := slog.New(logr.ToSlogHandler(logger))
5659
var resourceSelector *prometheus.ResourceSelector
5760
mClient, err := monitoringclient.NewForConfig(cfg.ClusterConfig)
5861
if err != nil {
@@ -79,18 +82,20 @@ func NewPrometheusCRWatcher(ctx context.Context, logger logr.Logger, cfg allocat
7982
Spec: monitoringv1.PrometheusSpec{
8083
CommonPrometheusFields: monitoringv1.CommonPrometheusFields{
8184
ScrapeInterval: monitoringv1.Duration(cfg.PrometheusCR.ScrapeInterval.String()),
82-
ServiceMonitorSelector: cfg.PrometheusCR.ServiceMonitorSelector,
8385
PodMonitorSelector: cfg.PrometheusCR.PodMonitorSelector,
84-
ServiceMonitorNamespaceSelector: cfg.PrometheusCR.ServiceMonitorNamespaceSelector,
8586
PodMonitorNamespaceSelector: cfg.PrometheusCR.PodMonitorNamespaceSelector,
87+
ServiceMonitorSelector: cfg.PrometheusCR.ServiceMonitorSelector,
88+
ServiceMonitorNamespaceSelector: cfg.PrometheusCR.ServiceMonitorNamespaceSelector,
89+
ScrapeConfigSelector: cfg.PrometheusCR.ScrapeConfigSelector,
90+
ScrapeConfigNamespaceSelector: cfg.PrometheusCR.ScrapeConfigNamespaceSelector,
91+
ProbeSelector: cfg.PrometheusCR.ProbeSelector,
92+
ProbeNamespaceSelector: cfg.PrometheusCR.ProbeNamespaceSelector,
8693
ServiceDiscoveryRole: &serviceDiscoveryRole,
8794
},
8895
},
8996
}
9097

91-
promOperatorLogger := level.NewFilter(log.NewLogfmtLogger(os.Stderr), level.AllowWarn())
92-
promOperatorSlogLogger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelWarn}))
93-
generator, err := prometheus.NewConfigGenerator(promOperatorLogger, prom, true)
98+
generator, err := prometheus.NewConfigGenerator(promLogger, prom, true)
9499

95100
if err != nil {
96101
return nil, err
@@ -108,21 +113,21 @@ func NewPrometheusCRWatcher(ctx context.Context, logger logr.Logger, cfg allocat
108113
logger.Error(err, "Retrying namespace informer creation in promOperator CRD watcher")
109114
return true
110115
}, func() error {
111-
nsMonInf, err = getNamespaceInformer(ctx, map[string]struct{}{v1.NamespaceAll: {}}, promOperatorLogger, clientset, operatorMetrics)
116+
nsMonInf, err = getNamespaceInformer(ctx, map[string]struct{}{v1.NamespaceAll: {}}, promLogger, clientset, operatorMetrics)
112117
return err
113118
})
114119
if getNamespaceInformerErr != nil {
115120
logger.Error(getNamespaceInformerErr, "Failed to create namespace informer in promOperator CRD watcher")
116121
return nil, getNamespaceInformerErr
117122
}
118123

119-
resourceSelector, err = prometheus.NewResourceSelector(promOperatorSlogLogger, prom, store, nsMonInf, operatorMetrics, eventRecorder)
124+
resourceSelector, err = prometheus.NewResourceSelector(slogger, prom, store, nsMonInf, operatorMetrics, eventRecorder)
120125
if err != nil {
121126
logger.Error(err, "Failed to create resource selector in promOperator CRD watcher")
122127
}
123128

124129
return &PrometheusCRWatcher{
125-
logger: logger,
130+
logger: slogger,
126131
kubeMonitoringClient: mClient,
127132
k8sClient: clientset,
128133
informers: monitoringInformers,
@@ -133,13 +138,15 @@ func NewPrometheusCRWatcher(ctx context.Context, logger logr.Logger, cfg allocat
133138
kubeConfigPath: cfg.KubeConfigFilePath,
134139
podMonitorNamespaceSelector: cfg.PrometheusCR.PodMonitorNamespaceSelector,
135140
serviceMonitorNamespaceSelector: cfg.PrometheusCR.ServiceMonitorNamespaceSelector,
141+
scrapeConfigNamespaceSelector: cfg.PrometheusCR.ScrapeConfigNamespaceSelector,
142+
probeNamespaceSelector: cfg.PrometheusCR.ProbeNamespaceSelector,
136143
resourceSelector: resourceSelector,
137144
store: store,
138145
}, nil
139146
}
140147

141148
type PrometheusCRWatcher struct {
142-
logger logr.Logger
149+
logger *slog.Logger
143150
kubeMonitoringClient monitoringclient.Interface
144151
k8sClient kubernetes.Interface
145152
informers map[string]*informers.ForResource
@@ -150,12 +157,13 @@ type PrometheusCRWatcher struct {
150157
kubeConfigPath string
151158
podMonitorNamespaceSelector *metav1.LabelSelector
152159
serviceMonitorNamespaceSelector *metav1.LabelSelector
160+
scrapeConfigNamespaceSelector *metav1.LabelSelector
161+
probeNamespaceSelector *metav1.LabelSelector
153162
resourceSelector *prometheus.ResourceSelector
154163
store *assets.StoreBuilder
155164
}
156165

157-
func getNamespaceInformer(ctx context.Context, allowList map[string]struct{}, promOperatorLogger log.Logger, clientset kubernetes.Interface, operatorMetrics *operator.Metrics) (cache.SharedIndexInformer, error) {
158-
166+
func getNamespaceInformer(ctx context.Context, allowList map[string]struct{}, promOperatorLogger gokitlog.Logger, clientset kubernetes.Interface, operatorMetrics *operator.Metrics) (cache.SharedIndexInformer, error) {
159167
kubernetesVersion, err := clientset.Discovery().ServerVersion()
160168
if err != nil {
161169
return nil, err
@@ -196,9 +204,21 @@ func getInformers(factory informers.FactoriesForNamespaces) (map[string]*informe
196204
return nil, err
197205
}
198206

207+
probeInformers, err := informers.NewInformersForResource(factory, monitoringv1.SchemeGroupVersion.WithResource(monitoringv1.ProbeName))
208+
if err != nil {
209+
return nil, err
210+
}
211+
212+
scrapeConfigInformers, err := informers.NewInformersForResource(factory, promv1alpha1.SchemeGroupVersion.WithResource(promv1alpha1.ScrapeConfigName))
213+
if err != nil {
214+
return nil, err
215+
}
216+
199217
return map[string]*informers.ForResource{
200218
monitoringv1.ServiceMonitorName: serviceMonitorInformers,
201219
monitoringv1.PodMonitorName: podMonitorInformers,
220+
monitoringv1.ProbeName: probeInformers,
221+
promv1alpha1.ScrapeConfigName: scrapeConfigInformers,
202222
}, nil
203223
}
204224

@@ -210,7 +230,7 @@ func (w *PrometheusCRWatcher) Watch(upstreamEvents chan Event, upstreamErrors ch
210230

211231
if w.nsInformer != nil {
212232
go w.nsInformer.Run(w.stopChannel)
213-
if ok := cache.WaitForNamedCacheSync("namespace", w.stopChannel, w.nsInformer.HasSynced); !ok {
233+
if ok := w.WaitForNamedCacheSync("namespace", w.nsInformer.HasSynced); !ok {
214234
success = false
215235
}
216236

@@ -228,10 +248,12 @@ func (w *PrometheusCRWatcher) Watch(upstreamEvents chan Event, upstreamErrors ch
228248
for name, selector := range map[string]*metav1.LabelSelector{
229249
"PodMonitorNamespaceSelector": w.podMonitorNamespaceSelector,
230250
"ServiceMonitorNamespaceSelector": w.serviceMonitorNamespaceSelector,
251+
"ProbeNamespaceSelector": w.probeNamespaceSelector,
252+
"ScrapeConfigNamespaceSelector": w.scrapeConfigNamespaceSelector,
231253
} {
232254
sync, err := k8sutil.LabelSelectionHasChanged(old.Labels, cur.Labels, selector)
233255
if err != nil {
234-
w.logger.Error(err, "Failed to check label selection between namespaces while handling namespace updates", "selector", name)
256+
w.logger.Error("Failed to check label selection between namespaces while handling namespace updates", "selector", name, "error", err)
235257
return
236258
}
237259

@@ -252,8 +274,9 @@ func (w *PrometheusCRWatcher) Watch(upstreamEvents chan Event, upstreamErrors ch
252274
for name, resource := range w.informers {
253275
resource.Start(w.stopChannel)
254276

255-
if ok := cache.WaitForNamedCacheSync(name, w.stopChannel, resource.HasSynced); !ok {
256-
success = false
277+
if ok := w.WaitForNamedCacheSync(name, resource.HasSynced); !ok {
278+
w.logger.Info("skipping informer", "informer", name)
279+
continue
257280
}
258281

259282
// only send an event notification if there isn't one already
@@ -342,6 +365,16 @@ func (w *PrometheusCRWatcher) LoadConfig(ctx context.Context) (*promconfig.Confi
342365
return nil, err
343366
}
344367

368+
probeInstances, err := w.resourceSelector.SelectProbes(ctx, w.informers[monitoringv1.ProbeName].ListAllByNamespace)
369+
if err != nil {
370+
return nil, err
371+
}
372+
373+
scrapeConfigInstances, err := w.resourceSelector.SelectScrapeConfigs(ctx, w.informers[promv1alpha1.ScrapeConfigName].ListAllByNamespace)
374+
if err != nil {
375+
return nil, err
376+
}
377+
345378
generatedConfig, err := w.configGenerator.GenerateServerConfiguration(
346379
"30s",
347380
"",
@@ -352,8 +385,8 @@ func (w *PrometheusCRWatcher) LoadConfig(ctx context.Context) (*promconfig.Confi
352385
nil,
353386
serviceMonitorInstances,
354387
podMonitorInstances,
355-
map[string]*monitoringv1.Probe{},
356-
map[string]*promv1alpha1.ScrapeConfig{},
388+
probeInstances,
389+
scrapeConfigInstances,
357390
w.store,
358391
nil,
359392
nil,
@@ -384,3 +417,41 @@ func (w *PrometheusCRWatcher) LoadConfig(ctx context.Context) (*promconfig.Confi
384417
return promCfg, nil
385418
}
386419
}
420+
421+
// WaitForNamedCacheSync adds a timeout to the informer's wait for the cache to be ready.
422+
// If the PrometheusCRWatcher is unable to load an informer within 15 seconds, the method is
423+
// cancelled and returns false. A successful informer load will return true. This method also
424+
// will be cancelled if the target allocator's stopChannel is called before it returns.
425+
//
426+
// This method is inspired by the upstream prometheus-operator implementation, with a shorter timeout
427+
// and support for the PrometheusCRWatcher's stopChannel.
428+
// https://github.com/prometheus-operator/prometheus-operator/blob/293c16c854ce69d1da9fdc8f0705de2d67bfdbfa/pkg/operator/operator.go#L433
429+
func (w *PrometheusCRWatcher) WaitForNamedCacheSync(controllerName string, inf cache.InformerSynced) bool {
430+
ctx, cancel := context.WithTimeout(context.Background(), time.Second*15)
431+
t := time.NewTicker(time.Second * 5)
432+
defer t.Stop()
433+
434+
go func() {
435+
for {
436+
select {
437+
case <-t.C:
438+
w.logger.Debug("cache sync not yet completed")
439+
case <-ctx.Done():
440+
return
441+
case <-w.stopChannel:
442+
w.logger.Warn("stop received, shutting down cache syncing")
443+
cancel()
444+
return
445+
}
446+
}
447+
}()
448+
449+
ok := cache.WaitForNamedCacheSync(controllerName, ctx.Done(), inf)
450+
if !ok {
451+
w.logger.Error("failed to sync cache")
452+
} else {
453+
w.logger.Debug("successfully synced cache")
454+
}
455+
456+
return ok
457+
}

0 commit comments

Comments
 (0)