Skip to content

Commit af4f66c

Browse files
authored
Merge pull request #595 from kartverket/customizable-scrape-interval
prometheus: add scrapeInterval
2 parents d2e27a5 + e6f6379 commit af4f66c

22 files changed

+201
-12
lines changed

api/v1alpha1/application_types.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ package v1alpha1
33
import (
44
"encoding/json"
55
"errors"
6+
"time"
7+
68
"github.com/kartverket/skiperator/api/v1alpha1/digdirator"
79
"github.com/kartverket/skiperator/api/v1alpha1/istiotypes"
810
"github.com/kartverket/skiperator/api/v1alpha1/podtypes"
911
corev1 "k8s.io/api/core/v1"
1012
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
1113
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1214
"k8s.io/apimachinery/pkg/util/intstr"
13-
"time"
1415
)
1516

1617
// +kubebuilder:object:root=true
@@ -333,6 +334,16 @@ type PrometheusConfig struct {
333334
//+kubebuilder:default:=false
334335
//+kubebuilder:validation:Optional
335336
AllowAllMetrics bool `json:"allowAllMetrics,omitempty"`
337+
338+
// ScrapeInterval specifies the interval at which Prometheus should scrape the metrics.
339+
// The interval must be at least 15 seconds (if using "Xs") and divisible by 5.
340+
// If minutes ("Xm") are used, the value must be at least 1m.
341+
//
342+
//+kubebuilder:default:="60s"
343+
//+kubebuilder:validation:Optional
344+
//+kubebuilder:validation:XValidation:rule="self == '' || self.matches('^([0-9]+[sm])+$')",messageExpression="'Rejected: ' + self + ' as an invalid value. ScrapeInterval must be empty (default applies) or in the format of <number>s or <number>m.'"
345+
//+kubebuilder:validation:XValidation:rule="self == '' || (self.endsWith('m') && int(self.split('m')[0]) >= 1) || (self.endsWith('s') && int(self.split('s')[0]) >= 15 && int(self.split('s')[0]) % 5 == 0)",messageExpression="'Rejected: ' + self + ' as an invalid value. ScrapeInterval must be at least 15s (if using <s>) and divisible by 5, or at least 1m (if using <m>).'"
346+
ScrapeInterval string `json:"scrapeInterval,omitempty"`
336347
}
337348

338349
func NewDefaultReplicas() Replicas {

cmd/skiperator/main.go

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ func main() {
5555
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&zap.Options{
5656
Development: !*isDeployment,
5757
Level: parsedLogLevel,
58+
DestWriter: os.Stdout,
5859
})))
5960

6061
setupLog.Info(fmt.Sprintf("Running skiperator %s (commit %s)", Version, Commit))

config/crd/skiperator.kartverket.no_applications.yaml

+18
Original file line numberDiff line numberDiff line change
@@ -947,6 +947,24 @@ spec:
947947
description: The port number or name where metrics are exposed
948948
(at the Pod level).
949949
x-kubernetes-int-or-string: true
950+
scrapeInterval:
951+
default: 60s
952+
description: |-
953+
ScrapeInterval specifies the interval at which Prometheus should scrape the metrics.
954+
The interval must be at least 15 seconds (if using "Xs") and divisible by 5.
955+
If minutes ("Xm") are used, the value must be at least 1m.
956+
type: string
957+
x-kubernetes-validations:
958+
- messageExpression: '''Rejected: '' + self + '' as an invalid
959+
value. ScrapeInterval must be empty (default applies) or in
960+
the format of <number>s or <number>m.'''
961+
rule: self == '' || self.matches('^([0-9]+[sm])+$')
962+
- messageExpression: '''Rejected: '' + self + '' as an invalid
963+
value. ScrapeInterval must be at least 15s (if using <s>)
964+
and divisible by 5, or at least 1m (if using <m>).'''
965+
rule: self == '' || (self.endsWith('m') && int(self.split('m')[0])
966+
>= 1) || (self.endsWith('s') && int(self.split('s')[0]) >=
967+
15 && int(self.split('s')[0]) % 5 == 0)
950968
required:
951969
- port
952970
type: object

config/crd/skiperator.kartverket.no_skipjobs.yaml

+18
Original file line numberDiff line numberDiff line change
@@ -880,6 +880,24 @@ spec:
880880
description: The port number or name where metrics are exposed
881881
(at the Pod level).
882882
x-kubernetes-int-or-string: true
883+
scrapeInterval:
884+
default: 60s
885+
description: |-
886+
ScrapeInterval specifies the interval at which Prometheus should scrape the metrics.
887+
The interval must be at least 15 seconds (if using "Xs") and divisible by 5.
888+
If minutes ("Xm") are used, the value must be at least 1m.
889+
type: string
890+
x-kubernetes-validations:
891+
- messageExpression: '''Rejected: '' + self + '' as an invalid
892+
value. ScrapeInterval must be empty (default applies) or in
893+
the format of <number>s or <number>m.'''
894+
rule: self == '' || self.matches('^([0-9]+[sm])+$')
895+
- messageExpression: '''Rejected: '' + self + '' as an invalid
896+
value. ScrapeInterval must be at least 15s (if using <s>)
897+
and divisible by 5, or at least 1m (if using <m>).'''
898+
rule: self == '' || (self.endsWith('m') && int(self.split('m')[0])
899+
>= 1) || (self.endsWith('s') && int(self.split('s')[0]) >=
900+
15 && int(self.split('s')[0]) % 5 == 0)
883901
required:
884902
- port
885903
type: object

internal/controllers/application.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ import (
2424
"github.com/kartverket/skiperator/pkg/resourcegenerator/maskinporten"
2525
networkpolicy "github.com/kartverket/skiperator/pkg/resourcegenerator/networkpolicy/dynamic"
2626
"github.com/kartverket/skiperator/pkg/resourcegenerator/pdb"
27+
"github.com/kartverket/skiperator/pkg/resourcegenerator/prometheus"
2728
"github.com/kartverket/skiperator/pkg/resourcegenerator/resourceutils"
2829
"github.com/kartverket/skiperator/pkg/resourcegenerator/service"
2930
"github.com/kartverket/skiperator/pkg/resourcegenerator/serviceaccount"
30-
"github.com/kartverket/skiperator/pkg/resourcegenerator/servicemonitor"
3131
"github.com/kartverket/skiperator/pkg/util"
3232
nais_io_v1 "github.com/nais/liberator/pkg/apis/nais.io/v1"
3333
pov1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
@@ -207,7 +207,7 @@ func (r *ApplicationReconciler) Reconcile(ctx context.Context, req reconcile.Req
207207
networkpolicy.Generate,
208208
authorizationpolicy.Generate,
209209
pdb.Generate,
210-
servicemonitor.Generate,
210+
prometheus.Generate,
211211
idporten.Generate,
212212
maskinporten.Generate,
213213
deployment.Generate,

internal/controllers/skipjob.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
"github.com/kartverket/skiperator/pkg/resourcegenerator/istio/telemetry"
1515
"github.com/kartverket/skiperator/pkg/resourcegenerator/job"
1616
networkpolicy "github.com/kartverket/skiperator/pkg/resourcegenerator/networkpolicy/dynamic"
17-
"github.com/kartverket/skiperator/pkg/resourcegenerator/podmonitor"
17+
"github.com/kartverket/skiperator/pkg/resourcegenerator/prometheus"
1818
"github.com/kartverket/skiperator/pkg/resourcegenerator/resourceutils"
1919
"github.com/kartverket/skiperator/pkg/resourcegenerator/serviceaccount"
2020
istionetworkingv1 "istio.io/client-go/pkg/apis/networking/v1"
@@ -163,7 +163,7 @@ func (r *SKIPJobReconciler) Reconcile(ctx context.Context, req reconcile.Request
163163
serviceentry.Generate,
164164
auth.Generate,
165165
job.Generate,
166-
podmonitor.Generate,
166+
prometheus.Generate,
167167
telemetry.Generate,
168168
}
169169

pkg/resourcegenerator/podmonitor/pod_monitor.go pkg/resourcegenerator/prometheus/pod_monitor.go

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
1-
package podmonitor
1+
package prometheus
22

33
import (
44
"fmt"
5+
"strings"
6+
57
skiperatorv1alpha1 "github.com/kartverket/skiperator/api/v1alpha1"
68
"github.com/kartverket/skiperator/pkg/reconciliation"
79
"github.com/kartverket/skiperator/pkg/util"
810
pov1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
911
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10-
"strings"
1112
)
1213

13-
func Generate(r reconciliation.Reconciliation) error {
14+
func init() {
15+
multiGenerator.Register(reconciliation.JobType, generateForSkipJob)
16+
}
17+
18+
func generateForSkipJob(r reconciliation.Reconciliation) error {
1419
ctxLog := r.GetLogger()
1520
ctxLog.Debug("Attempting to generate podmonitor for skipjob", "skipjob", r.GetSKIPObject().GetName())
1621

@@ -41,6 +46,7 @@ func Generate(r reconciliation.Reconciliation) error {
4146
{
4247
Path: util.IstioMetricsPath,
4348
TargetPort: &util.IstioMetricsPortName,
49+
Interval: getScrapeInterval(skipJob.Spec.Prometheus),
4450
},
4551
},
4652
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package prometheus
2+
3+
import (
4+
"github.com/kartverket/skiperator/api/v1alpha1"
5+
"github.com/kartverket/skiperator/pkg/reconciliation"
6+
"github.com/kartverket/skiperator/pkg/resourcegenerator/resourceutils/generator"
7+
pov1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
8+
)
9+
10+
var (
11+
multiGenerator = generator.NewMulti()
12+
defaultScrapeInterval = pov1.Duration("60s")
13+
)
14+
15+
func Generate(r reconciliation.Reconciliation) error {
16+
return multiGenerator.Generate(r, "PrometheusCRD")
17+
}
18+
19+
func getScrapeInterval(pc *v1alpha1.PrometheusConfig) pov1.Duration {
20+
if pc == nil {
21+
return defaultScrapeInterval
22+
}
23+
24+
return pov1.Duration(pc.ScrapeInterval)
25+
}

pkg/resourcegenerator/servicemonitor/service_monitor.go pkg/resourcegenerator/prometheus/service_monitor.go

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
1-
package servicemonitor
1+
package prometheus
22

33
import (
44
"fmt"
5+
"strings"
6+
57
skiperatorv1alpha1 "github.com/kartverket/skiperator/api/v1alpha1"
68
"github.com/kartverket/skiperator/pkg/reconciliation"
79
"github.com/kartverket/skiperator/pkg/util"
810
pov1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
911
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10-
"strings"
1112
)
1213

13-
func Generate(r reconciliation.Reconciliation) error {
14+
func init() {
15+
multiGenerator.Register(reconciliation.ApplicationType, generateForApplication)
16+
}
17+
18+
func generateForApplication(r reconciliation.Reconciliation) error {
1419
ctxLog := r.GetLogger()
1520
if r.GetType() != reconciliation.ApplicationType {
1621
return fmt.Errorf("unsupported type %s in service monitor", r.GetType())
@@ -44,6 +49,7 @@ func Generate(r reconciliation.Reconciliation) error {
4449
{
4550
Path: util.IstioMetricsPath,
4651
TargetPort: &util.IstioMetricsPortName,
52+
Interval: getScrapeInterval(application.Spec.Prometheus),
4753
MetricRelabelConfigs: []pov1.RelabelConfig{
4854
{
4955
Action: "drop",

tests/application/service-monitor/application-istio-assert.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ spec:
6868
endpoints:
6969
- targetPort: istio-metrics
7070
path: /stats/prometheus
71+
interval: "60s"
7172
metricRelabelings:
7273
- action: drop
7374
regex: istio_request_bytes_bucket|istio_response_bytes_bucket|istio_request_duration_milliseconds_bucket

tests/application/service-monitor/application-simple-assert.yaml

+2-1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ spec:
5757
endpoints:
5858
- targetPort: istio-metrics
5959
path: /stats/prometheus
60+
interval: "60s"
6061
metricRelabelings:
6162
- action: drop
6263
regex: istio_request_bytes_bucket|istio_response_bytes_bucket|istio_request_duration_milliseconds_bucket
@@ -100,4 +101,4 @@ spec:
100101
app.kubernetes.io/instance: alloy
101102
app.kubernetes.io/name: alloy
102103
ports:
103-
- port: istio-metrics
104+
- port: istio-metrics
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
apiVersion: monitoring.coreos.com/v1
2+
kind: ServiceMonitor
3+
metadata:
4+
labels:
5+
instance: primary
6+
name: some-simple-monitored-app-1
7+
namespace: sm-istio-ns-2
8+
spec:
9+
endpoints:
10+
- targetPort: istio-metrics
11+
path: /stats/prometheus
12+
interval: "90s"
13+
metricRelabelings:
14+
- action: drop
15+
regex: istio_request_bytes_bucket|istio_response_bytes_bucket|istio_request_duration_milliseconds_bucket
16+
sourceLabels:
17+
- __name__
18+
selector:
19+
matchLabels:
20+
app: some-simple-monitored-app-1
21+
namespaceSelector:
22+
matchNames:
23+
- sm-istio-ns-2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
apiVersion: skiperator.kartverket.no/v1alpha1
2+
kind: Application
3+
metadata:
4+
name: some-simple-monitored-app-1
5+
namespace: sm-istio-ns-2
6+
spec:
7+
image: image
8+
port: 8080
9+
prometheus:
10+
port: 8080
11+
scrapeInterval: 10s
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
apiVersion: v1
2+
kind: Namespace
3+
metadata:
4+
name: sm-istio-ns-2
5+
labels:
6+
istio.io/rev: "revision-1"
7+
---
8+
apiVersion: skiperator.kartverket.no/v1alpha1
9+
kind: Application
10+
metadata:
11+
name: some-simple-monitored-app-1
12+
namespace: sm-istio-ns-2
13+
spec:
14+
image: image
15+
port: 8080
16+
prometheus:
17+
port: 8080
18+
scrapeInterval: 90s

tests/application/service-monitor/chainsaw-test.yaml

+7
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,10 @@ spec:
2323
file: patch-application-allowall.yaml
2424
- assert:
2525
file: patch-application-allowall-assert.yaml
26+
- try:
27+
- apply:
28+
file: application-simple-custom-interval.yaml
29+
- assert:
30+
file: application-simple-custom-interval-assert.yaml
31+
- error:
32+
file: application-simple-custom-interval-invalid.yaml

tests/application/service-monitor/patch-application-allowall-assert.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ spec:
99
endpoints:
1010
- targetPort: istio-metrics
1111
path: /stats/prometheus
12+
interval: "60s"
1213
selector:
1314
matchLabels:
1415
app: some-monitored-app-1

tests/skipjob/podmonitor/chainsaw-test.yaml

+5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ spec:
1818
file: patch-skipjob-with-monitoring.yaml
1919
- assert:
2020
file: patch-skipjob-with-monitoring-assert.yaml
21+
- try:
22+
- patch:
23+
file: patch-skipjob-with-monitoring-custom-interval.yaml
24+
- assert:
25+
file: patch-skipjob-with-monitoring-custom-interval-assert.yaml
2126
- try:
2227
- patch:
2328
file: patch-skipjob-remove-monitoring.yaml

tests/skipjob/podmonitor/patch-skipjob-remove-monitoring-error.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ spec:
1111
podMetricsEndpoints:
1212
- targetPort: istio-metrics
1313
path: "/stats/prometheus"
14+
interval: "60s"
1415
metricRelabelings:
1516
- action: drop
1617
regex: istio_request_bytes_bucket|istio_response_bytes_bucket|istio_request_duration_milliseconds_bucket

tests/skipjob/podmonitor/patch-skipjob-with-monitoring-assert.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ spec:
1111
podMetricsEndpoints:
1212
- targetPort: istio-metrics
1313
path: "/stats/prometheus"
14+
interval: "60s"
1415
selector:
1516
matchLabels:
1617
app: podmonitor
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
apiVersion: monitoring.coreos.com/v1
2+
kind: PodMonitor
3+
metadata:
4+
labels:
5+
instance: primary
6+
name: podmonitor-monitor
7+
spec:
8+
namespaceSelector:
9+
matchNames:
10+
- podmonitor-ns
11+
podMetricsEndpoints:
12+
- targetPort: istio-metrics
13+
path: "/stats/prometheus"
14+
interval: "100s"
15+
selector:
16+
matchLabels:
17+
app: podmonitor
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
apiVersion: skiperator.kartverket.no/v1alpha1
2+
kind: SKIPJob
3+
metadata:
4+
name: podmonitor
5+
spec:
6+
container:
7+
image: "perl:5.34.0"
8+
command:
9+
- "perl"
10+
- "-Mbignum=bpi"
11+
- "-wle"
12+
- "print bpi(2000)"
13+
prometheus:
14+
path: /metrics
15+
port: 8080
16+
allowAllMetrics: true
17+
scrapeInterval: "100s"

tests/skipjob/podmonitor/skipjob-with-monitoring-assert.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ spec:
5555
podMetricsEndpoints:
5656
- targetPort: istio-metrics
5757
path: "/stats/prometheus"
58+
interval: "60s"
5859
metricRelabelings:
5960
- action: drop
6061
regex: istio_request_bytes_bucket|istio_response_bytes_bucket|istio_request_duration_milliseconds_bucket

0 commit comments

Comments
 (0)