From 5fcaeadcaf58c0d87e2157ede7b8278d57911b47 Mon Sep 17 00:00:00 2001 From: ITQ Date: Sat, 23 May 2026 01:11:38 +0300 Subject: [PATCH] feat(helm): added observability to helm chart --- deploy/argocd/grafana.yaml | 79 ++ deploy/helm/movienight/templates/_helpers.tpl | 32 + .../templates/backend/deployment.yaml | 19 +- .../movienight/templates/backend/service.yaml | 6 + .../grafana-dashboard-business.yaml | 1092 +++++++++++++++++ .../observability/grafana-dashboard-red.yaml | 828 +++++++++++++ .../observability/grafana-datasource.yaml | 39 + .../observability/victoriametrics.yaml | 142 +++ .../templates/observability/vmagent.yaml | 169 +++ deploy/helm/movienight/values.schema.json | 37 + deploy/helm/movienight/values.yaml | 77 +- 11 files changed, 2516 insertions(+), 4 deletions(-) create mode 100644 deploy/argocd/grafana.yaml create mode 100644 deploy/helm/movienight/templates/observability/grafana-dashboard-business.yaml create mode 100644 deploy/helm/movienight/templates/observability/grafana-dashboard-red.yaml create mode 100644 deploy/helm/movienight/templates/observability/grafana-datasource.yaml create mode 100644 deploy/helm/movienight/templates/observability/victoriametrics.yaml create mode 100644 deploy/helm/movienight/templates/observability/vmagent.yaml diff --git a/deploy/argocd/grafana.yaml b/deploy/argocd/grafana.yaml new file mode 100644 index 0000000..9d34053 --- /dev/null +++ b/deploy/argocd/grafana.yaml @@ -0,0 +1,79 @@ +--- +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: grafana + namespace: argocd +spec: + project: default + source: + repoURL: oci://ghcr.io/grafana-community/helm-charts/grafana + path: . + targetRevision: 12.3.0 + helm: + valuesObject: + envValueFrom: + GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET: + secretKeyRef: + name: grafana-secrets + key: client-secret + + grafana.ini: + server: + root_url: https://grafana.internal.itqdev.xyz + + auth: + disable_login_form: false + oauth_auto_login: false + + auth.generic_oauth: + enabled: true + name: Keycloak + allow_sign_up: true + client_id: grafana-private + client_secret: ${GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET} + scopes: openid profile email + use_pkce: true + + auth_url: https://id.itqdev.xyz/realms/master/protocol/openid-connect/auth + token_url: https://id.itqdev.xyz/realms/master/protocol/openid-connect/token + api_url: https://id.itqdev.xyz/realms/master/protocol/openid-connect/userinfo + + role_attribute_path: > + contains(groups[*], 'admin') && 'Admin' || + contains(groups[*], 'editor') && 'Editor' || + 'Viewer' + role_attribute_strict: false + + use_refresh_token: true + id_token_attribute_name: preferred_username + + sidecar: + dashboards: + enabled: true + label: grafana_dashboard + labelValue: "1" + searchNamespace: ALL + folderAnnotation: grafana_folder + provider: + folder: MovieNight + allowUiUpdates: false + datasources: + enabled: true + label: grafana_datasource + labelValue: "1" + searchNamespace: ALL + + destination: + server: https://kubernetes.default.svc + namespace: grafana + + syncPolicy: + automated: + prune: true + selfHeal: true + enabled: true + syncOptions: + - CreateNamespace=true + - ApplyOutOfSyncOnly=true + - ServerSideApply=true diff --git a/deploy/helm/movienight/templates/_helpers.tpl b/deploy/helm/movienight/templates/_helpers.tpl index 5479b62..e32e83f 100644 --- a/deploy/helm/movienight/templates/_helpers.tpl +++ b/deploy/helm/movienight/templates/_helpers.tpl @@ -123,3 +123,35 @@ app.kubernetes.io/component: {{ $component }} key: password {{- end -}} {{- end -}} + +{{- define "movienight.victoriaMetricsName" -}} +{{- printf "%s-victoriametrics" (include "movienight.fullname" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "movienight.vmagentName" -}} +{{- printf "%s-vmagent" (include "movienight.fullname" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "movienight.victoriaMetricsURL" -}} +{{- if .Values.observability.grafana.datasource.url -}} +{{- .Values.observability.grafana.datasource.url -}} +{{- else -}} +{{- printf "http://%s.%s.svc:%v" (include "movienight.victoriaMetricsName" .) .Release.Namespace .Values.observability.victoriaMetrics.service.port -}} +{{- end -}} +{{- end -}} + +{{- define "movienight.vmagentRemoteWriteURL" -}} +{{- if .Values.observability.vmagent.remoteWriteUrl -}} +{{- .Values.observability.vmagent.remoteWriteUrl -}} +{{- else -}} +{{- printf "http://%s:%v/api/v1/write" (include "movienight.victoriaMetricsName" .) .Values.observability.victoriaMetrics.service.port -}} +{{- end -}} +{{- end -}} + +{{- define "movienight.backendMetricsTarget" -}} +{{- if .Values.backend.management.enabled -}} +{{- printf "%s-backend:%v" (include "movienight.fullname" .) .Values.backend.management.port -}} +{{- else -}} +{{- printf "%s-backend:%v" (include "movienight.fullname" .) .Values.backend.service.port -}} +{{- end -}} +{{- end -}} diff --git a/deploy/helm/movienight/templates/backend/deployment.yaml b/deploy/helm/movienight/templates/backend/deployment.yaml index 2a03d9d..4f8d8b5 100644 --- a/deploy/helm/movienight/templates/backend/deployment.yaml +++ b/deploy/helm/movienight/templates/backend/deployment.yaml @@ -48,8 +48,25 @@ spec: - name: http containerPort: {{ .Values.backend.service.port }} protocol: TCP - {{- if or $postgresEnv .Values.backend.env }} + {{- if .Values.backend.management.enabled }} + - name: management + containerPort: {{ .Values.backend.management.port }} + protocol: TCP + {{- end }} + {{- if or $postgresEnv .Values.backend.env .Values.backend.management.enabled .Values.observability.enabled }} env: +{{- if .Values.backend.management.enabled }} + - name: MANAGEMENT_SERVER_PORT + value: {{ .Values.backend.management.port | quote }} +{{- end }} +{{- if .Values.observability.enabled }} + - name: MANAGEMENT_METRICS_TAGS_APPLICATION + value: {{ .Values.observability.metrics.applicationTag | quote }} +{{- if .Values.observability.metrics.httpServerRequestsHistogram }} + - name: MANAGEMENT_METRICS_DISTRIBUTION_PERCENTILES_HISTOGRAM_HTTP_SERVER_REQUESTS + value: "true" +{{- end }} +{{- end }} {{- if $postgresEnv }} {{- $postgresEnv | nindent 12 }} {{- end }} diff --git a/deploy/helm/movienight/templates/backend/service.yaml b/deploy/helm/movienight/templates/backend/service.yaml index 1a4ca83..4e3b62e 100644 --- a/deploy/helm/movienight/templates/backend/service.yaml +++ b/deploy/helm/movienight/templates/backend/service.yaml @@ -16,6 +16,12 @@ spec: port: {{ .Values.backend.service.port }} targetPort: http protocol: TCP + {{- if .Values.backend.management.enabled }} + - name: management + port: {{ .Values.backend.management.port }} + targetPort: management + protocol: TCP + {{- end }} selector: {{- include "movienight.componentSelectorLabels" (dict "root" . "component" "backend") | nindent 4 }} {{- end }} diff --git a/deploy/helm/movienight/templates/observability/grafana-dashboard-business.yaml b/deploy/helm/movienight/templates/observability/grafana-dashboard-business.yaml new file mode 100644 index 0000000..a70fab4 --- /dev/null +++ b/deploy/helm/movienight/templates/observability/grafana-dashboard-business.yaml @@ -0,0 +1,1092 @@ +{{- if and .Values.observability.enabled .Values.observability.grafana.dashboards.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "movienight.fullname" . }}-grafana-business-dashboard + labels: + {{- include "movienight.componentLabels" (dict "root" . "component" "grafana-dashboard") | nindent 4 }} + {{- with .Values.observability.grafana.dashboards.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or .Values.global.annotations .Values.observability.grafana.dashboards.annotations }} + annotations: + {{- with .Values.global.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.observability.grafana.dashboards.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +data: + movienight-business.json: | + { + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": null, + "links": [], + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "ops" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.3.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate({__name__=~\"business_recommendation_requests_total(_total)?\",job=~\"$job\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "recommendations", + "range": true, + "refId": "A" + } + ], + "title": "Recommendation Rate", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "ops" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 6, + "y": 0 + }, + "id": 2, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.3.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate({__name__=~\"business_ratings_submitted_total(_total)?\",job=~\"$job\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "ratings", + "range": true, + "refId": "A" + } + ], + "title": "Rating Rate", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "ops" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 12, + "y": 0 + }, + "id": 3, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.3.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate({__name__=~\"business_library_events_total(_total)?\",job=~\"$job\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "library events", + "range": true, + "refId": "A" + } + ], + "title": "Library Event Rate", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "orange", + "value": 1 + }, + { + "color": "red", + "value": 5 + } + ] + }, + "unit": "ops" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 18, + "y": 0 + }, + "id": 4, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.3.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate({__name__=~\"business_films_blocked_total(_total)?|business_jellyfin_backend_write_failures_total(_total)?|business_jellyfin_sync_failures_total(_total)?\",job=~\"$job\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "failures", + "range": true, + "refId": "A" + } + ], + "title": "Business Failure Rate", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "ops" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 4 + }, + "id": 5, + "options": { + "legend": { + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate({__name__=~\"business_recommendation_requests_total(_total)?\",job=~\"$job\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "recommendations", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate({__name__=~\"business_ratings_submitted_total(_total)?\",job=~\"$job\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "ratings", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate({__name__=~\"business_library_events_total(_total)?\",job=~\"$job\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "library", + "range": true, + "refId": "C" + } + ], + "title": "Core Business Throughput", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "normal" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "ops" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 4 + }, + "id": 6, + "options": { + "legend": { + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate({__name__=~\"business_films_created_total(_total)?\",job=~\"$job\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "created", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate({__name__=~\"business_films_edited_total(_total)?\",job=~\"$job\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "edited", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate({__name__=~\"business_films_deleted_total(_total)?\",job=~\"$job\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "deleted", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate({__name__=~\"business_films_blocked_total(_total)?\",job=~\"$job\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "blocked", + "range": true, + "refId": "D" + } + ], + "title": "Film Mutations", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 12 + }, + "id": 7, + "options": { + "legend": { + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate({__name__=~\"business_jellyfin_sync_runs_total(_total)?\",job=~\"$job\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "sync runs", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate({__name__=~\"business_jellyfin_synced_users_total(_total)?\",job=~\"$job\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "synced users", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate({__name__=~\"business_jellyfin_synced_items_total(_total)?\",job=~\"$job\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "synced items", + "range": true, + "refId": "C" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate({__name__=~\"business_jellyfin_skipped_users_total(_total)?\",job=~\"$job\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "skipped users", + "range": true, + "refId": "D" + } + ], + "title": "Jellyfin Sync Activity", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 12 + }, + "id": 8, + "options": { + "legend": { + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate({__name__=~\"business_jellyfin_sync_failures_total(_total)?\",job=~\"$job\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "sync failures", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate({__name__=~\"business_jellyfin_backend_write_failures_total(_total)?\",job=~\"$job\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "write failures", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(business_jellyfin_unmapped_users{job=~\"$job\"})", + "instant": false, + "legendFormat": "unmapped users", + "range": true, + "refId": "C" + } + ], + "title": "Jellyfin Problems", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 20 + }, + "id": 9, + "options": { + "legend": { + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.95, sum by (le) (rate(business_jellyfin_sync_duration_seconds_bucket{job=~\"$job\"}[$__rate_interval])))", + "instant": false, + "legendFormat": "p95", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate(business_jellyfin_sync_duration_seconds_sum{job=~\"$job\"}[$__rate_interval])) / clamp_min(sum(rate(business_jellyfin_sync_duration_seconds_count{job=~\"$job\"}[$__rate_interval])), 0.001)", + "instant": false, + "legendFormat": "mean", + "range": true, + "refId": "B" + } + ], + "title": "Jellyfin Sync Duration", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "ops" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 20 + }, + "id": 10, + "options": { + "legend": { + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum by (eventType) (rate({__name__=~\"recommendation_weights_updated_total(_total)?\",job=~\"$job\"}[$__rate_interval]))", + "instant": false, + "range": true, + "refId": "A" + } + ], + "title": "Recommendation Weight Updates", + "type": "timeseries" + } + ], + "preload": false, + "refresh": "30s", + "schemaVersion": 42, + "tags": [ + "movienight", + "business" + ], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": {{ .Values.observability.grafana.datasource.name | quote }}, + "value": {{ .Values.observability.grafana.datasource.uid | quote }} + }, + "hide": 0, + "includeAll": false, + "label": "Datasource", + "multi": false, + "name": "datasource", + "options": [], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "current": { + "selected": false, + "text": {{ .Values.observability.vmagent.backendJobName | quote }}, + "value": {{ .Values.observability.vmagent.backendJobName | quote }} + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "definition": "label_values(up, job)", + "hide": 0, + "includeAll": false, + "label": "Job", + "multi": false, + "name": "job", + "options": [], + "query": { + "query": "label_values(up, job)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "/movienight-backend/", + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "MovieNight Business", + "uid": "movienight-business", + "version": 1, + "weekStart": "" + } +{{- end }} diff --git a/deploy/helm/movienight/templates/observability/grafana-dashboard-red.yaml b/deploy/helm/movienight/templates/observability/grafana-dashboard-red.yaml new file mode 100644 index 0000000..8ba66fc --- /dev/null +++ b/deploy/helm/movienight/templates/observability/grafana-dashboard-red.yaml @@ -0,0 +1,828 @@ +{{- if and .Values.observability.enabled .Values.observability.grafana.dashboards.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "movienight.fullname" . }}-grafana-red-dashboard + labels: + {{- include "movienight.componentLabels" (dict "root" . "component" "grafana-dashboard") | nindent 4 }} + {{- with .Values.observability.grafana.dashboards.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or .Values.global.annotations .Values.observability.grafana.dashboards.annotations }} + annotations: + {{- with .Values.global.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.observability.grafana.dashboards.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +data: + movienight-red.json: | + { + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "grafana", + "uid": "-- Grafana --" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "target": { + "limit": 100, + "matchAny": false, + "tags": [], + "type": "dashboard" + }, + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "graphTooltip": 0, + "id": null, + "links": [], + "panels": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "red", + "value": null + }, + { + "color": "green", + "value": 1 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 0, + "y": 0 + }, + "id": 1, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.3.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "avg(up{job=~\"$job\"})", + "instant": false, + "legendFormat": "up", + "range": true, + "refId": "A" + } + ], + "title": "Availability", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "reqps" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 6, + "y": 0 + }, + "id": 2, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.3.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate(http_server_requests_seconds_count{job=~\"$job\",uri!~\"/actuator.*\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "requests", + "range": true, + "refId": "A" + } + ], + "title": "Request Rate", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "orange", + "value": 0.01 + }, + { + "color": "red", + "value": 0.05 + } + ] + }, + "unit": "percentunit" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 12, + "y": 0 + }, + "id": 3, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.3.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate(http_server_requests_seconds_count{job=~\"$job\",status=~\"5..\",uri!~\"/actuator.*\"}[$__rate_interval])) / clamp_min(sum(rate(http_server_requests_seconds_count{job=~\"$job\",uri!~\"/actuator.*\"}[$__rate_interval])), 0.001)", + "instant": false, + "legendFormat": "5xx ratio", + "range": true, + "refId": "A" + } + ], + "title": "Error Ratio", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "orange", + "value": 0.5 + }, + { + "color": "red", + "value": 1 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 4, + "w": 6, + "x": 18, + "y": 0 + }, + "id": 4, + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "auto", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "12.3.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate(http_server_requests_seconds_sum{job=~\"$job\",uri!~\"/actuator.*\"}[$__rate_interval])) / clamp_min(sum(rate(http_server_requests_seconds_count{job=~\"$job\",uri!~\"/actuator.*\"}[$__rate_interval])), 0.001)", + "instant": false, + "legendFormat": "mean", + "range": true, + "refId": "A" + } + ], + "title": "Mean Duration", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "reqps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 4 + }, + "id": 5, + "options": { + "legend": { + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum by (method, uri, status) (rate(http_server_requests_seconds_count{job=~\"$job\",uri!~\"/actuator.*\"}[$__rate_interval]))", + "instant": false, + "range": true, + "refId": "A" + } + ], + "title": "Request Rate by Route", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 4 + }, + "id": 6, + "options": { + "legend": { + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "histogram_quantile(0.95, sum by (le, uri) (rate(http_server_requests_seconds_bucket{job=~\"$job\",uri!~\"/actuator.*\"}[$__rate_interval])))", + "instant": false, + "legendFormat": "p95", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum by (uri) (rate(http_server_requests_seconds_sum{job=~\"$job\",uri!~\"/actuator.*\"}[$__rate_interval])) / clamp_min(sum by (uri) (rate(http_server_requests_seconds_count{job=~\"$job\",uri!~\"/actuator.*\"}[$__rate_interval])), 0.001)", + "instant": false, + "legendFormat": "mean", + "range": true, + "refId": "B" + } + ], + "title": "Duration by Route", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "reqps" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 0, + "y": 12 + }, + "id": 7, + "options": { + "legend": { + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate(http_server_requests_seconds_count{job=~\"$job\",status=~\"2..\",uri!~\"/actuator.*\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "2xx", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate(http_server_requests_seconds_count{job=~\"$job\",status=~\"4..\",uri!~\"/actuator.*\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "4xx", + "range": true, + "refId": "B" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(rate(http_server_requests_seconds_count{job=~\"$job\",status=~\"5..\",uri!~\"/actuator.*\"}[$__rate_interval]))", + "instant": false, + "legendFormat": "5xx", + "range": true, + "refId": "C" + } + ], + "title": "Requests by Status Class", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "short" + }, + "overrides": [] + }, + "gridPos": { + "h": 8, + "w": 12, + "x": 12, + "y": 12 + }, + "id": 8, + "options": { + "legend": { + "calcs": [ + "lastNotNull" + ], + "displayMode": "table", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "12.3.0", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(process_cpu_usage{job=~\"$job\"})", + "instant": false, + "legendFormat": "process CPU", + "range": true, + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "editorMode": "code", + "expr": "sum(jvm_memory_used_bytes{job=~\"$job\",area=\"heap\"})", + "instant": false, + "legendFormat": "heap used", + "range": true, + "refId": "B" + } + ], + "title": "Runtime Signals", + "type": "timeseries" + } + ], + "preload": false, + "refresh": "30s", + "schemaVersion": 42, + "tags": [ + "movienight", + "red" + ], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": {{ .Values.observability.grafana.datasource.name | quote }}, + "value": {{ .Values.observability.grafana.datasource.uid | quote }} + }, + "hide": 0, + "includeAll": false, + "label": "Datasource", + "multi": false, + "name": "datasource", + "options": [], + "query": "prometheus", + "refresh": 1, + "regex": "", + "type": "datasource" + }, + { + "current": { + "selected": false, + "text": {{ .Values.observability.vmagent.backendJobName | quote }}, + "value": {{ .Values.observability.vmagent.backendJobName | quote }} + }, + "datasource": { + "type": "prometheus", + "uid": "${datasource}" + }, + "definition": "label_values(http_server_requests_seconds_count, job)", + "hide": 0, + "includeAll": false, + "label": "Job", + "multi": false, + "name": "job", + "options": [], + "query": { + "query": "label_values(http_server_requests_seconds_count, job)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "sort": 1, + "type": "query" + } + ] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": {}, + "timezone": "browser", + "title": "MovieNight RED", + "uid": "movienight-red", + "version": 1, + "weekStart": "" + } +{{- end }} diff --git a/deploy/helm/movienight/templates/observability/grafana-datasource.yaml b/deploy/helm/movienight/templates/observability/grafana-datasource.yaml new file mode 100644 index 0000000..2ebc49c --- /dev/null +++ b/deploy/helm/movienight/templates/observability/grafana-datasource.yaml @@ -0,0 +1,39 @@ +{{- if and .Values.observability.enabled .Values.observability.grafana.datasource.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "movienight.fullname" . }}-grafana-datasource + labels: + {{- include "movienight.componentLabels" (dict "root" . "component" "grafana-datasource") | nindent 4 }} + {{- with .Values.observability.grafana.datasource.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or .Values.global.annotations .Values.observability.grafana.datasource.annotations }} + annotations: + {{- with .Values.global.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.observability.grafana.datasource.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- end }} +data: + victoriametrics.yaml: | + apiVersion: 1 + prune: true + + datasources: + - name: {{ .Values.observability.grafana.datasource.name | quote }} + type: prometheus + access: proxy + orgId: 1 + uid: {{ .Values.observability.grafana.datasource.uid | quote }} + url: {{ include "movienight.victoriaMetricsURL" . | quote }} + basicAuth: false + isDefault: {{ .Values.observability.grafana.datasource.isDefault }} + editable: false + jsonData: + httpMethod: POST + queryTimeout: 10s + timeInterval: {{ .Values.observability.vmagent.scrapeInterval | quote }} +{{- end }} diff --git a/deploy/helm/movienight/templates/observability/victoriametrics.yaml b/deploy/helm/movienight/templates/observability/victoriametrics.yaml new file mode 100644 index 0000000..e829ec3 --- /dev/null +++ b/deploy/helm/movienight/templates/observability/victoriametrics.yaml @@ -0,0 +1,142 @@ +{{- if and .Values.observability.enabled .Values.observability.victoriaMetrics.enabled }} +{{- if .Values.observability.victoriaMetrics.persistence.enabled }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "movienight.victoriaMetricsName" . }} + labels: + {{- include "movienight.componentLabels" (dict "root" . "component" "victoriametrics") | nindent 4 }} + {{- with .Values.global.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.observability.victoriaMetrics.persistence.size }} + {{- with .Values.observability.victoriaMetrics.persistence.storageClass }} + storageClassName: {{ . | quote }} + {{- end }} +--- +{{- end }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "movienight.victoriaMetricsName" . }} + labels: + {{- include "movienight.componentLabels" (dict "root" . "component" "victoriametrics") | nindent 4 }} + {{- with .Values.global.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + {{- include "movienight.componentSelectorLabels" (dict "root" . "component" "victoriametrics") | nindent 6 }} + template: + metadata: + labels: + {{- include "movienight.componentSelectorLabels" (dict "root" . "component" "victoriametrics") | nindent 8 }} + {{- with .Values.observability.victoriaMetrics.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.observability.victoriaMetrics.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ include "movienight.serviceAccountName" . }} + {{- with .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.observability.victoriaMetrics.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: victoriametrics + image: "{{ .Values.observability.victoriaMetrics.image.repository }}:{{ .Values.observability.victoriaMetrics.image.tag }}" + imagePullPolicy: {{ .Values.observability.victoriaMetrics.image.pullPolicy }} + args: + - -storageDataPath=/var/lib/victoriametrics + - -retentionPeriod={{ .Values.observability.victoriaMetrics.retentionPeriod }} + - -httpListenAddr=:{{ .Values.observability.victoriaMetrics.service.port }} + {{- with .Values.observability.victoriaMetrics.extraArgs }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.observability.victoriaMetrics.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http + containerPort: {{ .Values.observability.victoriaMetrics.service.port }} + protocol: TCP + readinessProbe: + httpGet: + path: /-/ready + port: http + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 5 + livenessProbe: + httpGet: + path: /-/healthy + port: http + initialDelaySeconds: 10 + periodSeconds: 30 + timeoutSeconds: 5 + {{- with .Values.observability.victoriaMetrics.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: data + mountPath: /var/lib/victoriametrics + volumes: + - name: data + {{- if .Values.observability.victoriaMetrics.persistence.enabled }} + persistentVolumeClaim: + claimName: {{ include "movienight.victoriaMetricsName" . }} + {{- else }} + emptyDir: {} + {{- end }} + {{- with .Values.observability.victoriaMetrics.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.observability.victoriaMetrics.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.observability.victoriaMetrics.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "movienight.victoriaMetricsName" . }} + labels: + {{- include "movienight.componentLabels" (dict "root" . "component" "victoriametrics") | nindent 4 }} + {{- with .Values.global.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.observability.victoriaMetrics.service.type }} + ports: + - name: http + port: {{ .Values.observability.victoriaMetrics.service.port }} + targetPort: http + protocol: TCP + selector: + {{- include "movienight.componentSelectorLabels" (dict "root" . "component" "victoriametrics") | nindent 4 }} +{{- end }} diff --git a/deploy/helm/movienight/templates/observability/vmagent.yaml b/deploy/helm/movienight/templates/observability/vmagent.yaml new file mode 100644 index 0000000..fdce0e4 --- /dev/null +++ b/deploy/helm/movienight/templates/observability/vmagent.yaml @@ -0,0 +1,169 @@ +{{- if and .Values.observability.enabled .Values.observability.vmagent.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "movienight.vmagentName" . }} + labels: + {{- include "movienight.componentLabels" (dict "root" . "component" "vmagent") | nindent 4 }} + {{- with .Values.global.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +data: + scrape.yaml: | + global: + scrape_interval: {{ .Values.observability.vmagent.scrapeInterval }} + scrape_timeout: {{ .Values.observability.vmagent.scrapeTimeout }} + + scrape_configs: + {{- if .Values.backend.enabled }} + - job_name: {{ .Values.observability.vmagent.backendJobName | quote }} + metrics_path: /actuator/prometheus + static_configs: + - targets: + - {{ include "movienight.backendMetricsTarget" . | quote }} + labels: + app: {{ include "movienight.name" . | quote }} + release: {{ .Release.Name | quote }} + namespace: {{ .Release.Namespace | quote }} + {{- end }} + - job_name: {{ printf "%s-vmagent" (include "movienight.name" .) | quote }} + static_configs: + - targets: + - {{ printf "%s:%v" (include "movienight.vmagentName" .) .Values.observability.vmagent.service.port | quote }} + labels: + app: {{ include "movienight.name" . | quote }} + release: {{ .Release.Name | quote }} + namespace: {{ .Release.Namespace | quote }} + {{- if .Values.observability.victoriaMetrics.enabled }} + - job_name: {{ printf "%s-victoriametrics" (include "movienight.name" .) | quote }} + static_configs: + - targets: + - {{ printf "%s:%v" (include "movienight.victoriaMetricsName" .) .Values.observability.victoriaMetrics.service.port | quote }} + labels: + app: {{ include "movienight.name" . | quote }} + release: {{ .Release.Name | quote }} + namespace: {{ .Release.Namespace | quote }} + {{- end }} + {{- with .Values.observability.vmagent.extraScrapeConfigs }} + {{- toYaml . | nindent 6 }} + {{- end }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "movienight.vmagentName" . }} + labels: + {{- include "movienight.componentLabels" (dict "root" . "component" "vmagent") | nindent 4 }} + {{- with .Values.global.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: 1 + selector: + matchLabels: + {{- include "movienight.componentSelectorLabels" (dict "root" . "component" "vmagent") | nindent 6 }} + template: + metadata: + labels: + {{- include "movienight.componentSelectorLabels" (dict "root" . "component" "vmagent") | nindent 8 }} + {{- with .Values.observability.vmagent.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.observability.vmagent.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ include "movienight.serviceAccountName" . }} + {{- with .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.observability.vmagent.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: vmagent + image: "{{ .Values.observability.vmagent.image.repository }}:{{ .Values.observability.vmagent.image.tag }}" + imagePullPolicy: {{ .Values.observability.vmagent.image.pullPolicy }} + args: + - -promscrape.config=/etc/vmagent/scrape.yaml + - -remoteWrite.url={{ include "movienight.vmagentRemoteWriteURL" . }} + - -httpListenAddr=:{{ .Values.observability.vmagent.service.port }} + {{- with .Values.observability.vmagent.extraArgs }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.observability.vmagent.securityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http + containerPort: {{ .Values.observability.vmagent.service.port }} + protocol: TCP + readinessProbe: + httpGet: + path: /-/ready + port: http + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 5 + livenessProbe: + httpGet: + path: /-/healthy + port: http + initialDelaySeconds: 10 + periodSeconds: 30 + timeoutSeconds: 5 + {{- with .Values.observability.vmagent.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: config + mountPath: /etc/vmagent + readOnly: true + - name: tmp + mountPath: /tmp + volumes: + - name: config + configMap: + name: {{ include "movienight.vmagentName" . }} + - name: tmp + emptyDir: {} + {{- with .Values.observability.vmagent.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.observability.vmagent.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.observability.vmagent.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "movienight.vmagentName" . }} + labels: + {{- include "movienight.componentLabels" (dict "root" . "component" "vmagent") | nindent 4 }} + {{- with .Values.global.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.observability.vmagent.service.type }} + ports: + - name: http + port: {{ .Values.observability.vmagent.service.port }} + targetPort: http + protocol: TCP + selector: + {{- include "movienight.componentSelectorLabels" (dict "root" . "component" "vmagent") | nindent 4 }} +{{- end }} diff --git a/deploy/helm/movienight/values.schema.json b/deploy/helm/movienight/values.schema.json index 395fdcc..61677a9 100644 --- a/deploy/helm/movienight/values.schema.json +++ b/deploy/helm/movienight/values.schema.json @@ -180,6 +180,18 @@ }, "additionalProperties": true }, + "management": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "port": { + "type": "integer" + } + }, + "additionalProperties": true + }, "env": { "type": "array", "items": { @@ -241,6 +253,31 @@ "routes": { "type": "object", "additionalProperties": true + }, + "observability": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "metrics": { + "type": "object", + "additionalProperties": true + }, + "victoriaMetrics": { + "type": "object", + "additionalProperties": true + }, + "vmagent": { + "type": "object", + "additionalProperties": true + }, + "grafana": { + "type": "object", + "additionalProperties": true + } + }, + "additionalProperties": true } } } diff --git a/deploy/helm/movienight/values.yaml b/deploy/helm/movienight/values.yaml index b787c63..60e1b33 100644 --- a/deploy/helm/movienight/values.yaml +++ b/deploy/helm/movienight/values.yaml @@ -48,6 +48,9 @@ backend: service: type: ClusterIP port: 8080 + management: + enabled: true + port: 8081 env: - name: SERVER_PORT value: "8080" @@ -73,7 +76,7 @@ backend: livenessProbe: httpGet: path: /actuator/health/liveness - port: http + port: management initialDelaySeconds: 20 periodSeconds: 10 timeoutSeconds: 5 @@ -81,7 +84,7 @@ backend: readinessProbe: httpGet: path: /actuator/health/readiness - port: http + port: management initialDelaySeconds: 10 periodSeconds: 10 timeoutSeconds: 5 @@ -89,7 +92,7 @@ backend: startupProbe: httpGet: path: /actuator/health - port: http + port: management initialDelaySeconds: 5 periodSeconds: 5 timeoutSeconds: 5 @@ -116,3 +119,71 @@ routes: backend: enabled: true pathPrefix: / + +observability: + enabled: false + metrics: + applicationTag: movienight + httpServerRequestsHistogram: true + victoriaMetrics: + enabled: true + image: + repository: docker.io/victoriametrics/victoria-metrics + tag: v1.134.0 + pullPolicy: IfNotPresent + service: + type: ClusterIP + port: 8428 + retentionPeriod: 30d + extraArgs: [] + persistence: + enabled: true + size: 10Gi + storageClass: "" + podAnnotations: {} + podLabels: {} + resources: {} + securityContext: {} + podSecurityContext: {} + nodeSelector: {} + tolerations: [] + affinity: {} + vmagent: + enabled: true + image: + repository: docker.io/victoriametrics/vmagent + tag: v1.135.0 + pullPolicy: IfNotPresent + service: + type: ClusterIP + port: 8429 + scrapeInterval: 5s + scrapeTimeout: 5s + remoteWriteUrl: "" + backendJobName: movienight-backend + extraArgs: [] + extraScrapeConfigs: [] + podAnnotations: {} + podLabels: {} + resources: {} + securityContext: {} + podSecurityContext: {} + nodeSelector: {} + tolerations: [] + affinity: {} + grafana: + datasource: + enabled: true + name: VictoriaMetrics + uid: victoriametrics + labels: + grafana_datasource: "1" + annotations: {} + url: "" + isDefault: true + dashboards: + enabled: true + labels: + grafana_dashboard: "1" + annotations: + grafana_folder: MovieNight