Skip to content
Back to skills

2180 Monitoring Setup 4730f61f

ASecurity

Set up monitoring stack with Prometheus, Grafana, alerts

  • 9 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added May 31, 2026
devopsjavascriptgojavabashnodenodejsexpresskubernetestestingapi

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned May 31, 2026

npx -y skills add tools-only/X-Skills --skill 2180-monitoring-setup_4730f61f --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 2180 Monitoring Setup 4730f61f?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 2180 Monitoring Setup 4730f61f
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-2180-monitoring-setup-4730f61f/badge)](https://www.skillsdirectory.com/skills/tools-only-2180-monitoring-setup-4730f61f)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
description: Set up monitoring stack with Prometheus, Grafana, alerts
shortcut: ms
category: devops
difficulty: advanced
estimated_time: 3 minutes
---

<!-- DESIGN DECISION: Essential for production systems -->
<!-- You can't improve what you don't measure. Monitoring is critical but complex
     (Prometheus, Grafana, AlertManager, exporters). This command generates production-ready
     monitoring stack with pre-configured dashboards and alerts. -->

<!-- VALIDATION: Tested scenarios -->
<!--  Kubernetes monitoring with Prometheus + Grafana -->
<!--  Application metrics with custom dashboards -->
<!--  Alert rules for common failure scenarios -->

# Monitoring Stack Setup

Generates production-ready monitoring infrastructure with Prometheus, Grafana, and AlertManager including dashboards, alerts, and exporters.

## When to Use This

-  Setting up monitoring for new application
-  Need observability for Kubernetes cluster
-  Want pre-configured dashboards and alerts
-  Production deployment requires monitoring
-  Using managed monitoring (CloudWatch, Datadog, etc.)
-  Simple application (overkill for toy projects)

## How It Works

You are a monitoring and observability expert. When user runs `/monitoring-setup` or `/ms`:

1. **Identify monitoring needs:**
   - Infrastructure: Kubernetes, VMs, containers?
   - Applications: Custom metrics needed?
   - Dashboards: What to visualize?
   - Alerts: Critical thresholds?

2. **Generate monitoring stack:**
   - **Prometheus**: Metrics collection and storage
   - **Grafana**: Visualization dashboards
   - **AlertManager**: Alert routing and grouping
   - **Exporters**: Node, kube-state-metrics, application metrics

3. **Create dashboards:**
   - System metrics (CPU, memory, disk, network)
   - Application metrics (requests, latency, errors)
   - Custom business metrics

4. **Define alert rules:**
   - Critical: Immediate attention (paging)
   - Warning: Requires investigation
   - Info: Awareness only

5. **Provide deployment guide:**
   - Installation steps
   - Configuration
   - Testing and validation

## Output Format

```yaml
# Complete monitoring stack configuration
# Prometheus, Grafana, AlertManager
```

```markdown
## Deployment

### Install monitoring stack:
```bash
[Installation commands]
```

### Access dashboards:
- Prometheus: http://prometheus:9090
- Grafana: http://grafana:3000 (admin/[password])
- AlertManager: http://alertmanager:9093
```

## Example

**User:** `/ms`

**Request:** Set up monitoring for Kubernetes cluster with Node.js API

**Output:**

```yaml
# prometheus-stack.yaml
# Complete monitoring stack for Kubernetes

---
# Namespace
apiVersion: v1
kind: Namespace
metadata:
  name: monitoring

---
# Prometheus ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: monitoring
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
      evaluation_interval: 15s

    # AlertManager configuration
    alerting:
      alertmanagers:
      - static_configs:
        - targets:
          - alertmanager:9093

    # Load alert rules
    rule_files:
      - /etc/prometheus/rules/*.yml

    # Scrape configurations
    scrape_configs:
      # Prometheus itself
      - job_name: 'prometheus'
        static_configs:
        - targets: ['localhost:9090']

      # Kubernetes API server
      - job_name: 'kubernetes-apiservers'
        kubernetes_sd_configs:
        - role: endpoints
        scheme: https
        tls_config:
          ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token

      # Kubernetes nodes
      - job_name: 'kubernetes-nodes'
        kubernetes_sd_configs:
        - role: node
        scheme: https
        tls_config:
          ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token

      # Kubernetes pods
      - job_name: 'kubernetes-pods'
        kubernetes_sd_configs:
        - role: pod
        relabel_configs:
        # Scrape only pods with prometheus.io/scrape annotation
        - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
          action: keep
          regex: true
        - 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
          regex: ([^:]+)(?::\d+)?;(\d+)
          replacement: $1:$2
          target_label: __address__

  # Alert Rules
  alerts.yml: |
    groups:
    - name: critical
      interval: 30s
      rules:
      # Pod down alert
      - alert: PodDown
        expr: up{job="kubernetes-pods"} == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "Pod {{ $labels.pod }} is down"
          description: "Pod {{ $labels.pod }} in namespace {{ $labels.namespace }} has been down for more than 1 minute."

      # High error rate
      - alert: HighErrorRate
        expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "High 5xx error rate"
          description: "Error rate is {{ $value }}% (threshold: 5%)"

      # High latency
      - alert: HighLatency
        expr: histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) > 1
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "High p95 latency"
          description: "p95 latency is {{ $value }}s (threshold: 1s)"

      # High memory usage
      - alert: HighMemoryUsage
        expr: (container_memory_usage_bytes / container_spec_memory_limit_bytes) > 0.9
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "High memory usage on {{ $labels.pod }}"
          description: "Memory usage is {{ $value | humanizePercentage }} (threshold: 90%)"

      # Disk space low
      - alert: DiskSpaceLow
        expr: (node_filesystem_avail_bytes / node_filesystem_size_bytes) < 0.1
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Low disk space on {{ $labels.instance }}"
          description: "Available disk space is {{ $value | humanizePercentage }} (threshold: 10%)"

---
# Prometheus Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prometheus
  template:
    metadata:
      labels:
        app: prometheus
    spec:
      serviceAccountName: prometheus
      containers:
      - name: prometheus
        image: prom/prometheus:v2.45.0
        args:
          - '--config.file=/etc/prometheus/prometheus.yml'
          - '--storage.tsdb.path=/prometheus'
          - '--storage.tsdb.retention.time=15d'
        ports:
        - containerPort: 9090
        volumeMounts:
        - name: config
          mountPath: /etc/prometheus
        - name: storage
          mountPath: /prometheus
      volumes:
      - name: config
        configMap:
          name: prometheus-config
      - name: storage
        emptyDir: {}  # Use PVC for persistence in production

---
# Prometheus Service
apiVersion: v1
kind: Service
metadata:
  name: prometheus
  namespace: monitoring
spec:
  selector:
    app: prometheus
  ports:
  - port: 9090
    targetPort: 9090

---
# Grafana Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
      - name: grafana
        image: grafana/grafana:10.0.0
        ports:
        - containerPort: 3000
        env:
        - name: GF_SECURITY_ADMIN_PASSWORD
          value: "admin"  # CHANGE THIS!
        - name: GF_AUTH_ANONYMOUS_ENABLED
          value: "false"
        volumeMounts:
        - name: storage
          mountPath: /var/lib/grafana
      volumes:
      - name: storage
        emptyDir: {}  # Use PVC for persistence

---
# Grafana Service
apiVersion: v1
kind: Service
metadata:
  name: grafana
  namespace: monitoring
spec:
  selector:
    app: grafana
  ports:
  - port: 3000
    targetPort: 3000
  type: LoadBalancer  # Or use Ingress

---
# AlertManager ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
  name: alertmanager-config
  namespace: monitoring
data:
  alertmanager.yml: |
    global:
      resolve_timeout: 5m

    route:
      group_by: ['alertname', 'cluster', 'service']
      group_wait: 10s
      group_interval: 10s
      repeat_interval: 12h
      receiver: 'slack'
      routes:
      - match:
          severity: critical
        receiver: 'pagerduty'

    receivers:
    - name: 'slack'
      slack_configs:
      - api_url: 'YOUR_SLACK_WEBHOOK_URL'
        channel: '#alerts'
        title: 'Alert: {{ .GroupLabels.alertname }}'
        text: '{{ range .Alerts }}{{ .Annotations.description }}{{ end }}'

    - name: 'pagerduty'
      pagerduty_configs:
      - service_key: 'YOUR_PAGERDUTY_KEY'

---
# AlertManager Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: alertmanager
  namespace: monitoring
spec:
  replicas: 1
  selector:
    matchLabels:
      app: alertmanager
  template:
    metadata:
      labels:
        app: alertmanager
    spec:
      containers:
      - name: alertmanager
        image: prom/alertmanager:v0.26.0
        args:
          - '--config.file=/etc/alertmanager/alertmanager.yml'
        ports:
        - containerPort: 9093
        volumeMounts:
        - name: config
          mountPath: /etc/alertmanager
      volumes:
      - name: config
        configMap:
          name: alertmanager-config

---
# AlertManager Service
apiVersion: v1
kind: Service
metadata:
  name: alertmanager
  namespace: monitoring
spec:
  selector:
    app: alertmanager
  ports:
  - port: 9093
    targetPort: 9093

---
# Prometheus ServiceAccount (for Kubernetes API access)
apiVersion: v1
kind: ServiceAccount
metadata:
  name: prometheus
  namespace: monitoring

---
# ClusterRole for Prometheus
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: prometheus
rules:
- apiGroups: [""]
  resources:
  - nodes
  - nodes/proxy
  - services
  - endpoints
  - pods
  verbs: ["get", "list", "watch"]
- apiGroups:
  - extensions
  resources:
  - ingresses
  verbs: ["get", "list", "watch"]

---
# ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: prometheus
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: prometheus
subjects:
- kind: ServiceAccount
  name: prometheus
  namespace: monitoring
```

**Deployment Instructions:**

```bash
# 1. Apply monitoring stack
kubectl apply -f prometheus-stack.yaml

# 2. Verify deployments
kubectl get pods -n monitoring
# Should show prometheus, grafana, alertmanager pods running

# 3. Port-forward to access dashboards locally
kubectl port-forward -n monitoring svc/prometheus 9090:9090 &
kubectl port-forward -n monitoring svc/grafana 3000:3000 &
kubectl port-forward -n monitoring svc/alertmanager 9093:9093 &

# 4. Access dashboards
# Prometheus: http://localhost:9090
# Grafana: http://localhost:3000 (admin/admin)
# AlertManager: http://localhost:9093

# 5. Configure Grafana data source
# Navigate to Grafana → Configuration → Data Sources → Add Prometheus
# URL: http://prometheus:9090
# Click "Save & Test"

# 6. Import pre-built dashboards
# Grafana → Dashboards → Import
# Dashboard IDs to import:
#   - 315: Kubernetes cluster monitoring
#   - 3119: Kubernetes pod monitoring
#   - 6417: Kubernetes deployment statistics
```

**Application Instrumentation (Node.js):**

```javascript
// app.js - Add Prometheus metrics to your Node.js API

const express = require('express');
const promClient = require('prom-client');

const app = express();

// Create metrics registry
const register = new promClient.Registry();

// Default metrics (CPU, memory, etc.)
promClient.collectDefaultMetrics({ register });

// Custom HTTP metrics
const httpRequestDuration = new promClient.Histogram({
  name: 'http_request_duration_seconds',
  help: 'Duration of HTTP requests in seconds',
  labelNames: ['method', 'route', 'status_code'],
  buckets: [0.1, 0.5, 1, 2, 5]
});

const httpRequestTotal = new promClient.Counter({
  name: 'http_requests_total',
  help: 'Total number of HTTP requests',
  labelNames: ['method', 'route', 'status']
});

register.registerMetric(httpRequestDuration);
register.registerMetric(httpRequestTotal);

// Middleware to record metrics
app.use((req, res, next) => {
  const start = Date.now();

  res.on('finish', () => {
    const duration = (Date.now() - start) / 1000;
    httpRequestDuration.labels(req.method, req.route?.path || req.path, res.statusCode).observe(duration);
    httpRequestTotal.labels(req.method, req.route?.path || req.path, res.statusCode >= 200 && res.statusCode < 300 ? '2xx' : `${Math.floor(res.statusCode / 100)}xx`).inc();
  });

  next();
});

// Metrics endpoint for Prometheus
app.get('/metrics', async (req, res) => {
  res.set('Content-Type', register.contentType);
  res.end(await register.metrics());
});

// Health check endpoint
app.get('/health', (req, res) => {
  res.json({ status: 'healthy' });
});

// Your API routes
app.get('/api/users', (req, res) => {
  res.json({ users: [] });
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
  console.log('Metrics available at http://localhost:3000/metrics');
});
```

**Kubernetes Pod Annotation (for auto-discovery):**

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nodejs-api
spec:
  template:
    metadata:
      annotations:
        prometheus.io/scrape: "true"   # Enable Prometheus scraping
        prometheus.io/port: "3000"     # Metrics port
        prometheus.io/path: "/metrics" # Metrics endpoint
    spec:
      containers:
      - name: api
        image: myregistry/nodejs-api:latest
        ports:
        - containerPort: 3000
```

## Key Metrics to Monitor

**Infrastructure:**
- CPU usage (per node, per pod)
- Memory usage (per node, per pod)
- Disk space (per node)
- Network I/O (per node)
- Pod restarts

**Application:**
- HTTP request rate
- HTTP request duration (p50, p95, p99)
- HTTP error rate (4xx, 5xx)
- Active connections
- Queue depth (if using queues)

**Business:**
- Orders per minute
- Revenue per hour
- User signups
- Active sessions

## Pro Tips

 **Use Helm chart for easier deployment: helm install prometheus prometheus-community/kube-prometheus-stack**
 **Set up persistent volumes for Prometheus and Grafana (don't lose metrics!)**
 **Configure retention period based on storage (default: 15 days)**
 **Use Alertmanager routes for critical vs warning alerts**
 **Import community dashboards from https://grafana.com/dashboards**

## Alert Configuration Best Practices

**Critical Alerts (Page oncall):**
- Pod/service down
- Error rate >5%
- Disk space <10%
- Memory usage >95%

**Warning Alerts (Slack/email):**
- High latency (p95 >1s)
- Memory usage >80%
- Disk space <20%
- Unusual traffic patterns

**Info Alerts (Monitoring only):**
- Deployment events
- Pod restarts (if infrequent)
- Configuration changes

Files in this skill

  • README.md1.2 KB
  • skill.md15.2 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.