ai

BetterUptime กับ GitOps Workflow — วิธีใช้

BetterUptime กับ GitOps Workflow — วิธีใช้

GitOps สำหรับ Monitoring

BetterUptime กับ GitOps Workflow — วิธีใช้

GitOps เป็นแนวทางที่ใช้ Git เป็น Single Source of Truth สำหรับทุกอย่างในระบบ รวมถึง Monitoring Configuration เมื่อรวม BetterUptime กับ GitOps ได้ระบบ Monitoring ที่จัดการผ่าน Code ทุกการเปลี่ยนแปลงผ่าน PR มี Review มี Audit Trail

เนื้อหาเกี่ยวข้อง — Prometheus Alertmanager Agile Scrum Kanban — คู่มือฉบับสมบูรณ์ 2026

ข้อดีคือ Version Control ย้อนกลับได้ Consistency ทุก Environment เหมือนกัน Automation ไม่ต้อง Manual Setup และ Review Process ป้องกันผิดพลาด

เนื้อหาเกี่ยวข้อง — บทความที่เกี่ยวข้อง: mql4 tutorial pdf — ข้อมูลครบถ้วน 2026

BetterUptime Configuration as Code

# === BetterUptime GitOps Configuration ===

# monitoring/config.yaml — Monitoring Configuration in Git



monitors:

  - name: "Production API"

    url: "https://api.example.com/health"

    monitor_type: "status"

    check_frequency: 30

    request_timeout: 15

    confirmation_period: 3

    regions: ["us", "eu", "as"]

    expected_status_codes: [200]

    alert_channels: ["slack-ops", "pagerduty-oncall"]



  - name: "Production Frontend"

    url: "https://www.example.com"

    monitor_type: "status"

    check_frequency: 60

    request_timeout: 30

    regions: ["us", "eu", "as", "au"]

    alert_channels: ["slack-ops"]



  - name: "Database Health"

    url: "https://api.example.com/db-health"

    monitor_type: "status"

    check_frequency: 60

    request_timeout: 10

    alert_channels: ["slack-ops", "pagerduty-oncall"]



  - name: "Staging API"

    url: "https://staging-api.example.com/health"

    monitor_type: "status"

    check_frequency: 120

    alert_channels: ["slack-dev"]



  - name: "SSL Certificate"

    url: "https://www.example.com"

    monitor_type: "ssl"

    check_frequency: 86400

    alert_channels: ["slack-ops"]



heartbeats:

  - name: "Backup Job"

    period: 86400

    grace: 3600

    alert_channels: ["slack-ops"]



  - name: "Data Sync"

    period: 3600

    grace: 600

    alert_channels: ["slack-ops"]



status_pages:

  - name: "Example Status"

    subdomain: "status-example"

    custom_domain: "status.example.com"

    sections:

      - name: "Core Services"

        monitors: ["Production API", "Production Frontend"]

      - name: "Infrastructure"

        monitors: ["Database Health"]



alert_channels:

  slack-ops:

    type: "slack"

    webhook: ""

  slack-dev:

    type: "slack"

    webhook: ""

  pagerduty-oncall:

    type: "pagerduty"

    key: ""

Python — GitOps Sync Script

BetterUptime กับ GitOps Workflow — วิธีใช้
# gitops_sync.py — Sync BetterUptime Config จาก Git

# pip install requests pyyaml



import yaml

import requests

import os

import json

import sys

from pathlib import Path



class BetterUptimeGitOps:

    """Sync BetterUptime Configuration จาก YAML Config"""



    BASE_URL = "https://betteruptime.com/api/v2"



    def __init__(self, api_token):

        self.session = requests.Session()

        self.session.headers = {

            "Authorization": f"Bearer {api_token}",

            "Content-Type": "application/json",

        }



    def load_config(self, config_path):

        """โหลด Config จาก YAML"""

        with open(config_path) as f:

            raw = f.read()



        # Replace environment variables

        for key, value in os.environ.items():

            raw = raw.replace(f"}}", value)



        return yaml.safe_load(raw)



    def get_existing_monitors(self):

        """ดึง Monitors ที่มีอยู่"""

        resp = self.session.get(f"{self.BASE_URL}/monitors")

        monitors = resp.json().get("data", [])

        return {m["attributes"]["pronounceable_name"]: m for m in monitors}



    def sync_monitors(self, config):

        """Sync Monitors ตาม Config"""

        existing = self.get_existing_monitors()

        desired = {m["name"]: m for m in config.get("monitors", [])}



        created, updated, deleted = 0, 0, 0



        # Create or Update

        for name, spec in desired.items():

            payload = {

                "pronounceable_name": name,

                "url": spec["url"],

                "monitor_type": spec.get("monitor_type", "status"),

                "check_frequency": spec.get("check_frequency", 60),

                "request_timeout": spec.get("request_timeout", 15),

                "confirmation_period": spec.get("confirmation_period", 3),

                "regions": ",".join(spec.get("regions", ["us", "eu"])),

            }



            if name in existing:

                # Update

                monitor_id = existing[name]["id"]

                resp = self.session.patch(

                    f"{self.BASE_URL}/monitors/{monitor_id}",

                    json=payload,

                )

                if resp.status_code == 200:

                    updated += 1

                    print(f"  Updated: {name}")

            else:

                # Create

                resp = self.session.post(

                    f"{self.BASE_URL}/monitors",

                    json=payload,

                )

                if resp.status_code in [200, 201]:

                    created += 1

                    print(f"  Created: {name}")



        # Delete monitors not in config

        for name, monitor in existing.items():

            if name not in desired:

                resp = self.session.delete(

                    f"{self.BASE_URL}/monitors/{monitor['id']}"

                )

                if resp.status_code in [200, 204]:

                    deleted += 1

                    print(f"  Deleted: {name}")



        return {"created": created, "updated": updated, "deleted": deleted}



    def sync_heartbeats(self, config):

        """Sync Heartbeats"""

        for hb in config.get("heartbeats", []):

            payload = {

                "name": hb["name"],

                "period": hb.get("period", 3600),

                "grace": hb.get("grace", 300),

            }

            resp = self.session.post(f"{self.BASE_URL}/heartbeats", json=payload)

            status = "created" if resp.status_code in [200, 201] else "exists"

            print(f"  Heartbeat {hb['name']}: {status}")



    def plan(self, config_path):

        """Plan — แสดงการเปลี่ยนแปลงที่จะเกิดขึ้น (Dry Run)"""

        config = self.load_config(config_path)

        existing = self.get_existing_monitors()

        desired = {m["name"]: m for m in config.get("monitors", [])}



        print("\n=== GitOps Plan ===")

        for name in desired:

            if name in existing:

                print(f"  ~ Update: {name}")

            else:

                print(f"  + Create: {name}")



        for name in existing:

            if name not in desired:

                print(f"  - Delete: {name}")



    def apply(self, config_path):

        """Apply — Sync Configuration"""

        config = self.load_config(config_path)



        print("\n=== GitOps Apply ===")

        print("\nMonitors:")

        result = self.sync_monitors(config)

        print(f"\n  Summary: {result['created']} created, "

              f"{result['updated']} updated, {result['deleted']} deleted")



        print("\nHeartbeats:")

        self.sync_heartbeats(config)



        print("\n=== Apply Complete ===")



# Usage:

# gitops = BetterUptimeGitOps(os.environ["BETTERUPTIME_TOKEN"])

# gitops.plan("monitoring/config.yaml")

# gitops.apply("monitoring/config.yaml")

CI/CD Pipeline สำหรับ GitOps Monitoring

# === GitHub Actions — GitOps Monitoring Pipeline ===

# .github/workflows/monitoring-gitops.yml



name: Monitoring GitOps

on:

  push:

    branches: [main]

    paths: ["monitoring/**"]

  pull_request:

    branches: [main]

    paths: ["monitoring/**"]



env:

  BETTERUPTIME_TOKEN: }

  SLACK_OPS_WEBHOOK: }

  SLACK_DEV_WEBHOOK: }

  PAGERDUTY_KEY: }



jobs:

  validate:

    runs-on: ubuntu-latest

    steps:

      - uses: actions/checkout@v4

      - uses: actions/setup-python@v5

        with:

          python-version: "3.11"



      - name: Install Dependencies

        run: pip install pyyaml jsonschema



      - name: Validate Config

        run: |

          python -c "

          import yaml, sys

          with open('monitoring/config.yaml') as f:

              config = yaml.safe_load(f.read())

          monitors = config.get('monitors', [])

          print(f'Monitors: {len(monitors)}')

          for m in monitors:

              assert 'name' in m, f'Missing name in monitor'

              assert 'url' in m, f'Missing url in {m[\"name\"]}'

              print(f'  OK: {m[\"name\"]}')

          print('Validation passed!')

          "



  plan:

    runs-on: ubuntu-latest

    needs: validate

    if: github.event_name == 'pull_request'

    steps:

      - uses: actions/checkout@v4

      - uses: actions/setup-python@v5

        with:

          python-version: "3.11"

      - run: pip install requests pyyaml



      - name: Plan Changes

        run: python scripts/gitops_sync.py plan monitoring/config.yaml



      - name: Comment PR

        uses: actions/github-script@v7

        with:

          script: |

            const output = `### Monitoring GitOps Plan

            Changes detected in monitoring configuration.

            Review the plan output above before approving.`;

            github.rest.issues.createComment({

              issue_number: context.issue.number,

              owner: context.repo.owner,

              repo: context.repo.repo,

              body: output

            });



  apply:

    runs-on: ubuntu-latest

    needs: validate

    if: github.ref == 'refs/heads/main'

    steps:

      - uses: actions/checkout@v4

      - uses: actions/setup-python@v5

        with:

          python-version: "3.11"

      - run: pip install requests pyyaml



      - name: Apply Changes

        run: python scripts/gitops_sync.py apply monitoring/config.yaml



      - name: Notify Slack

        if: success()

        run: |

          curl -X POST $SLACK_OPS_WEBHOOK \

            -H 'Content-Type: application/json' \

            -d '{"text":"Monitoring config updated via GitOps"}'



# === ArgoCD Application สำหรับ Monitoring Stack ===

# argocd/monitoring-app.yaml

# apiVersion: argoproj.io/v1alpha1

# kind: Application

# metadata:

#   name: monitoring-stack

#   namespace: argocd

# spec:

#   project: default

#   source:

#     repoURL: https://github.com/myorg/monitoring-config

#     path: k8s/monitoring

#     targetRevision: main

#   destination:

#     server: https://kubernetes.default.svc

#     namespace: monitoring

#   syncPolicy:

#     automated:

#       prune: true

#       selfHeal: true

#     syncOptions:

#       - CreateNamespace=true

Best Practices

  • Config in Git: เก็บ Monitoring Config ใน Git Repository เหมือน Infrastructure Code
  • PR Review: ทุกการเปลี่ยน Monitor ต้องผ่าน Pull Request มี Review ก่อน Apply
  • Plan Before Apply: แสดง Plan ก่อน Apply เหมือน Terraform Plan ป้องกันผิดพลาด
  • Environment Variables: เก็บ Secrets (API Keys, Webhooks) ใน CI/CD Secrets ไม่ Hardcode
  • Drift Detection: ตรวจสอบว่า Config จริงตรงกับ Git อย่างสม่ำเสมอ
  • Rollback: ถ้า Apply ผิดพลาด Revert Git Commit แล้ว Apply ใหม่

GitOps คืออะไร

แนวทางจัดการ Infrastructure โดยใช้ Git เป็น Single Source of Truth ทุกการเปลี่ยนแปลงผ่าน PR มี Review ใช้ ArgoCD Flux CD Reconcile สถานะจริงให้ตรงกับ Git อัตโนมัติ

แนะนำเพิ่มเติม — แหล่งความรู้ Forex iCafeForex

เนื้อหาเกี่ยวข้อง — แนะนำให้อ่าน learn ethical hacking

XM Legend · เทรดเดอร์ & ผู้สอน Forex 13 ปี

ผู้ก่อตั้ง SiamCafe ตั้งแต่ปี 1997 · เทรดเดอร์สาย Forex มากกว่า 13 ปี ได้รับการยกย่องเป็น XM Legend · แบ่งปันความรู้ Forex, ไอที, AI และการเทรด จากประสบการณ์จริงในตลาดจริง