diff --git a/.vitepress/en.ts b/.vitepress/en.ts
index 664469a8..d2140ebf 100644
--- a/.vitepress/en.ts
+++ b/.vitepress/en.ts
@@ -520,6 +520,7 @@ function sidebarSelfHosted(): DefaultTheme.SidebarItem[] {
{ text: 'Quick Start', link: 'kubernetes/deploy' },
{ text: 'Custom Configuration', link: 'kubernetes/configuration' },
{ text: 'Update & Rollback', link: 'kubernetes/upgrade' },
+ { text: 'Monitor & Logging', link: 'kubernetes/monitor-logging' },
{ text: 'Data Migration', link: 'kubernetes/data-migration' },
{ text: 'FAQ', link: 'kubernetes/faq' },
]
diff --git a/.vitepress/zh.ts b/.vitepress/zh.ts
index 2c5b7f29..794804c4 100644
--- a/.vitepress/zh.ts
+++ b/.vitepress/zh.ts
@@ -577,6 +577,7 @@ function sidebarSelfHosted(): DefaultTheme.SidebarItem[] {
{ text: '快速开始', link: 'kubernetes/deploy' },
{ text: '自定义配置', link: 'kubernetes/configuration' },
{ text: '更新与回滚', link: 'kubernetes/upgrade' },
+ { text: '监控与日志', link: 'kubernetes/monitor-logging' },
{ text: '数据迁移', link: 'kubernetes/data-migration' },
{ text: '常见问题', link: 'kubernetes/faq' },
]
diff --git a/en/self_host/kubernetes/data-migration.md b/en/self_host/kubernetes/data-migration.md
index ced4113b..827108b3 100644
--- a/en/self_host/kubernetes/data-migration.md
+++ b/en/self_host/kubernetes/data-migration.md
@@ -339,7 +339,6 @@ spec:
:::
----
::: details export-clickhouse
@@ -476,7 +475,6 @@ spec:
:::
----
::: details export-redis
@@ -613,7 +611,6 @@ spec:
:::
----
::: details export-vector
@@ -765,7 +762,6 @@ spec:
:::
----
```bash
# Execute all export Jobs in parallel
@@ -1009,7 +1005,6 @@ spec:
:::
----
::: details import-clickhouse
@@ -1140,7 +1135,6 @@ spec:
:::
----
::: details import-redis
@@ -1271,7 +1265,6 @@ spec:
:::
----
::: details import-vector
@@ -1414,7 +1407,6 @@ spec:
:::
----
```bash
# Execute all import Jobs in parallel
diff --git a/en/self_host/kubernetes/deploy.md b/en/self_host/kubernetes/deploy.md
index 0d0723c4..34a27620 100644
--- a/en/self_host/kubernetes/deploy.md
+++ b/en/self_host/kubernetes/deploy.md
@@ -9,13 +9,11 @@ If you want to use [Kubernetes](https://kubernetes.io/) for self-hosted deployme

----
[[toc]]
----
**Resources and Concepts:**
@@ -413,7 +411,6 @@ helm install swanlab-self-hosted ./self-hosted/ \
```
- After confirming there are no errors, remove the `--dry-run` option to execute the installation
----
By installing `swanlab/self-hosted`, you can install the SwanLab self-hosted application on k8s. The installation result will print similar information in the terminal:
@@ -448,7 +445,6 @@ Get the application URL by running these commands:
As shown above, the `swanlab-self-hosted` self-hosted service cannot be directly accessed via external network by default. You can access this service locally using the `port-forward` functionality.
If you wish to **enable external access (via IP or domain name)**, please refer to [Configuring Application Access Entrypoint](/self_host/kubernetes/configuration.md#configuring-application-access-entrypoint).
----
Here is an example of accessing it locally; open a terminal and execute:
diff --git a/en/self_host/kubernetes/monitor-logging.md b/en/self_host/kubernetes/monitor-logging.md
new file mode 100644
index 00000000..0303c9e1
--- /dev/null
+++ b/en/self_host/kubernetes/monitor-logging.md
@@ -0,0 +1,721 @@
+# Monitor & Logging Configuration Guide
+
+> This guide describes how to configure `Prometheus + Grafana` monitoring for SwanLab backend services.
+
+## Architecture Overview
+
+SwanLab self-hosted deployment uses a microservices architecture. The monitoring pipeline works as follows:
+
+1. **Prometheus** periodically scrapes the `/metrics` endpoints exposed by each SwanLab service.
+2. **Grafana** reads data from Prometheus and renders SwanLab monitoring dashboards and alert panels.
+3. **[Optional] Alertmanager** or your existing alerting system sends notifications when Prometheus alert rules trigger.
+
+## Flow Diagram
+
+
+
+## Prerequisites
+
+- SwanLab self-hosted service has been installed via Helm (see [Kubernetes Deployment Guide](./deploy.md))
+- The default `release_name` is `swanlab-self-hosted`, installed in namespace `` (replace with your actual namespace)
+- You have the necessary permissions to access Kubernetes resources
+
+The following SwanLab backend services currently expose Prometheus metrics:
+
+| Service | Description | Port | Path |
+|---------|-------------|------|------|
+| SwanLab-Server | Core backend service | 3000 | /metrics |
+| SwanLab-House | Experiment metrics OLAP service | 3000 | /api/house/metrics |
+
+Before configuring Prometheus scrape jobs, verify that each service's Prometheus Metrics endpoint is working.
+
+- **Verify SwanLab-Server**
+
+```bash
+kubectl exec -n -c server "$(
+ kubectl get pod -n \
+ -l app.kubernetes.io/instance=swanlab-self-hosted,app.kubernetes.io/service=server \
+ -o jsonpath='{.items[0].metadata.name}'
+)" -- wget -qO- http://127.0.0.1:3000/metrics
+```
+
+- **Verify SwanLab-House**
+
+```bash
+kubectl exec -n -c house "$(
+ kubectl get pod -n \
+ -l app.kubernetes.io/instance=swanlab-self-hosted,app.kubernetes.io/service=house \
+ -o jsonpath='{.items[0].metadata.name}'
+)" -- wget -qO- http://127.0.0.1:3000/api/house/metrics
+```
+
+Notes:
+- `app.kubernetes.io/instance=` uses the default release name `swanlab-self-hosted` — replace with your actual deployment value
+- `` should be replaced with the namespace where SwanLab is deployed
+
+## Integrating Monitoring Services
+
+Choose the appropriate configuration method based on your environment:
+
+- **Scenario 1: No Prometheus in the cluster** — Deploy an independent Prometheus + Grafana stack in the SwanLab namespace, and configure observability metrics
+- **Scenario 2: Prometheus already exists in the cluster** — Integrate SwanLab metrics into your existing Prometheus monitoring system
+
+### 1. Scenario 1: No Prometheus in the Cluster
+
+This scenario applies when your cluster does not have an existing Prometheus monitoring setup. You will deploy a complete `Prometheus + Grafana` monitoring stack in the SwanLab namespace.
+
+If your cluster already has a mature Prometheus observability service, you can skip this step and go to [Configure Prometheus Scrape Jobs](#_2-scenario-2-prometheus-already-exists-in-the-cluster).
+
+#### 1.1 Create swanlab-monitor PVC
+
+Create persistent storage for Prometheus and Grafana. This example uses 20Gi for each — adjust based on your cluster's actual usage.
+
+::: details swanlab-monitor-pvc.yaml Example
+```yaml
+# ============================================================
+# Prometheus + Grafana PVC Configuration
+# ============================================================
+# Pre-create persistent storage for Prometheus and Grafana
+# Must be created and Bound before installing kube-prometheus-stack
+#
+# Usage:
+# kubectl apply -f swanlab-monitor-pvc.yaml
+#
+# Verify status:
+# kubectl get pvc -n
+#
+# Notes:
+# - Prometheus PVC name must exactly match the Operator (StatefulSet) auto-generated name:
+# prometheus--db-prometheus--
+# where CR-name = -kube-prome-prometheus (release name + chart name, truncated to 26 chars)
+# For release swanlab-monitor:
+# prometheus-swanlab-monitor-kube-prome-prometheus-db-prometheus-swanlab-monitor-kube-prome-prometheus-0
+# If the name doesn't match, the Operator will create a new PVC and the pre-created one will be unused
+# After installation, verify with: kubectl get pvc -n
+# - Grafana PVC name is referenced via existingClaim in values
+# ============================================================
+
+# Prometheus data storage
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ # PVC name must exactly match the Operator auto-generated name (see header comments)
+ name: prometheus-swanlab-monitor-kube-prome-prometheus-db-prometheus-swanlab-monitor-kube-prome-prometheus-0
+ namespace: # TODO: replace with actual namespace
+spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 20Gi # TODO: scale as needed
+ storageClassName: # TODO: replace with actual storage class
+ volumeMode: Filesystem
+---
+# Grafana data storage
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ # Grafana PVC name is referenced via existingClaim in values
+ name: swanlab-monitor-grafana-pvc
+ namespace: # TODO: replace with actual namespace
+spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 20Gi # TODO: scale as needed
+ storageClassName: # TODO: replace with actual storage class
+ volumeMode: Filesystem
+```
+:::
+
+Apply the PVC configuration:
+
+```bash
+kubectl apply -f swanlab-monitor-pvc.yaml
+
+# Verify PVC status (ensure all are Bound)
+kubectl get pvc -n
+```
+
+#### 1.2 Configure swanlab-monitor-value
+
+Create a `swanlab-monitor-value.yaml` file with Prometheus scrape job configuration and PVC references:
+
+::: details swanlab-monitor-value.yaml Example
+```yaml
+# ============================================================
+# kube-prometheus-stack values — using Alibaba Cloud ACR images
+# ============================================================
+# For deploying Prometheus + Grafana independently in the SwanLab namespace
+# Auto-discovers SwanLab services via Pod Annotations
+#
+# Usage:
+# helm install swanlab-monitor prometheus-community/kube-prometheus-stack \
+# -n -f swanlab-monitor-value.yaml
+#
+# Prerequisites:
+# 1. PVC created (see swanlab-monitor-pvc.yaml)
+# 2. Helm repo added:
+# helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
+# ============================================================
+
+# ---------- Grafana ----------
+# Grafana visualizes Prometheus data and provides SwanLab monitoring dashboards
+grafana:
+ persistence:
+ enabled: true
+ # Use pre-created PVC (must be created and Bound before installation)
+ existingClaim: swanlab-monitor-grafana-pvc
+ # Grafana admin default password (default username is admin)
+ # ⚠️ Security note: This is an example default password. Change it immediately after installation,
+ # or use admin.existingSecret to reference a Kubernetes Secret for credential management
+ adminPassword: "swanlab-monitor@default"
+
+ # Grafana image (Alibaba Cloud ACR)
+ image:
+ registry: repo.swanlab.cn
+ repository: public/grafana
+ tag: "13.0.1-security-01"
+
+ # initChownData container image (for initializing data directory permissions)
+ initChownData:
+ image:
+ registry: repo.swanlab.cn
+ repository: public/busybox
+ tag: "1.38.0"
+
+ # sidecar container image (for auto-loading dashboards and datasources from ConfigMap)
+ sidecar:
+ image:
+ registry: repo.swanlab.cn
+ repository: public/k8s-sidecar
+ tag: "2.7.3"
+
+ replicas: 1
+
+# ---------- Prometheus ----------
+# Prometheus collects and stores SwanLab metrics data
+prometheus:
+ prometheusSpec:
+ # Allow selecting all ServiceMonitors (not limited to Helm-managed ones)
+ serviceMonitorSelectorNilUsesHelmValues: false
+
+ # Persistent storage configuration
+ # Operator generates PVC for StatefulSet via volumeClaimTemplate, naming format:
+ # prometheus--db-prometheus-- (CR-name = -kube-prome-prometheus)
+ # For this release (swanlab-monitor):
+ # prometheus-swanlab-monitor-kube-prome-prometheus-db-prometheus-swanlab-monitor-kube-prome-prometheus-0
+ # This PVC has been pre-created with the correct name in swanlab-monitor-pvc.yaml
+ storageSpec:
+ volumeClaimTemplate:
+ spec:
+ storageClassName: # TODO: replace with actual storage class, must match swanlab-monitor-pvc.yaml
+ accessModes: ["ReadWriteOnce"]
+ resources:
+ requests:
+ storage: 20Gi # must match the pre-created PVC capacity in swanlab-monitor-pvc.yaml
+
+ replicas: 1
+
+ # Prometheus image (Alibaba Cloud ACR)
+ image:
+ registry: repo.swanlab.cn
+ repository: public/prometheus
+ tag: "v3.12.0-distroless"
+
+ # Custom scrape config — SwanLab dedicated scrape job
+ # Auto-discovers SwanLab services via Pod Annotations
+ additionalScrapeConfigs:
+ - job_name: "swanlab"
+ kubernetes_sd_configs:
+ - role: pod
+ relabel_configs:
+ # Only scrape Pods annotated with prometheus.io/scrape: "swanlab"
+ - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
+ action: keep
+ regex: swanlab
+ # Read metrics_path from annotation
+ - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
+ action: replace
+ target_label: __metrics_path__
+ regex: (.+)
+ # Read port from annotation
+ - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
+ action: replace
+ target_label: __address__
+ regex: ([^:]+)(?::\d+)?;(\d+)
+ replacement: $1:$2
+ # Retain common Kubernetes labels for Grafana queries and grouping
+ - source_labels: [__meta_kubernetes_namespace]
+ target_label: namespace
+ - source_labels: [__meta_kubernetes_pod_name]
+ target_label: pod
+ - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_instance]
+ target_label: release
+ - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_service]
+ target_label: service
+
+# ---------- Alertmanager ----------
+# Alertmanager handles Prometheus alert rules and sends notifications
+alertmanager:
+ replicas: 1
+ alertmanagerSpec:
+ image:
+ registry: repo.swanlab.cn
+ repository: public/alertmanager
+ tag: "v0.32.2"
+
+# ---------- Prometheus Operator ----------
+# Prometheus Operator manages Prometheus and Alertmanager instances
+prometheusOperator:
+ replicas: 1
+ image:
+ registry: repo.swanlab.cn
+ repository: public/prometheus-operator
+ tag: "v0.91.0"
+ # admissionWebhook validates PrometheusRule and ServiceMonitor configurations
+ admissionWebhook:
+ image:
+ registry: repo.swanlab.cn
+ repository: public/kube-webhook-certgen
+ tag: "1.8.3"
+ patch:
+ image:
+ registry: repo.swanlab.cn
+ repository: public/kube-webhook-certgen
+ tag: "1.8.3"
+ # prometheusConfigReloader auto-reloads Prometheus config on ConfigMap changes
+ prometheusConfigReloader:
+ image:
+ registry: repo.swanlab.cn
+ repository: public/prometheus-config-reloader
+ tag: "v0.91.0"
+
+# ---------- Kube State Metrics ----------
+# kube-state-metrics exports cluster resource metrics from the Kubernetes API
+kube-state-metrics:
+ replicas: 1
+ image:
+ registry: repo.swanlab.cn
+ repository: public/kube-state-metrics
+ tag: "v2.19.0"
+
+# ---------- Node Exporter (DaemonSet) ----------
+# node-exporter collects node-level hardware and OS metrics
+# Note: chart defaults distroless: true, which auto-appends -distroless suffix
+# So tag should be "v1.11.1" without -distroless
+prometheus-node-exporter:
+ # Disable hostNetwork to avoid port conflicts (default is true)
+ hostNetwork: false
+ hostPort:
+ enabled: false
+ # Tolerate all taints to ensure DaemonSet runs on all nodes (including control plane)
+ tolerations:
+ - effect: NoSchedule
+ operator: Exists
+ - effect: NoExecute
+ operator: Exists
+ - effect: PreferNoSchedule
+ operator: Exists
+ image:
+ registry: repo.swanlab.cn
+ repository: public/node-exporter
+ tag: "v1.11.1"
+```
+:::
+
+:::warning ⚠️ Security Note
+The Grafana admin password `swanlab-monitor@default` is an example default value. Change the admin password immediately after installation. For production, use `grafana.admin.existingSecret` to reference a Kubernetes Secret for credential management, avoiding plaintext passwords in values files.
+:::
+
+#### 1.3 Install Prometheus + Grafana
+
+Similar to the [Upgrade & Rollback](./upgrade.md) section, choose the installation method based on whether your cluster can access `github.com`:
+
+- **Cluster can access github**
+
+First add the prometheus-community `kube-prometheus-stack` chart repo:
+
+```bash
+# Add Helm repo
+helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
+helm repo update
+
+# Install via Helm repo
+helm install swanlab-monitor prometheus-community/kube-prometheus-stack \
+ -n \
+ -f swanlab-monitor-value.yaml
+```
+
+- **Cluster cannot access github**
+
+Pull the `kube-prometheus-stack` chart locally via OCI, then install:
+
+```bash
+# 1. Pull chart package locally
+helm pull oci://swanlab-registry.cn-hangzhou.cr.aliyuncs.com/chart/monitoring/kube-prometheus-stack \
+ --version 86.2.1
+# 2. Extract
+tar -zxvf kube-prometheus-stack-86.2.1.tgz
+# 3. Install using local chart
+helm install swanlab-monitor ./kube-prometheus-stack \
+ -n \
+ -f swanlab-monitor-value.yaml
+```
+
+Wait for all pods and deployments to be ready:
+
+```bash
+# deployments
+kubectl get deployments -n | grep monitor
+
+# pods
+kubectl get pods -n | grep monitor
+```
+
+### 2. Scenario 2: Prometheus Already Exists in the Cluster
+
+This scenario applies when your cluster already has a mature Prometheus monitoring setup. You only need to integrate SwanLab metrics into the existing Prometheus scrape jobs. Three integration methods are provided — choose one:
+
+| Method | Description | Prerequisites | Requires Pod Annotation Changes |
+|--------|-------------|---------------|-------------------------------|
+| [2.1 Method 1: Pod Annotation (Recommended)](#_2-1-method-1-pod-annotation-recommended) | Single job, dynamic service discovery via annotations | Requires [Step 3](#_3-configure-pod-annotations-and-update-services) to configure annotations | ✅ Yes |
+| [2.2 Method 2: Label-Based Dual Jobs](#_2-2-method-2-label-based-dual-jobs) | Two independent jobs, discovery via Pod labels | Uses default labels from SwanLab Helm Chart | ❌ No |
+| [2.3 Method 3: Prometheus Operator](#_2-3-method-3-prometheus-operator-servicemonitor-podmonitor) | Declarative integration via ServiceMonitor/PodMonitor | Cluster has Prometheus Operator deployed | ❌ No |
+
+#### 2.1 Method 1: Pod Annotation (Recommended)
+
+Add a dedicated SwanLab scrape job to your existing `prometheus.yaml` `scrape_configs`. This approach uses a single job to collect both Server and House metrics via Pod annotations — adding new services only requires adding annotations, no Prometheus config changes needed.
+
+::: details prometheus.yaml — Pod Annotation Scrape Job
+```yaml
+scrape_configs:
+ - job_name: "swanlab"
+ kubernetes_sd_configs:
+ - role: pod
+
+ relabel_configs:
+ # Only scrape Pods annotated with prometheus.io/scrape: "swanlab"
+ - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
+ action: keep
+ regex: swanlab
+
+ # Use prometheus.io/path annotation as metrics_path
+ - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
+ action: replace
+ target_label: __metrics_path__
+ regex: (.+)
+
+ # Use prometheus.io/port annotation as scrape port
+ - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
+ action: replace
+ target_label: __address__
+ regex: ([^:]+)(?::\d+)?;(\d+)
+ replacement: $1:$2
+
+ # Retain common Kubernetes labels for Grafana queries and grouping
+ - source_labels: [__meta_kubernetes_namespace]
+ target_label: namespace
+
+ - source_labels: [__meta_kubernetes_pod_name]
+ target_label: pod
+
+ - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_instance]
+ target_label: release
+
+ - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_service]
+ target_label: service
+```
+:::
+
+When using Method 1, you must also complete [Step 3: Configure Pod Annotations](#_3-configure-pod-annotations-and-update-services).
+
+#### 2.2 Method 2: Label-Based Dual Jobs
+
+Add two independent scrape jobs to your `prometheus.yaml` `scrape_configs`, one for Server and one for House. This method uses the `app.kubernetes.io/instance` and `app.kubernetes.io/service` labels auto-generated by the SwanLab Helm Chart for service discovery — **no Pod annotation changes required**, works immediately after deployment.
+
+::: details prometheus.yaml — Label-Based Dual Jobs
+```yaml
+scrape_configs:
+ - job_name: "swanlab-server"
+ kubernetes_sd_configs:
+ - role: pod
+ namespaces:
+ names:
+ - # TODO: replace with SwanLab deployment namespace
+ relabel_configs:
+ # Only scrape Pods with release= and service=server
+ - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_instance]
+ action: keep
+ regex: swanlab-self-hosted # TODO: replace with actual release name
+
+ - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_service]
+ action: keep
+ regex: server
+
+ # Force Metrics port
+ - source_labels: [__address__]
+ action: replace
+ target_label: __address__
+ regex: ([^:]+)(?::\d+)?
+ replacement: $1:3000
+
+ - target_label: __metrics_path__
+ replacement: /metrics
+
+ # Retain common Kubernetes labels
+ - source_labels: [__meta_kubernetes_namespace]
+ target_label: namespace
+
+ - source_labels: [__meta_kubernetes_pod_name]
+ target_label: pod
+
+ - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_service]
+ target_label: service
+
+ - job_name: "swanlab-house"
+ kubernetes_sd_configs:
+ - role: pod
+ namespaces:
+ names:
+ - # TODO: replace with SwanLab deployment namespace
+ relabel_configs:
+ # Only scrape Pods with release= and service=house
+ - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_instance]
+ action: keep
+ regex: swanlab-self-hosted # TODO: replace with actual release name
+
+ - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_service]
+ action: keep
+ regex: house
+
+ # Force Metrics port
+ - source_labels: [__address__]
+ action: replace
+ target_label: __address__
+ regex: ([^:]+)(?::\d+)?
+ replacement: $1:3000
+
+ # House Metrics path differs from Server
+ - target_label: __metrics_path__
+ replacement: /api/house/metrics
+
+ # Retain common Kubernetes labels
+ - source_labels: [__meta_kubernetes_namespace]
+ target_label: namespace
+
+ - source_labels: [__meta_kubernetes_pod_name]
+ target_label: pod
+
+ - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_service]
+ target_label: service
+```
+:::
+
+::: tip Differences from Method 1
+- **No Pod annotation changes needed**: Uses default `app.kubernetes.io/*` labels from SwanLab Helm Chart.
+- **Namespace-scoped**: Uses `namespaces.names` to limit SD scope, friendlier to clusters with tightened permissions.
+- **Independent Jobs**: Separate jobs for Server and House, easier to monitor and debug in Prometheus Targets panel.
+- Grafana dashboard template variable `$job` values are `swanlab-server` or `swanlab-house` (not `swanlab`).
+:::
+
+#### 2.3 Method 3: Prometheus Operator (ServiceMonitor / PodMonitor)
+
+If your cluster's Prometheus is managed by [Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator) (e.g., kube-prometheus-stack, Bitnami Helm Charts), you can integrate SwanLab declaratively via `ServiceMonitor` or `PodMonitor` resources — no manual `prometheus.yaml` editing needed.
+
+::: details ServiceMonitor Example
+```yaml
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+ name: swanlab-server
+ namespace: # TODO: replace with SwanLab deployment namespace
+ labels:
+ release: kube-prometheus-stack # TODO: match your Prometheus Operator's serviceMonitorSelector
+spec:
+ namespaceSelector:
+ matchNames:
+ -
+ selector:
+ matchLabels:
+ app.kubernetes.io/instance: swanlab-self-hosted # TODO: replace with actual release name
+ app.kubernetes.io/service: server
+ endpoints:
+ - port: http
+ path: /metrics
+ interval: 30s
+---
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+ name: swanlab-house
+ namespace: # TODO: replace with SwanLab deployment namespace
+ labels:
+ release: kube-prometheus-stack # TODO: match your Prometheus Operator's serviceMonitorSelector
+spec:
+ namespaceSelector:
+ matchNames:
+ -
+ selector:
+ matchLabels:
+ app.kubernetes.io/instance: swanlab-self-hosted # TODO: replace with actual release name
+ app.kubernetes.io/service: house
+ endpoints:
+ - port: http
+ path: /api/house/metrics
+ interval: 30s
+```
+:::
+
+::: warning
+- `metadata.labels.release` must match the Prometheus Operator's `serviceMonitorSelector`, otherwise the Operator will not pick up this ServiceMonitor. Check your existing Prometheus Helm values for `prometheus.prometheusSpec.serviceMonitorSelector`.
+- Scenario 1's `swanlab-monitor-value.yaml` already sets `serviceMonitorSelectorNilUsesHelmValues: false`, so adding ServiceMonitors in Scenario 1 requires no additional configuration.
+:::
+
+### 3. Configure Pod Annotations and Update Services
+
+> This step only applies to [Method 1 (Pod Annotation)](#_2-1-method-1-pod-annotation-recommended). If using [Method 2 (Label-Based)](#_2-2-method-2-label-based-dual-jobs) or [Method 3 (ServiceMonitor)](#_2-3-method-3-prometheus-operator-servicemonitor-podmonitor), skip this step and go to [Step 4](#_4-configure-ingress).
+
+In your SwanLab self-hosted `swanlab-self-hosted-value.yaml`, find `service.server.customPodAnnotations` and `service.house.customPodAnnotations`, and add the following Prometheus scrape annotations for SwanLab-Server and SwanLab-House:
+
+::: details swanlab-self-hosted-value.yaml — Pod Annotations
+```yaml
+....
+service:
+ server:
+ ....
+ customPodAnnotations:
+ prometheus.io/scrape: "swanlab" # SwanLab dedicated scrape identifier
+ prometheus.io/port: "3000" # Server Metrics port
+ prometheus.io/path: "/metrics" # Server Metrics path
+...
+ house:
+ ...
+ customPodAnnotations:
+ prometheus.io/scrape: "swanlab" # SwanLab dedicated scrape identifier
+ prometheus.io/port: "3000" # House Metrics port
+ prometheus.io/path: "/api/house/metrics" # House Metrics path
+ ...
+```
+:::
+
+:::warning
+⚠️ **Note**: `prometheus.io/port` and `prometheus.io/path` are built-in SwanLab service requirements and cannot be changed.
+:::
+
+After modifying the annotations, apply the changes using `helm upgrade` (see [Upgrade & Rollback](./upgrade.md)):
+
+```bash
+# Online update
+helm upgrade swanlab-self-hosted swanlab/self-hosted \
+ -f swanlab-self-hosted-value.yaml \
+ -n
+
+# Or update using offline chart package
+helm upgrade swanlab-self-hosted ./self-hosted \
+ -f swanlab-self-hosted-value.yaml \
+ -n
+```
+
+### 4. Configure Ingress
+
+Similarly, the `swanlab-monitor` service does not include Ingress gateway configuration. You need to configure an external access entry on your cluster's load balancer (or Ingress) for the **80 port** of the `swanlab-monitor-grafana` Service.
+
+If you can configure port forwarding, use the following command and open `localhost:3000`:
+
+```bash
+kubectl port-forward svc/swanlab-monitor-grafana 3000:80 -n
+```
+
+### 5. Import Grafana Dashboards
+
+SwanLab provides official Grafana dashboard templates for monitoring visualization in both scenarios.
+
+#### 5.1 Download Dashboard Templates
+
+- [swanlab-monitor-config-server.json](https://swanlab-docs-1301372061.cos.ap-beijing.myqcloud.com/assets/swanlab-monitor-config-server.json) — Server service monitoring dashboard
+- [swanlab-monitor-config-house.json](https://swanlab-docs-1301372061.cos.ap-beijing.myqcloud.com/assets/swanlab-monitor-config-house.json) — House service monitoring dashboard
+
+#### 5.2 Import Steps
+
+1. In Grafana, add a `prometheus` data source: click **Connections** → **Data Sources** → **Add new data source** → select **Prometheus**, and set the URL to your Prometheus endpoint.
+
+
+
+For example:
+- `swanlab-monitor-kube-prome-prometheus` is the Prometheus Service in the same namespace, exposing port `9090`
+- `tenant-shaobo` is the namespace where `swanlab-self-hosted` is deployed
+
+Set the **Prometheus server URL** to `http://swanlab-monitor-kube-prome-prometheus.tenant-shaobo:9090/`
+
+> The example above applies when Prometheus is installed in the same namespace as `swanlab-self-hosted` per [Scenario 1](#_1-scenario-1-no-prometheus-in-the-cluster). If your Prometheus is deployed in a different namespace or outside the cluster, replace the URL with your actual accessible Prometheus address.
+
+2. In Grafana, navigate to **Dashboards → New → Import**
+
+
+
+3. Paste or upload `swanlab-monitor-config-server.json` and `swanlab-monitor-config-house.json`
+
+4. Select the corresponding **dataSource**, **namespace**, **job**, and **service**.
+
+The dashboards use template variables to adapt to different Prometheus configurations. After importing, select from the **top dropdown menus**:
+
+| Variable | Description | Example Value |
+|----------|-------------|---------------|
+| `$datasource` | Prometheus data source | Select your configured data source |
+| `$namespace` | Kubernetes namespace | `swanlab` |
+| `$job` | Prometheus scrape job name | `swanlab`, `swanlab-server`, or `swanlab-house` (depends on integration method) |
+| `$service` | SwanLab service name | `server` or `house` |
+
+> **Note**: Template variables are automatically populated from Prometheus — no manual input needed.
+>
+> **Important**: The "CPU Usage" and "Memory Usage" panels in the House dashboard use kubelet/cAdvisor metrics (`container_cpu_usage_seconds_total`, `container_memory_working_set_bytes`), not from SwanLab service Metrics endpoints. Scenario 1's kube-prometheus-stack collects these by default; for Scenario 2, confirm your existing Prometheus is scraping cAdvisor metrics, otherwise these panels will show no data.
+
+
+
+Once configured correctly, you should see service health metrics:
+
+- **SwanLab-Server**:
+
+
+- **SwanLab-House**:
+
+
+## Log Collection
+
+> 🚧 The log collection configuration guide (e.g., `Loki + Promtail`, `ELK` etc.) is being written. Stay tuned.
+> In the meantime, you can view service Pod logs via `kubectl logs`, or use your cloud provider's built-in cluster Pod log service:
+>
+> ```bash
+> kubectl logs -n -c
+> ```
+
+## FAQ
+
+### Why does the Metrics endpoint return 404?
+
+The most likely cause is an incorrect request method. Make sure you are using `HTTP GET` to access the metrics endpoint. Additionally, ensure the service, port, and path are all correct.
+
+### What do the metrics returned by the Metrics endpoint represent?
+
+The Metrics endpoint follows the Prometheus format specification and typically returns information such as request QPS, request latency, and request error rate, along with internal runtime metrics for Node.js, Go, and other languages. Due to the large number of metrics, it is difficult to list all of them and their meanings. We recommend verifying the metrics endpoint as described in [Prerequisites](#prerequisites), or manually retrieving all metrics information from the Prometheus panel, and then using other tools (such as large language models) to look up the meaning of specific metrics.
+
+### Does the Metrics endpoint return CPU, memory, and other metrics?
+
+The Metrics endpoint does not collect CPU, memory, or other hardware metrics.
+
+First, for performance reasons, the SwanLab service Metrics endpoint primarily exposes application runtime status metrics and does not include system resource metrics such as CPU and memory. Collecting CPU and other resource information may increase the application burden. On the other hand, CPU and memory metric collection may require higher permissions, which does not align with SwanLab's self-hosted deployment requirements. Finally, in cloud-native environments, these resource metrics are typically collected uniformly by [cAdvisor](https://github.com/google/cadvisor), [node-exporter](https://github.com/prometheus/node_exporter), or cloud provider monitoring components. Consider deploying the corresponding components to collect CPU and other data.
+
+### Why do panels in the SwanLab monitoring dashboards show no data?
+
+If CPU, memory, or other panels show no data, as mentioned in the previous question, you should consider deploying the corresponding hardware monitoring components. If you have already deployed the components, or if panels such as request latency show no data, the recommended troubleshooting steps are:
+
+1. Check whether the corresponding metric exists in the Prometheus panel;
+2. If it exists, the Grafana dashboard metric query configuration may be incorrect and needs to be modified;
+3. If it does not exist, there is an issue with the Prometheus scrape job that needs to be investigated.
+
+### Is monitoring of PostgreSQL, ClickHouse, and other infrastructure services supported?
+
+PostgreSQL and ClickHouse have corresponding exporters (e.g., [postgres_exporter](https://github.com/prometheus-community/postgres_exporter)), but they require higher deployment permissions.
+Future updates will consider integrating infrastructure service metrics into the Grafana dashboards.
diff --git a/en/self_host/kubernetes/upgrade.md b/en/self_host/kubernetes/upgrade.md
index 8a1033b7..0967ffb1 100644
--- a/en/self_host/kubernetes/upgrade.md
+++ b/en/self_host/kubernetes/upgrade.md
@@ -4,7 +4,6 @@
[[toc]]
----
## 1. Pre-Update Preparation
diff --git a/zh/api/cli-swanlab-watch.md b/zh/api/cli-swanlab-watch.md
index 5702b4f3..c6d2229d 100644
--- a/zh/api/cli-swanlab-watch.md
+++ b/zh/api/cli-swanlab-watch.md
@@ -13,7 +13,7 @@ swanlab watch [OPTIONS]
## 介绍
-本地启动SwanLab[离线看板](/zh/guide_cloud/offline-board.md)。
+本地启动SwanLab[离线看板](../guide_cloud/offline-board.md)。
在创建SwanLab实验时(并设置mode="local"),会在本地目录下创建一个日志文件夹(默认名称为`swanlog`),使用`swanlab watch`可以本地离线打开实验看板,查看指标图表和配置。
## 使用案例
diff --git a/zh/api/py-api-legacy.md b/zh/api/py-api-legacy.md
index 09a5e65f..0f176151 100644
--- a/zh/api/py-api-legacy.md
+++ b/zh/api/py-api-legacy.md
@@ -3,7 +3,7 @@
::: warning 版本提示
此文档适用于 swanlab **< 0.8.0** 的版本。
-swanlab >= `0.8.0` 请参考新版 API 文档:[`py-api`](/zh/api/py-api.md)。
+swanlab >= `0.8.0` 请参考新版 API 文档:[`py-api`](./py-api.md)。
:::
基于 SwanLab 云端功能, 在 SDK 端提供访问 **开放 API(OpenAPI)** 的能力, 允许用户通过编程方式在本地环境中操作云端 **实验/项目/空间/指标** 资源。
diff --git a/zh/api/py-openapi.md b/zh/api/py-openapi.md
index b2b791a5..9fd1e384 100644
--- a/zh/api/py-openapi.md
+++ b/zh/api/py-openapi.md
@@ -3,7 +3,7 @@
::: danger 废弃提示
`swanlab.OpenApi` 已于 `0.8.0` 版本**废弃**,将在后续版本中**移除**。
-请迁移至新版 [`swanlab.Api`](/zh/api/py-api.md)。
+请迁移至新版 [`swanlab.Api`](./py-api.md)。
> 此 API 适用于 swanlab **< 0.8.0** 的版本。
:::
diff --git a/zh/guide_cloud/general/changelog.md b/zh/guide_cloud/general/changelog.md
index 58a1ce2a..20ce83fe 100644
--- a/zh/guide_cloud/general/changelog.md
+++ b/zh/guide_cloud/general/changelog.md
@@ -269,7 +269,7 @@ bunx skills add https://www.modelscope.cn/skills/SwanLab/swanlab-skill
- 新增折线图 **Log Scale** 功能
- 新增 **实验分组拖拽** 功能
- 新增实验卡片中**配置**与**指标**表格下载功能
-- 新增[开放接口](/zh/api/py-openapi.md),支持通过API获取SwanLab数据
+- 新增[开放接口](../../api/py-openapi.md),支持通过API获取SwanLab数据
- 大幅优化了指标传输性能,提升上千指标的传输速度
- 集成`paddlenlp`框架
@@ -277,7 +277,7 @@ bunx skills add https://www.modelscope.cn/skills/SwanLab/swanlab-skill
- 优化了个人主页的一系列交互
**生态**
-- 腾讯云云应用上架:[指引](/zh/self_host/tencentcloud-app.md)
+- 腾讯云云应用上架:[指引](../../self_host/tencentcloud-app.md)
## v0.5.6 - 2025.04.23
@@ -352,8 +352,8 @@ bunx skills add https://www.modelscope.cn/skills/SwanLab/swanlab-skill
**🚀新增功能**
- `swanlab.init`新增参数`callbacks`,支持在初始化时注册回调函数,以支持各式各样的自定义插件类
- 新增`swanlab.register_callback()`,支持在`init`外部注册回调函数,[文档](/api/py-register-callback.html)
-- `swanlab.login()`升级,新增`host`、`web_host`、`save`参数,适配了私有化部署服务的特性,同时支持不将用户登录凭证写入本地,以适应共用服务器场景。[文档](/zh/api/py-login.md)
-- `swanlab login`升级,新增`host`、`web_host`、`api-key`参数,[文档](/zh/api/cli-swanlab-login.md)
+- `swanlab.login()`升级,新增`host`、`web_host`、`save`参数,适配了私有化部署服务的特性,同时支持不将用户登录凭证写入本地,以适应共用服务器场景。[文档](../../api/py-login.md)
+- `swanlab login`升级,新增`host`、`web_host`、`api-key`参数,[文档](../../api/cli-swanlab-login.md)
- 新增支持使用`swanlab.sync_mlflow()`将MLflow项目同步到SwanLab,[文档](/guide_cloud/integration/integration-mlflow.md)
**🤔优化**
diff --git a/zh/guide_cloud/integration/integration-mmengine.md b/zh/guide_cloud/integration/integration-mmengine.md
index 4263b942..48c356ad 100644
--- a/zh/guide_cloud/integration/integration-mmengine.md
+++ b/zh/guide_cloud/integration/integration-mmengine.md
@@ -12,10 +12,10 @@ SwanLab将专为MMEngine设计的`SwanlabVisBackend`集成到MMEngine中,可
::: warning MM生态的其他集成
-- [MMPretrain](/zh/guide_cloud/integration/integration-mmpretrain.md)
-- [MMDetection](/zh/guide_cloud/integration/integration-mmdetection.md)
-- [MMSegmentation](/zh/guide_cloud/integration/integration-mmsegmentation.md)
-- [XTuner](/zh/guide_cloud/integration/integration-xtuner.md)
+- [MMPretrain](./integration-mmpretrain.md)
+- [MMDetection](./integration-mmdetection.md)
+- [MMSegmentation](./integration-mmsegmentation.md)
+- [XTuner](./integration-xtuner.md)
:::
diff --git a/zh/guide_cloud/integration/integration-pytorch-torchtune.md b/zh/guide_cloud/integration/integration-pytorch-torchtune.md
index 979e110e..f1b44c4e 100644
--- a/zh/guide_cloud/integration/integration-pytorch-torchtune.md
+++ b/zh/guide_cloud/integration/integration-pytorch-torchtune.md
@@ -30,7 +30,7 @@ metric_logger:
log_dir: ${output_dir}
```
-其中,`_component_`对应的`swanlab.integration.torchtune.SwanLabLogger`是适配于PyTorch torchtune的日志记录类。而`project`、`experiment_name`等则是创建SwanLab项目传入的参数,支持传入的参数与[swanlab.init](/zh/api/py-init.html)规则一致。
+其中,`_component_`对应的`swanlab.integration.torchtune.SwanLabLogger`是适配于PyTorch torchtune的日志记录类。而`project`、`experiment_name`等则是创建SwanLab项目传入的参数,支持传入的参数与[swanlab.init](../../api/py-init.md)规则一致。
## 2. 开始训练
diff --git a/zh/guide_cloud/integration/integration-wandb.md b/zh/guide_cloud/integration/integration-wandb.md
index dbd0e890..2c09e2cf 100644
--- a/zh/guide_cloud/integration/integration-wandb.md
+++ b/zh/guide_cloud/integration/integration-wandb.md
@@ -145,7 +145,7 @@ swanlab convert --mode 'offline' -t wandb --wb-project [WANDB_PROJECT_NAME] --wb
swanlab sync [日志文件夹路径]
```
-[swanlab sync文档](/zh/api/cli-swanlab-sync.md)
+[swanlab sync文档](../../api/cli-swanlab-sync.md)
### 2.3 方式二:代码内转换
@@ -191,7 +191,7 @@ wb_converter.run(wb_project="WANDB_PROJECT_NAME", wb_entity="WANDB_USERNAME")
swanlab sync [日志文件夹路径]
```
-[swanlab sync文档](/zh/api/cli-swanlab-sync.md)
+[swanlab sync文档](../../api/cli-swanlab-sync.md)
## 3 转换wandb日志文件
diff --git a/zh/plugin/custom-plugin.md b/zh/plugin/custom-plugin.md
index bbb6b098..6831d752 100644
--- a/zh/plugin/custom-plugin.md
+++ b/zh/plugin/custom-plugin.md
@@ -147,5 +147,5 @@ for epoch in range(2, epochs):
## 学习更多插件
-- [EmailCallback](/zh/plugin/notification-email.md):训练完成/发生错误时,发送消息到邮箱
-- [LarkCallback](/zh/plugin/notification-lark.md):训练完成/发生错误时,发送消息到飞书
+- [EmailCallback](./notification-email.md):训练完成/发生错误时,发送消息到邮箱
+- [LarkCallback](./notification-lark.md):训练完成/发生错误时,发送消息到飞书
diff --git a/zh/self_host/kubernetes/data-migration.md b/zh/self_host/kubernetes/data-migration.md
index 3d772a8d..3c79b776 100644
--- a/zh/self_host/kubernetes/data-migration.md
+++ b/zh/self_host/kubernetes/data-migration.md
@@ -339,7 +339,6 @@ spec:
:::
----
::: details export-clickhouse
@@ -476,7 +475,6 @@ spec:
:::
----
::: details export-redis
@@ -613,7 +611,6 @@ spec:
:::
----
::: details export-vector
@@ -765,7 +762,6 @@ spec:
:::
----
```bash
# 并行执行所有导出 Job
@@ -1009,7 +1005,6 @@ spec:
:::
----
::: details import-clickhouse
@@ -1140,7 +1135,6 @@ spec:
:::
----
::: details import-redis
@@ -1271,7 +1265,6 @@ spec:
:::
----
::: details import-vector
@@ -1414,7 +1407,6 @@ spec:
:::
----
```bash
# 并行执行所有导入 Job
diff --git a/zh/self_host/kubernetes/deploy.md b/zh/self_host/kubernetes/deploy.md
index 4d31378e..41796b08 100644
--- a/zh/self_host/kubernetes/deploy.md
+++ b/zh/self_host/kubernetes/deploy.md
@@ -9,14 +9,10 @@

----
-
[[toc]]
----
-
**资源和概念:**
- [SwanHubX/charts - 私有化服务发布地址](https://github.com/SwanHubX/charts/releases):SwanLab的Kubernetes Helm Chart仓库
@@ -414,8 +410,6 @@ helm install swanlab-self-hosted ./self-hosted/ \
```
- 确认无报错后,去掉 `--dry-run` 选项执行安装
----
-
通过安装 `swanlab/self-hosted`,即可在k8s上安装SwanLab私有化部署版应用,安装结果会在终端打印类似如下信息:
```bash
@@ -449,8 +443,6 @@ Get the application URL by running these commands:
如上所示,`swanlab-self-hosted` 私有化服务默认无法直接通过外部网络访问,您可以通过`port-forward`功能在本地访问此服务。
如果您希望**开启外部访问(通过IP或域名)**,请参考 [配置应用访问入口](/self_host/kubernetes/configuration.md#配置应用访问入口)。
----
-
下面是一个在本机访问的例子,打开终端并执行:
```bash
diff --git a/zh/self_host/kubernetes/monitor-logging.md b/zh/self_host/kubernetes/monitor-logging.md
new file mode 100644
index 00000000..c8b2f581
--- /dev/null
+++ b/zh/self_host/kubernetes/monitor-logging.md
@@ -0,0 +1,733 @@
+# 监控与日志配置指南
+
+> 本文档介绍了利用 `Prometheus + Grafana` 监测 SwanLab 线上应用的配置方法。
+
+## ☀️ 架构概述
+
+SwanLab 私有化部署采用微服务架构,各应用服务按照职责拆分并独立运行,整体监控链路如下:
+
+1. **Prometheus** 定期抓取 SwanLab 各个服务暴露的 `/metrics` 接口。
+2. **Grafana** 从 Prometheus 读取数据,并渲染 SwanLab 的监控仪表盘和告警面板。
+3. **「可选」Alertmanager** 或您已有的告警系统在 Prometheus 告警规则触发时发送通知。
+
+## 🪜 流程示意
+
+
+
+## 🧱 前置条件
+
+- 已通过 Helm 安装 SwanLab 私有化服务(参考 [Kubernetes 部署指南](./deploy.md))
+- 应用默认 `release_name` 为 `swanlab-self-hosted`,安装命名空间为 ``(请根据实际情况替换)
+- 具备访问相关 Kubernetes 资源的权限
+
+
+下表为 SwanLab 后端服务目前支持访问 metrics 信息的应用和对应接口配置、路由:
+
+| 服务名称 | 服务说明 | 端口 | 路由 |
+|---------|---------|------|------|
+| SwanLab-Server | 后端核心业务服务 | 3000 | /metrics |
+| SwanLab-House | 实验指标OLAP服务 | 3000 | /api/house/metrics |
+
+
+在实际配置 Prometheus 抓取任务前,建议先验证各自服务的 Prometheus Metrics 接口是否正常。
+
+- **验证 SwanLab-Server**
+
+```bash
+kubectl exec -n -c server "$(
+ kubectl get pod -n \
+ -l app.kubernetes.io/instance=swanlab-self-hosted,app.kubernetes.io/service=server \
+ -o jsonpath='{.items[0].metadata.name}'
+)" -- wget -qO- http://127.0.0.1:3000/metrics
+```
+
+- **验证 SwanLab-House**
+
+```bash
+kubectl exec -n -c house "$(
+ kubectl get pod -n \
+ -l app.kubernetes.io/instance=swanlab-self-hosted,app.kubernetes.io/service=house \
+ -o jsonpath='{.items[0].metadata.name}'
+)" -- wget -qO- http://127.0.0.1:3000/api/house/metrics
+```
+其中:
+- `app.kubernetes.io/instance=` 中,`` 使用的是默认的 RELEASE 名称,默认为 `swanlab-self-hosted` ,请按照实际部署情况替换
+- `` 替换为您实际部署使用的集群命名空间
+
+
+
+## 📊 集成监控服务
+
+根据您的环境选择合适的配置方式:
+
+- **场景一:集群中【没有】 Prometheus** — 在 SwanLab 私有化服务的命名空间内独立部署 Prometheus + Grafana,并配置可观测指标
+- **场景二:集群中【已有】 Prometheus** — 将 SwanLab 的可观测指标接入现有的 Prometheus 监控体系
+
+
+### 1. 场景一:集群中没有 Prometheus 监控
+
+此场景适用于没有现成 Prometheus 监控的集群,需要在 SwanLab 的命名空间内独立部署一套完整的 `Prometheus + Grafana` 监控栈。
+
+如集群中已有成熟的 `Prometheus` 可观测服务,可以跳过本步骤,查看 [配置 Prometheus 抓取任务](#_2-场景二-集群中已有-prometheus)。
+
+
+
+#### 1.1 创建 swanlab-monitor-PVC
+
+为 Prometheus 和 Grafana 创建持久化存储,示例中以各自 `20Gi` 的存储空间大小进行申请,可根据集群实际使用情况进行申请
+
+::: details swanlab-monitor-pvc.yaml 配置示例
+```yaml
+# ============================================================
+# Prometheus + Grafana PVC 配置
+# ============================================================
+# 用于为 Prometheus 和 Grafana 预创建持久化存储
+# 必须在安装 kube-prometheus-stack 之前创建并确保 Bound
+#
+# 使用方式:
+# kubectl apply -f swanlab-monitor-pvc.yaml
+#
+# 验证状态:
+# kubectl get pvc -n
+#
+# 注意:
+# - Prometheus PVC 名称必须与 Operator(StatefulSet)自动生成的名称完全一致:
+# prometheus--db-prometheus--<序号>
+# 其中 CR名 = -kube-prome-prometheus(release 名与 chart 名拼接后截断 26 字符)
+# release 为 swanlab-monitor 时即:
+# prometheus-swanlab-monitor-kube-prome-prometheus-db-prometheus-swanlab-monitor-kube-prome-prometheus-0
+# 名称不一致时 Operator 会另行自动创建新 PVC,预创建的 PVC 将被闲置
+# 安装后请用 kubectl get pvc -n 核对 Prometheus Pod 实际挂载的 PVC
+# - Grafana PVC 名称在 values 中通过 existingClaim 引用
+# ============================================================
+
+# Prometheus 数据存储
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ # PVC 名称必须与 Operator 自动生成的名称完全一致(格式说明见文件头注释)
+ name: prometheus-swanlab-monitor-kube-prome-prometheus-db-prometheus-swanlab-monitor-kube-prome-prometheus-0
+ namespace: # TODO: 替换为实际的命名空间
+spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 20Gi # TODO: 按需动态扩容
+ storageClassName: # TODO: 替换为实际的存储类名称
+ volumeMode: Filesystem
+---
+# Grafana 数据存储
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ # Grafana PVC 名称在 values 中通过 existingClaim 引用
+ name: swanlab-monitor-grafana-pvc
+ namespace: # TODO: 替换为实际的命名空间
+spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 20Gi # TODO: 按需动态扩容
+ storageClassName: # TODO: 替换为实际的存储类名称
+ volumeMode: Filesystem
+```
+:::
+
+使用如下指令申请监控所需的 PVC 存储资源
+```bash
+kubectl apply -f swanlab-monitor-pvc.yaml
+
+# 验证 PVC 状态(务必确保全部 Bound)
+kubectl get pvc -n
+```
+
+#### 1.2 配置 swanlab-monitor-value
+
+编写独立的 `swanlab-monitor-value.yaml` 文件,包含 Prometheus scrape job 配置、PVC 引用:
+
+::: details swanlab-monitor-value.yaml 配置示例
+```yaml
+# ============================================================
+# kube-prometheus-stack values — 使用阿里云 ACR 镜像
+# ============================================================
+# 适用于在 SwanLab 命名空间内独立部署 Prometheus + Grafana
+# 通过 Pod Annotation 自动发现 SwanLab 服务
+#
+# 使用方式:
+# helm install swanlab-monitor prometheus-community/kube-prometheus-stack \
+# -n -f swanlab-monitor-value.yaml
+#
+# 前置条件:
+# 1. 已创建 PVC(见 swanlab-monitor-pvc.yaml)
+# 2. 已添加 Helm 仓库:
+# helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
+# ============================================================
+
+# ---------- Grafana ----------
+# Grafana 用于可视化 Prometheus 数据,提供 SwanLab 监控仪表盘
+grafana:
+ persistence:
+ enabled: true
+ # 使用预创建的 PVC(必须在安装前创建并 Bound)
+ existingClaim: swanlab-monitor-grafana-pvc
+ # Grafana 管理员默认密码(默认用户名为 admin)
+ # ⚠️ 安全提示:此为示例默认密码,安装完成后请立即登录 Grafana 修改,
+ # 或改用 admin.existingSecret 引用 Kubernetes Secret 管理凭据
+ adminPassword: "swanlab-monitor@default"
+
+ # Grafana 主镜像(阿里云 ACR)
+ image:
+ registry: repo.swanlab.cn
+ repository: public/grafana
+ tag: "13.0.1-security-01"
+
+ # initChownData 容器镜像(用于初始化数据目录权限)
+ initChownData:
+ image:
+ registry: repo.swanlab.cn
+ repository: public/busybox
+ tag: "1.38.0"
+
+ # sidecar 容器镜像(用于自动加载 ConfigMap 中的 dashboard 和 datasource)
+ sidecar:
+ image:
+ registry: repo.swanlab.cn
+ repository: public/k8s-sidecar
+ tag: "2.7.3"
+
+ replicas: 1
+
+# ---------- Prometheus ----------
+# Prometheus 用于采集和存储 SwanLab 的 metrics 数据
+prometheus:
+ prometheusSpec:
+ # 允许选择所有 ServiceMonitor(不限于 Helm 管理的)
+ serviceMonitorSelectorNilUsesHelmValues: false
+
+ # 持久化存储配置
+ # Operator 按 volumeClaimTemplate 为 StatefulSet 生成 PVC,名称格式为:
+ # prometheus--db-prometheus--<序号>(CR名 = -kube-prome-prometheus)
+ # 本 release(swanlab-monitor)对应:
+ # prometheus-swanlab-monitor-kube-prome-prometheus-db-prometheus-swanlab-monitor-kube-prome-prometheus-0
+ # 该 PVC 已在 swanlab-monitor-pvc.yaml 中按此名称预创建,安装时将直接复用
+ storageSpec:
+ volumeClaimTemplate:
+ spec:
+ storageClassName: # TODO: 替换为实际的存储类名称,必须与 swanlab-monitor-pvc.yaml 中的 storageClassName 保持一致
+ accessModes: ["ReadWriteOnce"]
+ resources:
+ requests:
+ storage: 20Gi # 必须与 swanlab-monitor-pvc.yaml 中预创建的容量保持一致
+
+ replicas: 1
+
+ # Prometheus 主镜像(阿里云 ACR)
+ image:
+ registry: repo.swanlab.cn
+ repository: public/prometheus
+ tag: "v3.12.0-distroless"
+
+ # 自定义抓取配置 —— SwanLab 专属 scrape job
+ # 通过 Pod Annotation 自动发现 SwanLab 服务
+ additionalScrapeConfigs:
+ - job_name: "swanlab"
+ kubernetes_sd_configs:
+ - role: pod
+ relabel_configs:
+ # 只抓取标记为 prometheus.io/scrape: "swanlab" 的 Pod
+ - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
+ action: keep
+ regex: swanlab
+ # 从注解读取 metrics_path
+ - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
+ action: replace
+ target_label: __metrics_path__
+ regex: (.+)
+ # 从注解读取端口
+ - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
+ action: replace
+ target_label: __address__
+ regex: ([^:]+)(?::\d+)?;(\d+)
+ replacement: $1:$2
+ # 保留常用 Kubernetes 标签,方便 Grafana 查询和分组
+ - source_labels: [__meta_kubernetes_namespace]
+ target_label: namespace
+ - source_labels: [__meta_kubernetes_pod_name]
+ target_label: pod
+ - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_instance]
+ target_label: release
+ - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_service]
+ target_label: service
+
+# ---------- Alertmanager ----------
+# Alertmanager 用于处理 Prometheus 告警规则并发送通知
+alertmanager:
+ replicas: 1
+ alertmanagerSpec:
+ image:
+ registry: repo.swanlab.cn
+ repository: public/alertmanager
+ tag: "v0.32.2"
+
+# ---------- Prometheus Operator ----------
+# Prometheus Operator 用于管理 Prometheus 和 Alertmanager 实例
+prometheusOperator:
+ replicas: 1
+ image:
+ registry: repo.swanlab.cn
+ repository: public/prometheus-operator
+ tag: "v0.91.0"
+ # admissionWebhook 用于验证 PrometheusRule 和 ServiceMonitor 配置
+ admissionWebhook:
+ image:
+ registry: repo.swanlab.cn
+ repository: public/kube-webhook-certgen
+ tag: "1.8.3"
+ patch:
+ image:
+ registry: repo.swanlab.cn
+ repository: public/kube-webhook-certgen
+ tag: "1.8.3"
+ # prometheusConfigReloader 用于在 ConfigMap 变更时自动重载 Prometheus 配置
+ prometheusConfigReloader:
+ image:
+ registry: repo.swanlab.cn
+ repository: public/prometheus-config-reloader
+ tag: "v0.91.0"
+
+# ---------- Kube State Metrics ----------
+# kube-state-metrics 用于从 Kubernetes API 导出集群资源指标
+kube-state-metrics:
+ replicas: 1
+ image:
+ registry: repo.swanlab.cn
+ repository: public/kube-state-metrics
+ tag: "v2.19.0"
+
+# ---------- Node Exporter (DaemonSet) ----------
+# node-exporter 用于采集节点级别的硬件和操作系统指标
+# 注意:chart 默认 distroless: true,会自动追加 -distroless 后缀
+# 因此 tag 只需写 "v1.11.1",不要带 -distroless
+prometheus-node-exporter:
+ # 禁用 hostNetwork 避免端口冲突(默认为 true)
+ hostNetwork: false
+ hostPort:
+ enabled: false
+ # 容忍所有 taint,确保 DaemonSet 在所有节点上运行(包括控制面)
+ tolerations:
+ - effect: NoSchedule
+ operator: Exists
+ - effect: NoExecute
+ operator: Exists
+ - effect: PreferNoSchedule
+ operator: Exists
+ image:
+ registry: repo.swanlab.cn
+ repository: public/node-exporter
+ tag: "v1.11.1"
+
+```
+:::
+
+:::warning ⚠️ 安全提示
+配置示例中的 Grafana 管理员密码 `swanlab-monitor@default` 仅为默认示例值。安装完成后,请**立即登录 Grafana 修改管理员密码**;生产环境建议改用 `grafana.admin.existingSecret` 引用 Kubernetes Secret 管理凭据,避免密码明文出现在 values 文件中。
+:::
+
+#### 1.3 安装 Prometheus + Grafana
+
+类似 [升级与回滚](./upgrade.md) 章节,区分集群能否访问 `github.com`,可以选择不同的安装方式
+
+
+- **集群可以访问 github**
+
+首先添加 prometheus-community 的仓库的 `kube-prometheus-stack` chart:
+
+```bash
+# 添加 Helm 仓库
+helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
+helm repo update
+
+# 使用 helm repo 在线安装
+helm install swanlab-monitor prometheus-community/kube-prometheus-stack \
+ -n \
+ -f swanlab-monitor-value.yaml
+```
+
+- **集群无法访问 github**
+
+通过 `oci` 的方式将 `kube-prometheus-stack` 的 chart 包拉取到本地,再执行安装
+```bash
+# 1. 拉取 chart 包到本地
+helm pull oci://swanlab-registry.cn-hangzhou.cr.aliyuncs.com/chart/monitoring/kube-prometheus-stack \
+ --version 86.2.1
+# 2. 解压
+tar -zxvf kube-prometheus-stack-86.2.1.tgz
+# 3. 使用本地 chart 安装
+helm install swanlab-monitor ./kube-prometheus-stack \
+ -n \
+ -f swanlab-monitor-value.yaml
+```
+
+等待所有 `pods` 和 `deployments` 正常
+
+```bash
+# deployments
+kubectl get deployments -n | grep monitor
+
+# pods
+kubectl get pods -n | grep monitor
+```
+
+
+
+### 2. 场景二:集群中已有 Prometheus
+
+此场景适用于已有成熟 Prometheus 监控的集群,只需将 SwanLab 接入现有的 Prometheus 抓取任务。本节提供三种接入方式,选择其一即可:
+
+| 方式 | 说明 | 适用条件 | 需要修改 Pod 注解 |
+|------|------|----------|------------------|
+| [2.1 方式一:Pod Annotation(推荐)](#_2-1-方式一-pod-annotation-推荐) | 单个 job,通过注解动态发现服务 | 需要 [第 3 步](#_3-配置-pod-注解并更新服务) 配置注解 | ✅ 是 |
+| [2.2 方式二:Label-Based 双 Job](#_2-2-方式二-label-based-双-job) | 两个独立 job,通过 Pod 标签发现 | SwanLab Helm Chart 默认生成的标签即可 | ❌ 否 |
+| [2.3 方式三:Prometheus Operator](#_2-3-方式三-prometheus-operator-servicemonitor-podmonitor) | 通过 ServiceMonitor/PodMonitor 声明式接入 | 集群已部署 Prometheus Operator | ❌ 否 |
+
+#### 2.1 方式一:Pod Annotation(推荐)
+
+在现有的 `prometheus.yaml` 的 `scrape_configs` 中添加一个 SwanLab 专属 job,通过 Pod 注解动态发现服务。此方式使用单个 job 统一采集 Server 和 House,后续新增服务也只需添加注解、无需修改 Prometheus 配置。
+
+::: details prometheus.yaml - Pod Annotation scrape job 配置示例
+```yaml
+scrape_configs:
+ - job_name: "swanlab"
+ kubernetes_sd_configs:
+ - role: pod
+
+ relabel_configs:
+ # 只抓取标记为 prometheus.io/scrape: "swanlab" 的 Pod
+ - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
+ action: keep
+ regex: swanlab
+
+ # 将 Pod Annotation 中的 prometheus.io/path 作为 metrics_path
+ - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
+ action: replace
+ target_label: __metrics_path__
+ regex: (.+)
+
+ # 将 Pod Annotation 中的 prometheus.io/port 作为抓取端口
+ - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
+ action: replace
+ target_label: __address__
+ regex: ([^:]+)(?::\d+)?;(\d+)
+ replacement: $1:$2
+
+ # 保留常用 Kubernetes 标签,方便 Grafana 查询和分组
+ - source_labels: [__meta_kubernetes_namespace]
+ target_label: namespace
+
+ - source_labels: [__meta_kubernetes_pod_name]
+ target_label: pod
+
+ - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_instance]
+ target_label: release
+
+ - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_service]
+ target_label: service
+```
+:::
+
+采用方式一时,需要继续完成 [第 3 步:配置 Pod 注解](#_3-配置-pod-注解并更新服务) 才能生效。
+
+#### 2.2 方式二:Label-Based 双 Job
+
+在 `prometheus.yaml` 的 `scrape_configs` 中添加两个独立的 job,分别采集 Server 和 House。此方式基于 SwanLab Helm Chart 自动为 Pod 生成的 `app.kubernetes.io/instance` 和 `app.kubernetes.io/service` 标签进行发现,**无需修改 Pod 注解**,部署后即可接入。
+
+::: details prometheus.yaml - Label-Based 双 Job 配置示例
+```yaml
+scrape_configs:
+ - job_name: "swanlab-server"
+ kubernetes_sd_configs:
+ - role: pod
+ namespaces:
+ names:
+ - # TODO: 替换为 SwanLab 部署的命名空间
+ relabel_configs:
+ # 只抓取 release= 且 service=server 的 Pod
+ - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_instance]
+ action: keep
+ regex: swanlab-self-hosted # TODO: 替换为实际的 release name
+
+ - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_service]
+ action: keep
+ regex: server
+
+ # 强制使用 Metrics 端口
+ - source_labels: [__address__]
+ action: replace
+ target_label: __address__
+ regex: ([^:]+)(?::\d+)?
+ replacement: $1:3000
+
+ - target_label: __metrics_path__
+ replacement: /metrics
+
+ # 保留常用 Kubernetes 标签
+ - source_labels: [__meta_kubernetes_namespace]
+ target_label: namespace
+
+ - source_labels: [__meta_kubernetes_pod_name]
+ target_label: pod
+
+ - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_service]
+ target_label: service
+
+ - job_name: "swanlab-house"
+ kubernetes_sd_configs:
+ - role: pod
+ namespaces:
+ names:
+ - # TODO: 替换为 SwanLab 部署的命名空间
+ relabel_configs:
+ # 只抓取 release= 且 service=house 的 Pod
+ - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_instance]
+ action: keep
+ regex: swanlab-self-hosted # TODO: 替换为实际的 release name
+
+ - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_service]
+ action: keep
+ regex: house
+
+ # 强制使用 Metrics 端口
+ - source_labels: [__address__]
+ action: replace
+ target_label: __address__
+ regex: ([^:]+)(?::\d+)?
+ replacement: $1:3000
+
+ # House 的 Metrics 路径与 Server 不同
+ - target_label: __metrics_path__
+ replacement: /api/house/metrics
+
+ # 保留常用 Kubernetes 标签
+ - source_labels: [__meta_kubernetes_namespace]
+ target_label: namespace
+
+ - source_labels: [__meta_kubernetes_pod_name]
+ target_label: pod
+
+ - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_service]
+ target_label: service
+```
+:::
+
+::: tip 与方式一的区别
+- **无需修改 Pod 注解**:利用 SwanLab Helm Chart 默认生成的 `app.kubernetes.io/*` 标签发现,部署后即可接入。
+- **限定命名空间**:通过 `namespaces.names` 缩小 SD 范围,对权限收紧的集群更友好。
+- **独立 Job**:Server 和 House 各自一个 job,便于在 Prometheus 的 Targets 面板中独立监控和排查。
+- 导入 Grafana 仪表盘时,模板变量 `$job` 的值为 `swanlab-server` 或 `swanlab-house`(而非 `swanlab`)。
+:::
+
+#### 2.3 方式三:Prometheus Operator(ServiceMonitor / PodMonitor)
+
+如果集群中的 Prometheus 由 [Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator) 管理(例如 kube-prometheus-stack、Bitnami 等 Helm Chart),可以通过声明式的 `ServiceMonitor` 或 `PodMonitor` 资源接入 SwanLab,无需手动编辑 `prometheus.yaml`。
+
+::: details ServiceMonitor 配置示例
+```yaml
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+ name: swanlab-server
+ namespace: # TODO: 替换为 SwanLab 部署的命名空间
+ labels:
+ release: kube-prometheus-stack # TODO: 匹配 Prometheus Operator 的 serviceMonitorSelector
+spec:
+ namespaceSelector:
+ matchNames:
+ -
+ selector:
+ matchLabels:
+ app.kubernetes.io/instance: swanlab-self-hosted # TODO: 替换为实际的 release name
+ app.kubernetes.io/service: server
+ endpoints:
+ - port: http
+ path: /metrics
+ interval: 30s
+---
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+ name: swanlab-house
+ namespace: # TODO: 替换为 SwanLab 部署的命名空间
+ labels:
+ release: kube-prometheus-stack # TODO: 匹配 Prometheus Operator 的 serviceMonitorSelector
+spec:
+ namespaceSelector:
+ matchNames:
+ -
+ selector:
+ matchLabels:
+ app.kubernetes.io/instance: swanlab-self-hosted # TODO: 替换为实际的 release name
+ app.kubernetes.io/service: house
+ endpoints:
+ - port: http
+ path: /api/house/metrics
+ interval: 30s
+```
+:::
+
+::: warning
+- `metadata.labels.release` 的值必须与 Prometheus Operator 的 `serviceMonitorSelector` 匹配,否则 Operator 不会拾取此 ServiceMonitor。请检查现有 Prometheus 的 Helm values 中 `prometheus.prometheusSpec.serviceMonitorSelector` 的设置。
+- 场景一的 `swanlab-monitor-value.yaml` 已通过 `serviceMonitorSelectorNilUsesHelmValues: false` 设置允许选择所有 ServiceMonitor,因此如果在场景一中新增 ServiceMonitor 无需额外配置。
+:::
+
+### 3. 配置 Pod 注解并更新服务
+
+> 此步骤仅适用于 [方式一(Pod Annotation)](#_2-1-方式一-pod-annotation-推荐)。若采用 [方式二(Label-Based)](#_2-2-方式二-label-based-双-job) 或 [方式三(ServiceMonitor)](#_2-3-方式三-prometheus-operator-servicemonitor-podmonitor),可跳过此步,直接前往 [第 4 步](#_4-配置-ingress)。
+
+在 SwanLab 私有化服务的 `swanlab-self-hosted-value.yaml` 中,分别找到`service.server.customPodAnnotations` 和`service.house.customPodAnnotations`,为 `SwanLab-Server` 和 `SwanLab-House` 添加相应的 Prometheus抓取注解:
+
+::: details swanlab-self-hosted-value.yaml - pod 注解配置示例
+```yaml
+....
+service:
+ server:
+ ....
+ customPodAnnotations:
+ prometheus.io/scrape: "swanlab" # SwanLab 专属抓取标识
+ prometheus.io/port: "3000" # Server Metrics 端口
+ prometheus.io/path: "/metrics" # Server Metrics 路径
+...
+ house:
+ ...
+ customPodAnnotations:
+ prometheus.io/scrape: "swanlab" # SwanLab 专属抓取标识
+ prometheus.io/port: "3000" # House Metrics 端口
+ prometheus.io/path: "/api/house/metrics" # House Metrics 路径
+ ...
+```
+:::
+
+:::warning
+⚠️ **注意**: `prometheus.io/port` 和 `prometheus.io/path` 为 SwanLab 服务内置要求,通常无法更改。
+:::
+
+仅修改上述两项 service 的 pod 注解,参考 [更新与回滚](./upgrade.md) 章节,执行 value 更新,使 SwanLab 私有化服务的 pod 注解生效
+```bash
+# 在线更新
+helm upgrade swanlab-self-hosted swanlab/self-hosted \
+ -f swanlab-self-hosted-value.yaml \
+ -n
+
+# 或使用离线 chart 包更新,
+helm upgrade swanlab-self-hosted ./self-hosted \
+ -f swanlab-self-hosted-value.yaml \
+ -n
+```
+
+
+### 4. 配置 Ingress
+同理,`swanlab-monitor` 服务不包括 ingress 的网关配置,您需要在集群的负载均衡器(或 Ingress)上配置外部访问入口,需要对 `swanlab-monitor-grafana` 该 SVC 对应 pod 的 **80 端口**配置访问入口。
+
+如果您可以配置端口转发,可以通过如下指令配置端口转发,打开 `localhost:3000` 进行配置
+```bash
+kubectl port-forward svc/swanlab-monitor-grafana 3000:80 -n
+```
+
+### 5. 导入 Grafana 仪表盘
+
+SwanLab 官方提供了 Grafana 仪表盘模板,支持两种场景下的监控可视化。
+
+#### 5.1 下载配置模板
+
+- [swanlab-monitor-config-server.json](https://swanlab-docs-1301372061.cos.ap-beijing.myqcloud.com/assets/swanlab-monitor-config-server.json) — Server 服务监控仪表盘
+- [swanlab-monitor-config-house.json](https://swanlab-docs-1301372061.cos.ap-beijing.myqcloud.com/assets/swanlab-monitor-config-house.json) — House 服务监控仪表盘
+
+
+
+
+#### 5.2 导入步骤
+
+1. 在 Grafana 中,添加对应的 `prometheus` 数据源,可以点击左侧的 `Connections` -> `Data Sources` -> 右上角 `Add new data source`,选择添加 prometheus 配置,设置 URL 为您的 prometheus 端点
+
+
+
+以图中为例:
+- `swanlab-monitor-kube-prome-prometheus` 为该 namespace 下的 prometheus 对应的 SVC,暴露端口为 `9090`
+- `tenant-shaobo` 为安装该 `swanlab-self-hosted` 私有化服务的命名空间
+
+那么可以配置 `Prometheus server URL` 为 `http://swanlab-monitor-kube-prome-prometheus.tenant-shaobo:9090/`
+
+> 上述示例适用于按照 [场景一](#_1-场景一-集群中没有-prometheus-监控) 在与 `swanlab-self-hosted` 相同命名空间内安装 Prometheus 的情况。若您的 Prometheus 部署在其他命名空间或集群外,请将 URL 替换为实际可访问的 Prometheus 地址。
+
+
+2. 在 Grafana 中,导航至 **Dashboards → New → Import**
+
+
+
+3. 分别粘贴或上传 `swanlab-monitor-config-server.json` 和 `swanlab-monitor-config-house.json`
+
+4. 选择对应的 **dataSource**, **namespace**, **job** 和 **service**。
+
+仪表盘使用模板变量自动适配不同的 Prometheus 配置。导入后在 **顶部下拉菜单** 中选择:
+
+| 变量 | 说明 | 示例值 |
+|------|------|--------|
+| `$datasource` | Prometheus 数据源 | 选择已配置的数据源 |
+| `$namespace` | Kubernetes 命名空间 | `swanlab` |
+| `$job` | Prometheus scrape job 名称 | `swanlab`、`swanlab-server` 或 `swanlab-house`(取决于接入方式) |
+| `$service` | SwanLab 服务名称 | `server` 或 `house` |
+
+> **说明**:模板变量会自动从 Prometheus 读取可用值,无需手动输入。
+>
+> **注意**:House 仪表盘中的「CPU 使用情况」「内存使用量」面板数据来自 kubelet/cAdvisor 指标(`container_cpu_usage_seconds_total`、`container_memory_working_set_bytes`),并非来自 SwanLab 服务的 Metrics 接口。场景一安装的 kube-prometheus-stack 默认会采集这些指标;场景二请确认现有 Prometheus 已抓取 cAdvisor 指标,否则这两个面板将无数据。
+
+
+
+
+配置正常后可以看到相关的服务检测指标
+- **SwanLab-Server**:
+
+
+- **SwanLab-House**:
+
+
+
+
+## 📝 日志采集
+
+> 🚧 日志采集(如 `Loki + Promtail`、`ELK` 等方案)的配置指南正在编写中,敬请期待。
+> 在此之前,您可以通过 `kubectl logs` 查看各服务 Pod 的运行日志,或通过公有云自带的集群 Pod 日志服务进行观测:
+>
+> ```bash
+> kubectl logs -n -c
+> ```
+
+## ❓ 常见问题
+
+### 为什么 Metrics 接口返回 404?
+
+最有可能的原因是请求 Method 不对。请确保使用 `HTTP GET` 访问 metrics 接口。除此之外,请确保访问的服务、端口、路由都是正确的。
+
+### Metrics 接口返回的指标分别代表什么?
+
+Metrics 接口遵循 Prometheus 格式规范,通常会返回请求 QPS、请求延迟、请求错误率等信息,同时包含 Node.js、Go 等语言内部运行指标。由于指标数量庞大,很难完全列出所有指标及其含义。通常我们建议您通过 [前置条件](#🧱-前置条件) 中的验证 Metrics 接口,或者在 Prometheus 面板手动获取所有指标信息,然后借助其他工具(如大语言模型)查询对应指标的含义。
+
+### Metrics 接口是否返回了 CPU、内存等指标?
+
+Metrics 接口没有采集 CPU、内存等硬件指标。
+
+首先,出于性能考虑,SwanLab 应用服务的 Metrics 接口主要暴露应用运行状态指标,不包含 CPU、内存等系统资源指标,采集 CPU 等资源信息可能会加重应用负担。另一方面,CPU、内存指标采集可能要求更高权限,这不符合 SwanLab 的私有化部署要求。最后,在云原生环境中,这类资源指标通常由 [cAdvisor](https://github.com/google/cadvisor)、[node-exporter](https://github.com/prometheus/node_exporter) 或云厂商监控组件统一采集,您可考虑部署对应组件以采集 CPU 等数据。
+
+### 为什么 SwanLab 监控仪表盘中的面板无数据?
+
+如果是 CPU、内存等面板无数据,正如上一问所述,您需要考虑部署对应的硬件监控组件。如果您确认已部署对应的组件,或者是请求延迟等面板无数据,建议的排查步骤为:
+
+1. 在 Prometheus 面板上查询对应名称的指标是否存在;
+2. 如果存在,则说明在 Grafana 面板上的指标查询配置存在错误,需要修改 Grafana 面板配置;
+3. 如果不存在,说明 Prometheus 的抓取任务存在问题,需要排查对应任务。
+
+### 是否支持监控 PostgreSQL、ClickHouse 等基础服务?
+
+PostgreSQL、ClickHouse 有推出对应的 exporter(例如 [postgres_exporter](https://github.com/prometheus-community/postgres_exporter)),但是对部署权限要求较高。
+未来更新中会考虑为 Grafana 面板集成相应的基础服务指标。
diff --git a/zh/self_host/kubernetes/upgrade.md b/zh/self_host/kubernetes/upgrade.md
index 90a37faf..493aeef9 100644
--- a/zh/self_host/kubernetes/upgrade.md
+++ b/zh/self_host/kubernetes/upgrade.md
@@ -4,8 +4,6 @@
[[toc]]
----
-
## 1. 更新前准备
### 1.1 了解版本信息