it

Betteruptime Feature Flag Management — ระบบ

Betteruptime Feature Flag Management — ระบบ

Better Uptime คืออะไรและทำไมต้องใช้ Feature Flag ร่วมกัน

Betteruptime Feature Flag Management — ระบบ

Better Uptime เป็นแพลตฟอร์ม Uptime Monitoring ที่ออกแบบมาสำหรับทีม DevOps และ SRE โดยเฉพาะ รองรับการตรวจสอบสถานะเว็บไซต์ API และบริการต่างๆผ่าน HTTP, TCP, UDP, DNS, ICMP และ Cron Job Monitoring สามารถแจ้งเตือนผ่านหลายช่องทางทั้ง Slack, PagerDuty, SMS, Email และ Webhook

Feature Flag (หรือ Feature Toggle) คือเทคนิคการเปิดปิดฟีเจอร์ในระบบโดยไม่ต้อง deploy ใหม่ ทำให้ทีมพัฒนาสามารถปล่อยฟีเจอร์ใหม่ให้ผู้ใช้บางกลุ่มทดสอบก่อน หรือปิดฟีเจอร์ที่มีปัญหาได้ทันทีโดยไม่ต้อง rollback deployment

การนำ Better Uptime มาใช้ร่วมกับ Feature Flag Management ช่วยให้ระบบตรวจจับปัญหาที่เกิดจากฟีเจอร์ใหม่ได้อัตโนมัติ เมื่อ Better Uptime ตรวจพบว่า Uptime หรือ Response Time ผิดปกติ ระบบจะส่ง Webhook ไปปิด Feature Flag ที่เพิ่งเปิดใช้งานโดยอัตโนมัติ ช่วยลดเวลา Mean Time To Recovery (MTTR) ได้อย่างมาก

สถาปัตยกรรมของระบบประกอบด้วย Better Uptime ทำหน้าที่ monitor สถานะบริการ, Unleash หรือ LaunchDarkly เป็น Feature Flag Server และ Webhook Middleware ที่เชื่อมทั้งสองระบบเข้าด้วยกัน

ติดตั้งและตั้งค่า Better Uptime Monitoring

เริ่มจากการตั้งค่า Better Uptime ผ่าน API เพื่อสร้าง Monitor สำหรับบริการที่ต้องการติดตาม

เนื้อหาเกี่ยวข้อง — Kubernetes Admission Webhook Testing Strategy QA

# สร้าง Monitor ผ่าน Better Uptime API

curl -X POST "https://betteruptime.com/api/v2/monitors" \

  -H "Authorization: Bearer YOUR_API_TOKEN" \

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

  -d '{

    "monitor_type": "status",

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

    "pronounceable_name": "Production API Health",

    "check_frequency": 30,

    "request_timeout": 15,

    "confirmation_period": 0,

    "http_method": "get",

    "expected_status_codes": [200],

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

    "maintenance_from": null,

    "paused": false,

    "follow_redirects": true,

    "remember_cookies": false

  }'



# สร้าง Monitor สำหรับ API Response Time

curl -X POST "https://betteruptime.com/api/v2/monitors" \

  -H "Authorization: Bearer YOUR_API_TOKEN" \

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

  -d '{

    "monitor_type": "expected_status_code",

    "url": "https://api.example.com/v2/orders",

    "pronounceable_name": "Orders API Latency",

    "check_frequency": 60,

    "request_timeout": 5,

    "http_method": "get",

    "expected_status_codes": [200, 201]

  }'



# ดูรายการ Monitors ทั้งหมด

curl -s "https://betteruptime.com/api/v2/monitors" \

  -H "Authorization: Bearer YOUR_API_TOKEN" | python3 -m json.tool

ตั้งค่า Webhook สำหรับส่งการแจ้งเตือนไปยังระบบ Feature Flag

# สร้าง Webhook Integration

curl -X POST "https://betteruptime.com/api/v2/webhooks" \

  -H "Authorization: Bearer YOUR_API_TOKEN" \

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

  -d '{

    "url": "https://ff-middleware.example.com/webhook/betteruptime",

    "webhook_type": "custom",

    "name": "Feature Flag Auto-Rollback",

    "recovery": true,

    "acknowledged": false

  }'



# ตั้งค่า Escalation Policy

curl -X POST "https://betteruptime.com/api/v2/policies" \

  -H "Authorization: Bearer YOUR_API_TOKEN" \

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

  -d '{

    "name": "Feature Flag Escalation",

    "repeat_count": 3,

    "repeat_delay": 60,

    "steps": [

      {

        "step_type": "webhook_integration",

        "wait_before": 0,

        "webhook_id": "WEBHOOK_ID_HERE"

      },

      {

        "step_type": "slack_integration",

        "wait_before": 120,

        "slack_id": "SLACK_ID_HERE"

      }

    ]

  }'

สร้างระบบ Feature Flag ด้วย Unleash

Unleash เป็น Feature Flag Server แบบ Open Source ที่สามารถ self-host ได้ รองรับหลาย SDK ทั้ง Node.js, Python, Go, Java และอื่นๆ ติดตั้งผ่าน Docker Compose ได้ง่าย

แนะนำเพิ่มเติม — อีบุ๊กการลงทุน SiamCafeBook

# docker-compose.yml สำหรับ Unleash

version: "3.9"

services:

  postgres:

    image: postgres:16-alpine

    environment:

      POSTGRES_DB: unleash

      POSTGRES_USER: unleash

      POSTGRES_PASSWORD: some-secret-password

    volumes:

      - unleash_data:/var/lib/postgresql/data

    healthcheck:

      test: ["CMD-SHELL", "pg_isready -U unleash"]

      interval: 5s

      timeout: 3s

      retries: 5



  unleash:

    image: unleashorg/unleash-server:latest

    ports:

      - "4242:4242"

    environment:

      DATABASE_URL: "postgres://unleash:some-secret-password@postgres:5432/unleash"

      DATABASE_SSL: "false"

      LOG_LEVEL: "info"

      INIT_ADMIN_API_TOKENS: "*:*.unleash-admin-api-token"

      INIT_CLIENT_API_TOKENS: "default:development.unleash-client-token"

    depends_on:

      postgres:

        condition: service_healthy



volumes:

  unleash_data:



# เริ่มต้นระบบ

# docker compose up -d

# เข้าถึง Unleash UI ที่ http://localhost:4242

สร้าง Feature Flag ผ่าน Unleash API

# สร้าง Feature Flag ใหม่

curl -X POST "http://localhost:4242/api/admin/projects/default/features" \

  -H "Authorization: *:*.unleash-admin-api-token" \

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

  -d '{

    "name": "new-checkout-flow",

    "description": "ระบบชำระเงินแบบใหม่ที่ปรับปรุง UX",

    "type": "release",

    "impressionData": true

  }'



# เปิด Feature Flag ใน Development Environment

curl -X POST "http://localhost:4242/api/admin/projects/default/features/new-checkout-flow/environments/development/on" \

  -H "Authorization: *:*.unleash-admin-api-token"



# เพิ่ม Strategy แบบ Gradual Rollout (เปิดให้ 10% ก่อน)

curl -X POST "http://localhost:4242/api/admin/projects/default/features/new-checkout-flow/environments/production/strategies" \

  -H "Authorization: *:*.unleash-admin-api-token" \

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

  -d '{

    "name": "flexibleRollout",

    "parameters": {

      "rollout": "10",

      "stickiness": "userId",

      "groupId": "new-checkout-flow"

    }

  }'



# ดูสถานะ Feature Flag

curl -s "http://localhost:4242/api/admin/projects/default/features/new-checkout-flow" \

  -H "Authorization: *:*.unleash-admin-api-token" | python3 -m json.tool

เชื่อมต่อ Feature Flag กับ Uptime Monitoring

Betteruptime Feature Flag Management — ระบบ

สร้าง Webhook Middleware Server ที่รับ alert จาก Better Uptime แล้วควบคุม Feature Flag ใน Unleash

# ff_middleware.py — Webhook Middleware Server

from flask import Flask, request, jsonify

import requests

import json

import os

import logging

from datetime import datetime



app = Flask(__name__)

logging.basicConfig(level=logging.INFO)

logger = logging.getLogger(__name__)



UNLEASH_URL = os.getenv("UNLEASH_URL", "http://localhost:4242")

UNLEASH_TOKEN = os.getenv("UNLEASH_TOKEN", "*:*.unleash-admin-api-token")

SLACK_WEBHOOK = os.getenv("SLACK_WEBHOOK", "")



# Mapping ระหว่าง Monitor กับ Feature Flag

MONITOR_FLAG_MAP = {

    "Production API Health": ["new-checkout-flow", "new-search-engine"],

    "Orders API Latency": ["new-checkout-flow"],

    "Payment Gateway": ["new-payment-provider"],

}



def disable_feature_flag(flag_name, environment="production"):

    url = f"{UNLEASH_URL}/api/admin/projects/default/features/{flag_name}/environments/{environment}/off"

    r = requests.post(url, headers={

        "Authorization": UNLEASH_TOKEN,

        "Content-Type": "application/json"

    })

    logger.info(f"Disabled flag {flag_name}: {r.status_code}")

    return r.status_code == 200



def enable_feature_flag(flag_name, environment="production"):

    url = f"{UNLEASH_URL}/api/admin/projects/default/features/{flag_name}/environments/{environment}/on"

    r = requests.post(url, headers={

        "Authorization": UNLEASH_TOKEN,

        "Content-Type": "application/json"

    })

    logger.info(f"Enabled flag {flag_name}: {r.status_code}")

    return r.status_code == 200



def notify_slack(message):

    if SLACK_WEBHOOK:

        requests.post(SLACK_WEBHOOK, json={"text": message})



@app.route("/webhook/betteruptime", methods=["POST"])

def handle_betteruptime():

    data = request.json

    monitor_name = data.get("data", {}).get("attributes", {}).get("pronounceable_name", "")

    status = data.get("data", {}).get("attributes", {}).get("status", "")

    

    flags = MONITOR_FLAG_MAP.get(monitor_name, [])

    if not flags:

        return jsonify({"status": "no_flags_mapped"}), 200

    

    timestamp = datetime.now().isoformat()

    

    if status == "down":

        for flag in flags:

            disable_feature_flag(flag)

        notify_slack(f"[{timestamp}] ALERT: {monitor_name} is DOWN. Disabled flags: {', '.join(flags)}")

        return jsonify({"action": "disabled", "flags": flags})

    

    elif status == "up":

        notify_slack(f"[{timestamp}] RECOVERY: {monitor_name} is UP. Flags remain disabled for manual review.")

        return jsonify({"action": "recovery_noted", "flags": flags})

    

    return jsonify({"status": "ignored"}), 200



@app.route("/health", methods=["GET"])

def health():

    return jsonify({"status": "ok"})



if __name__ == "__main__":

    app.run(host="0.0.0.0", port=9090)

Deploy middleware นี้ด้วย Docker

เนื้อหาเกี่ยวข้อง — บทความที่เกี่ยวข้อง: Vercel Edge Functions Progressive Delivery

# Dockerfile สำหรับ middleware

FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY ff_middleware.py .

EXPOSE 9090

CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:9090", "ff_middleware:app"]



# requirements.txt

flask==3.0.0

gunicorn==21.2.0

requests==2.31.0



# สร้างและรัน

docker build -t ff-middleware .

docker run -d --name ff-middleware \

  -p 9090:9090 \

  -e UNLEASH_URL=http://unleash:4242 \

  -e UNLEASH_TOKEN="*:*.unleash-admin-api-token" \

  -e SLACK_WEBHOOK="https://hooks.slack.com/services/xxx" \

  ff-middleware

ตั้งค่า Auto-Rollback เมื่อ Uptime ต่ำกว่า Threshold

นอกจากการปิด Feature Flag อัตโนมัติเมื่อ monitor down แล้ว ยังสามารถตั้งค่าให้ตรวจสอบ metrics อื่นๆเช่น Response Time, Error Rate หรือ Apdex Score เพื่อตัดสินใจ rollback ได้ละเอียดขึ้น

#!/usr/bin/env python3

# auto_rollback_checker.py — ตรวจสอบ metrics และ rollback อัตโนมัติ

import requests

import time

import json

import os

import sys



BETTERUPTIME_TOKEN = os.getenv("BETTERUPTIME_TOKEN")

UNLEASH_URL = os.getenv("UNLEASH_URL", "http://localhost:4242")

UNLEASH_TOKEN = os.getenv("UNLEASH_TOKEN")



THRESHOLDS = {

    "uptime_percent_min": 99.5,

    "response_time_max_ms": 2000,

    "incidents_max": 2,

    "check_interval_seconds": 300,

}



RECENT_FLAGS = []  # เก็บ flags ที่เพิ่งเปิดในช่วง 24 ชั่วโมง



def get_monitor_stats(monitor_id):

    url = f"https://betteruptime.com/api/v2/monitors/{monitor_id}/sla"

    r = requests.get(url, headers={"Authorization": f"Bearer {BETTERUPTIME_TOKEN}"})

    if r.status_code != 200:

        return None

    data = r.json().get("data", {}).get("attributes", {})

    return {

        "availability": float(data.get("availability", 100)),

        "response_time": float(data.get("average_response_time", 0)),

        "incidents": int(data.get("number_of_incidents", 0)),

    }



def get_recent_flags():

    url = f"{UNLEASH_URL}/api/admin/events?type=feature-environment-enabled"

    r = requests.get(url, headers={"Authorization": UNLEASH_TOKEN})

    events = r.json().get("events", [])

    recent = []

    for e in events[:20]:

        if e.get("environment") == "production":

            recent.append(e.get("featureName"))

    return recent



def disable_flag(flag_name):

    url = f"{UNLEASH_URL}/api/admin/projects/default/features/{flag_name}/environments/production/off"

    requests.post(url, headers={

        "Authorization": UNLEASH_TOKEN,

        "Content-Type": "application/json"

    })

    print(f"[ROLLBACK] Disabled: {flag_name}")



def check_and_rollback(monitor_id):

    stats = get_monitor_stats(monitor_id)

    if not stats:

        print("Failed to get monitor stats")

        return

    

    print(f"Uptime: {stats['availability']}% | "

          f"Response: {stats['response_time']}ms | "

          f"Incidents: {stats['incidents']}")

    

    needs_rollback = False

    if stats["availability"] < THRESHOLDS["uptime_percent_min"]:

        print(f"ALERT: Uptime {stats['availability']}% below threshold")

        needs_rollback = True

    if stats["response_time"] > THRESHOLDS["response_time_max_ms"]:

        print(f"ALERT: Response time {stats['response_time']}ms above threshold")

        needs_rollback = True

    if stats["incidents"] > THRESHOLDS["incidents_max"]:

        print(f"ALERT: {stats['incidents']} incidents above threshold")

        needs_rollback = True

    

    if needs_rollback:

        recent_flags = get_recent_flags()

        for flag in recent_flags:

            disable_flag(flag)

        print(f"Rolled back {len(recent_flags)} flags")

    else:

        print("All metrics OK")



if __name__ == "__main__":

    monitor_id = sys.argv[1] if len(sys.argv) > 1 else "MONITOR_ID"

    while True:

        check_and_rollback(monitor_id)

        time.sleep(THRESHOLDS["check_interval_seconds"])

ตั้ง cron job หรือ Kubernetes CronJob ให้รันตรวจสอบทุก 5 นาที

# Kubernetes CronJob

apiVersion: batch/v1

kind: CronJob

metadata:

  name: uptime-flag-checker

spec:

  schedule: "*/5 * * * *"

  jobTemplate:

    spec:

      template:

        spec:

          containers:

          - name: checker

            image: python:3.12-slim

            command: ["python3", "/app/auto_rollback_checker.py", "MONITOR_ID"]

            env:

            - name: BETTERUPTIME_TOKEN

              valueFrom:

                secretKeyRef:

                  name: monitoring-secrets

                  key: betteruptime-token

            - name: UNLEASH_URL

              value: "http://unleash.default:4242"

            - name: UNLEASH_TOKEN

              valueFrom:

                secretKeyRef:

                  name: monitoring-secrets

                  key: unleash-token

          restartPolicy: OnFailure

Dashboard และ Alerting สำหรับ Feature Flag

สร้าง Status Page ที่แสดงสถานะของ Feature Flag ร่วมกับ Uptime ได้ด้วย Better Uptime Status Page API

แนะนำเพิ่มเติม — สัญญาณเทรดรายวัน XM Signal

# สร้าง Status Page

curl -X POST "https://betteruptime.com/api/v2/status-pages" \

  -H "Authorization: Bearer YOUR_API_TOKEN" \

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

  -d '{

    "subdomain": "status-myapp",

    "company_name": "MyApp",

    "company_url": "https://example.com",

    "timezone": "Asia/Bangkok",

    "subscribable": true

  }'



# เพิ่ม Resource เข้า Status Page

curl -X POST "https://betteruptime.com/api/v2/status-pages/STATUS_PAGE_ID/resources" \

  -H "Authorization: Bearer YOUR_API_TOKEN" \

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

  -d '{

    "resource_id": "MONITOR_ID",

    "resource_type": "Monitor",

    "public_name": "API Server",

    "status_page_section_id": "SECTION_ID"

  }'

สำหรับ Grafana Dashboard ที่แสดงข้อมูล Feature Flag และ Uptime ร่วมกัน ใช้ Unleash Metrics API และ Better Uptime API เป็น data source

เนื้อหาเกี่ยวข้อง — แนะนำให้อ่าน Cloud-init API Integration เชื่อมต่อระบบ

# Prometheus metrics exporter สำหรับ Feature Flag status

# ff_exporter.py

from prometheus_client import start_http_server, Gauge

import requests

import time

import os



UNLEASH_URL = os.getenv("UNLEASH_URL", "http://localhost:4242")

UNLEASH_TOKEN = os.getenv("UNLEASH_TOKEN")



flag_status = Gauge("feature_flag_enabled", "Feature flag status", ["flag_name", "environment"])

flag_rollout = Gauge("feature_flag_rollout_percent", "Rollout percentage", ["flag_name"])



def collect_metrics():

    r = requests.get(f"{UNLEASH_URL}/api/admin/projects/default/features",

                     headers={"Authorization": UNLEASH_TOKEN})

    features = r.json().get("features", [])

    for f in features:

        name = f["name"]

        for env in f.get("environments", []):

            enabled = 1 if env.get("enabled") else 0

            flag_status.labels(flag_name=name, environment=env["name"]).set(enabled)

            for strategy in env.get("strategies", []):

                rollout = strategy.get("parameters", {}).get("rollout", "100")

                flag_rollout.labels(flag_name=name).set(float(rollout))



if __name__ == "__main__":

    start_http_server(9091)

    while True:

        collect_metrics()

        time.sleep(30)

FAQ คำถามที่พบบ่อย

Q: Better Uptime กับ UptimeRobot ต่างกันอย่างไร?

A: Better Uptime มี Incident Management ในตัว รองรับ On-call Scheduling และ Status Page ที่สวยกว่า ส่วน UptimeRobot เน้นความเรียบง่ายและมีแผนฟรีที่ใช้งานได้ดี สำหรับระบบที่ต้องการ Webhook Integration กับ Feature Flag แนะนำ Better Uptime เพราะ API ครบถ้วนกว่า

Q: Feature Flag ทำให้ระบบช้าลงไหม?

A: ผลกระทบน้อยมากถ้าใช้ SDK ที่ cache flag evaluation ไว้ในหน่วยความจำ Unleash SDK จะ poll ค่า flag จาก server ทุก 15 วินาทีแล้วเก็บไว้ใน memory ดังนั้นการ evaluate flag จะใช้เวลาเพียงไม่กี่ microsecond ไม่กระทบ response time ของแอปพลิเคชัน

Q: ควร self-host Unleash หรือใช้ Managed Service?

เนื้อหาเกี่ยวข้อง — แนะนำให้อ่าน dual band wifi คือ — ข้อมูลครบถ้วน 2026

A: ถ้าทีมมี DevOps ที่ดูแล infrastructure ได้ self-host จะประหยัดค่าใช้จ่ายและควบคุมข้อมูลได้เต็มที่ แต่ถ้าต้องการความสะดวกและ SLA ที่รับประกัน Unleash Cloud หรือ LaunchDarkly เป็นตัวเลือกที่ดี สำหรับองค์กรที่ต้องการ compliance เช่น SOC2 หรือ GDPR แนะนำ self-host เพราะข้อมูลอยู่ใน infrastructure ของตัวเอง

Q: ถ้า Feature Flag Server ล่มจะเกิดอะไรขึ้น?

A: Unleash SDK มี fallback mechanism ถ้าเชื่อมต่อ server ไม่ได้จะใช้ค่าล่าสุดที่ cache ไว้ และสามารถกำหนด default value ได้เมื่อไม่สามารถ evaluate flag ได้ ดังนั้นแม้ Feature Flag Server ล่มแอปพลิเคชันจะยังทำงานได้ตามปกติด้วย flag value ล่าสุด

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

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