All Products
Search
Document Center

Application Real-Time Monitoring Service:Aktifkan observabilitas ECS melalui OpenTelemetry eBPF (OBI)

Last Updated:Jul 17, 2026

Setelah Anda menggunakan OpenTelemetry eBPF Instrumentation (OBI) untuk melaporkan data trace ke Application Real-Time Monitoring Service (ARMS) secara non-intrusif, ARMS akan mulai memantau aplikasi Anda. Anda dapat melihat topologi aplikasi, jejak panggilan, transaksi abnormal, transaksi lambat, analisis SQL, serta data pemantauan lainnya. Topik ini menjelaskan cara menggunakan OBI untuk memantau aplikasi dan melaporkan data.

Prasyarat

Catatan

Jika Anda mengalami masalah saat menggunakan OpenTelemetry eBPF, hubungi kami melalui grup tanya jawab DingTalk (nomor grup: 159215000379).

  • Server Linux (instans Elastic Compute Service (ECS) atau lingkungan on-premises) yang memenuhi persyaratan berikut telah disiapkan.

    Persyaratan

    Range yang didukung

    Versi kernel

    Linux 5.8 atau lebih baru. Distribusi berbasis RHEL (dengan patch backport eBPF) mendukung minimal Linux 4.18.

    BTF

    Kernel harus mengekspos informasi BTF (BPF Type Format).

    Arsitektur CPU

    amd64 (x86_64), arm64 (aarch64).

    Izin

    Izin root.

    Catatan

    Alibaba Cloud Linux 3 dan Alibaba Cloud Linux 4 memenuhi persyaratan di atas secara default.

    Untuk memeriksa apakah server Anda memenuhi persyaratan, jalankan perintah berikut:

    # Periksa versi kernel (harus >= 5.8, atau >= 4.18 untuk distribusi berbasis RHEL)
    uname -r
    
    # Periksa arsitektur CPU (harus amd64 atau arm64)
    uname -m
    
    # Periksa apakah BTF tersedia (file ada jika didukung)
    ls /sys/kernel/btf/vmlinux
    
    # Periksa apakah Anda memiliki izin root
    whoami

Informasi latar belakang

OBI adalah komponen instrumentation otomatis berbasis eBPF untuk observabilitas Kubernetes. Komponen ini diterapkan sebagai DaemonSet pada node kluster dan dapat secara otomatis mengumpulkan data Metrics dan Traces dari aplikasi tanpa mengubah kode aplikasi atau menyuntikkan sidecar. OBI mendukung deteksi otomatis protokol utama seperti HTTP, gRPC, SQL, Redis, Kafka, dan lainnya, serta menyediakan ekstraksi mendalam terhadap isi request dan response untuk skenario GenAI (OpenAI, Anthropic, Qwen, MCP, Embedding, Rerank, dan lainnya). Data telemetri yang dikumpulkan diekspor melalui protokol OTLP dan dapat diintegrasikan secara mulus dengan platform observabilitas seperti ARMS, membantu Anda mencapai observabilitas full-stack dengan nol intrusi dan overhead rendah.

Metode pencocokan penemuan aplikasi

OBI menemukan dan mencocokkan proses yang akan dipantau melalui bagian konfigurasi discovery.instrument. Metode pencocokan berikut didukung (semua kondisi menggunakan logika AND—semua kondisi harus terpenuhi agar cocok):

Bidang YAML

Tipe

Deskripsi

Contoh

open_ports

Nomor/range port

Nomor port yang didengarkan oleh proses. Mendukung nilai yang dipisahkan koma dan range.

8080, 80,443, 8000-8999

exe_path

Pola Glob

Mencocokkan path lengkap file executable proses.

*/java, */nginx, *myapp*

cmd_args

Pola Glob

Mencocokkan argumen command-line proses (tidak termasuk nama file executable).

*petclinic*, *--config=prod*

languages

Pola Glob

Mencocokkan otomatis berdasarkan bahasa pemrograman (go/java/python/ruby/nodejs/rust/dotnet/php/cpp).

java, {go,rust}

target_pids

Daftar PID

Menentukan langsung PID proses.

[12345, 67890]

container_name

Pola Glob

Mencocokkan nama kontainer OCI (berlaku untuk penerapan Docker).

my-container-*

containers_only

Boolean

Hanya mencocokkan proses di dalam kontainer.

true

name

String

Nama aplikasi yang ditampilkan di Konsol ARMS.

my-app

namespace

String

Namespace layanan.

production

exports

Daftar sinyal

Mengontrol jenis sinyal yang diekspor (metrics/traces/logs). Array kosong menonaktifkan semua ekspor.

[metrics, traces]

sampler

Konfigurasi sampling

Sampling Traces berdasarkan rasio untuk mengurangi volume data.

name: traceidratio, arg: "0.5"

Contoh konfigurasi skenario umum

Skenario 1: Pencocokan berdasarkan nomor port — Metode paling sederhana, berlaku untuk semua jenis aplikasi web

discovery:
  instrument:
    - name: my-web-app
      open_ports: 8080

Skenario 2: Aplikasi Java (exe_path + cmd_args) — Menemukan proses berdasarkan executable java dan nama JAR

discovery:
  instrument:
    - name: my-java-app
      exe_path: "*/java"
      cmd_args: "*petclinic*"

Skenario 3: Penemuan otomatis berdasarkan bahasa pemrograman — Secara otomatis mendeteksi semua proses dari bahasa tertentu

discovery:
  instrument:
    - name: go-services
      languages: go
    - name: python-services
      languages: "{python,nodejs}"

Skenario 4: Pencocokan berdasarkan path file executable — Berlaku untuk binary hasil kompilasi sendiri

discovery:
  instrument:
    - name: my-binary
      exe_path: "*/my-server"

Skenario 5: Pencocokan berdasarkan nama kontainer Docker — Berlaku untuk penerapan Docker di ECS

discovery:
  instrument:
    - name: my-container-app
      container_name: "my-container-*"

Skenario 6: Range port ganda — Memantau layanan dalam range port tertentu

discovery:
  instrument:
    - name: microservices
      open_ports: 8080-8090,9090

Skenario 7: Menentukan PID untuk debugging sementara — Langsung menentukan PID proses untuk pemantauan

discovery:
  instrument:
    - name: debug-target
      target_pids: [12345]

Skenario 8: Hanya proses kontainer + sampling — Memantau hanya proses kontainer dengan sampling Traces 50%

discovery:
  instrument:
    - name: container-apps
      containers_only: true
      open_ports: 8080
      sampler:
        name: traceidratio
        arg: "0.5"

Skenario 9: Beberapa aplikasi + aturan eksklusi — Memantau beberapa aplikasi sekaligus mengecualikan proses tertentu

discovery:
  instrument:
    - name: api-gateway
      open_ports: 80,443
    - name: backend-java
      exe_path: "*/java"
      cmd_args: "*backend*"
    - name: worker
      exe_path: "*/python*"
      cmd_args: "*celery*"
  exclude_instrument:
    - exe_path: "{obi,prometheus,otelcol*}"

Skenario 10: Mengontrol sinyal yang diekspor — Hanya mengekspor Metrics tanpa Traces

discovery:
  instrument:
    - name: high-qps-app
      open_ports: 8080
      exports: [metrics]

Prosedur

Ikhtisar prosedur: Instalasi dan penerapan (dapatkan informasi endpoint > unduh OBI > buat file konfigurasi > terapkan layanan) > Verifikasi data pemantauan

Instalasi dan penerapan

Tersedia dua metode penerapan: penerapan skrip satu klik (direkomendasikan) dan penerapan manual langkah demi langkah.

Metode 1: Penerapan skrip satu klik (direkomendasikan)

Semua langkah digabungkan dalam satu skrip obi-setup.sh yang mendukung mode interaktif dan non-interaktif.

#!/bin/bash
# ============================================================================
#  Skrip penerapan satu klik OBI
#  Menggabungkan pemeriksaan lingkungan, unduh, pembuatan konfigurasi, dan instalasi layanan menjadi alur kerja lengkap.
#
#  Penggunaan:
#    sudo bash obi-setup.sh install   — Instalasi interaktif (binary + systemd)
#    sudo bash obi-setup.sh docker    — Terapkan menggunakan Docker
#    sudo bash obi-setup.sh check     — Jalankan hanya pemeriksaan lingkungan
#    sudo bash obi-setup.sh uninstall — Uninstal layanan OBI
#    sudo bash obi-setup.sh status    — Lihat status berjalan dan log
#
#  Penerapan non-interaktif (variabel lingkungan):
#    export OTLP_ENDPOINT="http://xxx:4318"
#    export OTLP_HEADERS="Authentication=xxx"
#    export APP_NAME="my-app"
#    export APP_MATCH_TYPE="port"    # port|cmd|exe|lang|container|pid
#    export APP_MATCH_VALUE="8080"
#    sudo -E bash obi-setup.sh install
# ============================================================================

set -euo pipefail

# ========================= Variabel Global =========================
VERSION="0.10.0"
SERVICE_NAME="obi"
INSTALL_DIR="/opt/obi"
CONFIG_FILE="${INSTALL_DIR}/config.yaml"
OBI_BINARY="${INSTALL_DIR}/obi"
DOCKER_IMAGE="registry.cn-hangzhou.aliyuncs.com/private-mesh/obi:${VERSION}"
OSS_BASE="https://arms-apm-cn-hangzhou-pre.oss-cn-hangzhou.aliyuncs.com/obi-agent/${VERSION}"

# Warna
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m'

# Daftar aplikasi (array)
declare -a APP_ENTRIES=()
# Aturan eksklusi
EXCLUDE_PATTERN=""

# ========================= Fungsi Utilitas =========================
info()  { echo -e "${CYAN}[INFO]${NC} $*"; }
ok()    { echo -e "${GREEN}[OK]${NC} $*"; }
warn()  { echo -e "${YELLOW}[WARN]${NC} $*"; }
fail()  { echo -e "${RED}[FAIL]${NC} $*"; }
die()   { fail "$*"; exit 1; }

prompt_input() {
    local var_name="$1" prompt_msg="$2" default_val="${3:-}"
    local current_val="${!var_name:-}"
    if [[ -n "$current_val" ]]; then
        info "Menggunakan variabel lingkungan ${var_name}=${current_val}"
        return
    fi
    if [[ -n "$default_val" ]]; then
        read -rp "$(echo -e "${BOLD}${prompt_msg} [${default_val}]: ${NC}")" input
        eval "$var_name=\"${input:-$default_val}\""
    else
        while true; do
            read -rp "$(echo -e "${BOLD}${prompt_msg}: ${NC}")" input
            if [[ -n "$input" ]]; then
                eval "$var_name=\"$input\""
                return
            fi
            warn "Bidang ini wajib diisi"
        done
    fi
}

prompt_yesno() {
    local prompt_msg="$1" default="${2:-n}"
    local yn
    read -rp "$(echo -e "${BOLD}${prompt_msg} [y/N]: ${NC}")" yn
    case "${yn:-$default}" in
        [Yy]*) return 0 ;;
        *) return 1 ;;
    esac
}

# ========================= Pemeriksaan Lingkungan =========================
check_root() {
    if [[ "$EUID" -ne 0 ]]; then
        die "Jalankan dengan izin root: sudo bash $0 $*"
    fi
    ok "Izin root"
}

check_env() {
    echo ""
    echo -e "${BOLD}========== Pemeriksaan Lingkungan ==========${NC}"

    local kernel_ver major minor
    kernel_ver=$(uname -r)
    major=$(echo "$kernel_ver" | cut -d. -f1)
    minor=$(echo "$kernel_ver" | cut -d. -f2)

    local is_rhel=false
    if [[ -f /etc/redhat-release ]] || grep -qi 'rhel\|centos\|rocky\|alma\|anolis\|alinux' /etc/os-release 2>/dev/null; then
        is_rhel=true
    fi

    if [[ "$major" -gt 5 ]] || { [[ "$major" -eq 5 ]] && [[ "$minor" -ge 8 ]]; }; then
        ok "Versi kernel: ${kernel_ver} (>= 5.8)"
    elif $is_rhel && { [[ "$major" -gt 4 ]] || { [[ "$major" -eq 4 ]] && [[ "$minor" -ge 18 ]]; }; }; then
        ok "Versi kernel: ${kernel_ver} (berbasis RHEL, >= 4.18)"
    else
        fail "Versi kernel: ${kernel_ver} (minimal 5.8, berbasis RHEL 4.18)"
        return 1
    fi

    local arch
    arch=$(uname -m)
    case "$arch" in
        x86_64|amd64) ok "Arsitektur CPU: ${arch} (amd64)" ;;
        aarch64|arm64) ok "Arsitektur CPU: ${arch} (arm64)" ;;
        *) fail "Arsitektur CPU: ${arch} (tidak didukung)"; return 1 ;;
    esac

    if [[ -f /sys/kernel/btf/vmlinux ]]; then
        ok "BTF: Tersedia"
    else
        fail "BTF: /sys/kernel/btf/vmlinux tidak ada"
        return 1
    fi

    echo -e "${GREEN}========== Pemeriksaan Lingkungan Lolos ==========${NC}"
    echo ""
    return 0
}

detect_arch() {
    local arch
    arch=$(uname -m)
    case "$arch" in
        x86_64|amd64) echo "amd64" ;;
        aarch64|arm64) echo "arm64" ;;
        *) die "Arsitektur CPU tidak didukung: ${arch}" ;;
    esac
}

# ========================= Konfigurasi Aplikasi Tunggal =========================
collect_one_app() {
    local app_name match_type
    local entry=""

    prompt_input app_name "Nama aplikasi (ditampilkan di Konsol ARMS)" "my-app"

    echo ""
    echo -e "  ${BOLD}Pilih metode pencocokan aplikasi:${NC}"
    echo -e "    1) Pencocokan nomor port     — open_ports, misalnya 8080 atau 80,443 atau 8000-8999"
    echo -e "    2) Pencocokan baris perintah — exe_path + cmd_args, untuk skenario java -jar"
    echo -e "    3) Pencocokan path executable — exe_path, untuk binary hasil kompilasi sendiri"
    echo -e "    4) Penemuan otomatis bahasa — languages, deteksi otomatis go/java/python/nodejs dll."
    echo -e "    5) Nama kontainer Docker     — container_name, untuk Docker di ECS"
    echo -e "    6) Penentuan PID             — target_pids, untuk debugging sementara"
    read -rp "$(echo -e "${BOLD}Pilih [1-6, default 1]: ${NC}")" match_choice

    entry="    - name: ${app_name}"

    case "${match_choice:-1}" in
        1)
            local ports
            prompt_input ports "Port pendengar (misalnya 8080, 80,443, 8000-8999)" "8080"
            entry="${entry}
      open_ports: ${ports}"
            ;;
        2)
            local exe_path cmd_args
            prompt_input exe_path "Glob path executable (misalnya */java)" "*/java"
            prompt_input cmd_args "Glob argumen baris perintah (misalnya *petclinic*)"
            entry="${entry}
      exe_path: \"${exe_path}\"
      cmd_args: \"${cmd_args}\""
            ;;
        3)
            local exe_path
            prompt_input exe_path "Glob path executable (misalnya */my-server, */nginx)"
            entry="${entry}
      exe_path: \"${exe_path}\""
            ;;
        4)
            local lang
            echo -e "    Bahasa yang didukung: go, java, python, ruby, nodejs, rust, dotnet, php, cpp"
            echo -e "    Beberapa bahasa gunakan kurung kurawal: {go,rust} atau {python,nodejs}"
            prompt_input lang "Bahasa pemrograman" "java"
            entry="${entry}
      languages: \"${lang}\""
            ;;
        5)
            local cname
            prompt_input cname "Glob nama kontainer Docker (misalnya my-container-*)"
            entry="${entry}
      container_name: \"${cname}\""
            ;;
        6)
            local pids
            prompt_input pids "Daftar PID, dipisahkan koma (misalnya 12345,67890)"
            local pid_array
            pid_array=$(echo "$pids" | tr ',' '\n' | sed 's/^[[:space:]]*//' | awk '{printf "      - %s\n", $0}')
            entry="${entry}
      target_pids:
${pid_array}"
            ;;
        *)
            local ports
            prompt_input ports "Port pendengar" "8080"
            entry="${entry}
      open_ports: ${ports}"
            ;;
    esac

    # Opsional: hanya proses kontainer
    if [[ "${match_choice:-1}" != "5" ]]; then
        if prompt_yesno "Hanya mencocokkan proses kontainer (containers_only)?"; then
            entry="${entry}
      containers_only: true"
        fi
    fi

    # Opsional: sampling
    if prompt_yesno "Konfigurasi sampling Traces (mengurangi volume data)?"; then
        echo -e "    Sampler: always_on, always_off, traceidratio, parentbased_traceidratio"
        local sampler_name sampler_arg
        prompt_input sampler_name "Nama sampler" "traceidratio"
        prompt_input sampler_arg  "Parameter sampling (misalnya 0.5 untuk sampling 50%)" "1.0"
        entry="${entry}
      sampler:
        name: ${sampler_name}
        arg: \"${sampler_arg}\""
    fi

    APP_ENTRIES+=("$entry")
    ok "Aplikasi ditambahkan: ${app_name}"
}

# ========================= Kumpulkan Konfigurasi =========================
collect_config() {
    echo -e "${BOLD}========== Konfigurasi ==========${NC}"
    echo ""
    info "Dapatkan informasi berikut dari halaman Pusat Integrasi ARMS:"
    info "  Konsol ARMS -> Pusat Integrasi -> Kartu OpenTelemetry -> Dapatkan LicenseKey"
    echo ""

    prompt_input OTLP_ENDPOINT "OTEL_EXPORTER_OTLP_ENDPOINT (misalnya http://xxx:4318)"
    prompt_input OTLP_HEADERS  "OTEL_EXPORTER_OTLP_HEADERS  (misalnya Authentication=xxx)"

    echo ""
    echo -e "${BOLD}========== Konfigurasi Aplikasi ==========${NC}"

    # Mode non-interaktif: buat satu aplikasi dari variabel lingkungan
    if [[ -n "${APP_MATCH_TYPE:-}" ]]; then
        local entry="    - name: ${APP_NAME:-my-app}"
        case "$APP_MATCH_TYPE" in
            port)
                entry="${entry}
      open_ports: ${APP_MATCH_VALUE:-8080}" ;;
            cmd)
                entry="${entry}
      exe_path: \"${APP_EXE_PATH:-*/java}\"
      cmd_args: \"${APP_CMD_ARGS}\"" ;;
            exe)
                entry="${entry}
      exe_path: \"${APP_MATCH_VALUE}\"" ;;
            lang)
                entry="${entry}
      languages: \"${APP_MATCH_VALUE}\"" ;;
            container)
                entry="${entry}
      container_name: \"${APP_MATCH_VALUE}\"" ;;
            pid)
                local pid_array
                pid_array=$(echo "${APP_MATCH_VALUE}" | tr ',' '\n' | sed 's/^[[:space:]]*//' | awk '{printf "      - %s\n", $0}')
                entry="${entry}
      target_pids:
${pid_array}" ;;
            *)
                die "APP_MATCH_TYPE tidak dikenal: ${APP_MATCH_TYPE} (didukung: port|cmd|exe|lang|container|pid)" ;;
        esac
        APP_ENTRIES+=("$entry")
        ok "Aplikasi ditambahkan: ${APP_NAME:-my-app} (${APP_MATCH_TYPE})"
        return
    fi

    # Mode interaktif: loop untuk menambahkan aplikasi
    while true; do
        echo ""
        collect_one_app
        echo ""
        if ! prompt_yesno "Lanjutkan menambahkan aplikasi lain?"; then
            break
        fi
    done

    # Opsional: aturan eksklusi
    echo ""
    if prompt_yesno "Konfigurasi aturan eksklusi (exclude_instrument)?"; then
        echo -e "    Masukkan glob path executable untuk dikecualikan"
        echo -e "    Contoh: {obi,prometheus,otelcol*,node_exporter}"
        local exclude_val
        prompt_input exclude_val "Glob path eksklusi"
        EXCLUDE_PATTERN="$exclude_val"
        ok "Aturan eksklusi ditambahkan: ${exclude_val}"
    fi
}

# ========================= Hasilkan File Konfigurasi =========================
generate_config() {
    local endpoint_metrics="${OTLP_ENDPOINT}/v1/metrics"

    # Bangun bagian instrument
    local instrument_yaml=""
    for entry in "${APP_ENTRIES[@]}"; do
        instrument_yaml="${instrument_yaml}
${entry}"
    done

    # Bangun bagian exclude
    local exclude_yaml=""
    if [[ -n "$EXCLUDE_PATTERN" ]]; then
        exclude_yaml="
  exclude_instrument:
    - exe_path: \"${EXCLUDE_PATTERN}\""
    fi

    cat > "${CONFIG_FILE}" <<YAML
# File Konfigurasi OBI - Dihasilkan otomatis oleh obi-setup.sh
# Dihasilkan pada: $(date '+%Y-%m-%d %H:%M:%S')

log_level: WARN

# ========== Ekspor Metrics ==========
otel_metrics_export:
  endpoint: ${endpoint_metrics}

metrics:
  features:
    - application
    - network
    - stats_tcp_rtt

routes:
  nmatched: low-cardinality
  max_path_segment_cardinality: 500

# ========== Konfigurasi Probe eBPF ==========
ebpf:
  context_propagation: all
  track_request_headers: true
  payload_extraction:
    http:
      genai:
        openai:
          enabled: true
        anthropic:
          enabled: true
        jsonrpc:
          enabled: true
        mcp:
          enabled: true
        qwen:
          enabled: true
        rerank:
          enabled: true
        embedding:
          enabled: true
        gemini:
          enabled: true
        rerank:
          enabled: true          
  buffer_sizes:
    http: 262144

# ========== Ekspor Traces ==========
otel_traces_export:
  endpoint: ${OTLP_ENDPOINT}
  batch_timeout: 10s
  batch_max_size: 512
  queue_size: 4096
  backoff_initial_interval: 5s
  backoff_max_interval: 15s
  backoff_max_elapsed_time: 2m  
  instrumentations:
    - http
    - grpc
    - sql
    - redis
    - kafka
    - mqtt
    - mongo
    - couchbase
    - memcached
    - genai

nodejs
  enabled: true

discovery:
  min_process_age: 30s  

# ========== Aturan Penemuan Aplikasi ==========
discovery:
  instrument:${instrument_yaml}${exclude_yaml}
YAML

    ok "File konfigurasi dihasilkan: ${CONFIG_FILE}"
}

# ========================= Unduh OBI =========================
download_obi() {
    local arch
    arch=$(detect_arch)
    local url="${OSS_BASE}/obi-linux-${arch}"

    info "Mengunduh OBI v${VERSION} (${arch})..."
    mkdir -p "${INSTALL_DIR}"

    if command -v wget &>/dev/null; then
        wget -q --show-progress "${url}" -O "${OBI_BINARY}"
    elif command -v curl &>/dev/null; then
        curl -fL --progress-bar "${url}" -o "${OBI_BINARY}"
    else
        die "Baik wget maupun curl tidak tersedia"
    fi

    chmod +x "${OBI_BINARY}"
    ok "OBI diunduh ke ${OBI_BINARY}"
}

# ========================= Layanan Systemd =========================
install_systemd() {
    info "Membuat layanan systemd..."

    cat > "/etc/systemd/system/${SERVICE_NAME}.service" <<EOF
[Unit]
Description=OBI eBPF Instrumentation Service
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=root
WorkingDirectory=${INSTALL_DIR}
Environment="OTEL_EBPF_CONFIG_PATH=${CONFIG_FILE}"
Environment="OTEL_EXPORTER_OTLP_HEADERS=${OTLP_HEADERS}"
ExecStart=${OBI_BINARY}
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=${SERVICE_NAME}

[Install]
WantedBy=multi-user.target
EOF

    systemctl daemon-reload
    systemctl enable "${SERVICE_NAME}" --quiet
    ok "Layanan systemd dibuat dan diaktifkan untuk auto-start"
}

start_service() {
    info "Memulai layanan OBI..."
    systemctl start "${SERVICE_NAME}"
    sleep 2

    if systemctl is-active --quiet "${SERVICE_NAME}"; then
        ok "Layanan OBI berhasil dimulai!"
    else
        fail "Layanan OBI gagal dimulai. Log kesalahan:"
        journalctl -u "${SERVICE_NAME}" -n 30 --no-pager
        exit 1
    fi
}

# ========================= Penerapan Docker =========================
deploy_docker() {
    if ! command -v docker &>/dev/null; then
        die "Docker belum diinstal"
    fi

    collect_config
    mkdir -p "${INSTALL_DIR}"
    generate_config

    info "Menarik image Docker: ${DOCKER_IMAGE}"
    docker pull "${DOCKER_IMAGE}"

    if docker ps -a --format '{{.Names}}' | grep -q "^${SERVICE_NAME}$"; then
        warn "Menghapus kontainer yang ada..."
        docker rm -f "${SERVICE_NAME}" >/dev/null 2>&1
    fi

    info "Memulai kontainer OBI..."
    docker run -d \
        --name "${SERVICE_NAME}" \
        --pid=host \
        --privileged \
        --restart=always \
        -v "${CONFIG_FILE}:/config/config.yaml:ro" \
        -e "OTEL_EXPORTER_OTLP_HEADERS=${OTLP_HEADERS}" \
        -e "OTEL_EXPORTER_OTLP_ENDPOINT=${OTLP_ENDPOINT}" \
        "${DOCKER_IMAGE}" \
        --config=/config/config.yaml

    sleep 2
    if docker ps --format '{{.Names}}' | grep -q "^${SERVICE_NAME}$"; then
        ok "Kontainer OBI berhasil dimulai!"
    else
        fail "Kontainer gagal dimulai:"
        docker logs "${SERVICE_NAME}" --tail 30
        exit 1
    fi

    echo ""
    echo -e "${BOLD}Perintah manajemen Docker:${NC}"
    echo "  Lihat log:      docker logs -f ${SERVICE_NAME}"
    echo "  Hentikan kontainer: docker stop ${SERVICE_NAME}"
    echo "  Hapus kontainer: docker rm -f ${SERVICE_NAME}"
    echo ""
}

# ========================= Uninstal =========================
uninstall() {
    echo -e "${BOLD}========== Uninstal OBI ==========${NC}

    if systemctl is-active --quiet "${SERVICE_NAME}" 2>/dev/null; then
        systemctl stop "${SERVICE_NAME}"
    fi
    if [[ -f "/etc/systemd/system/${SERVICE_NAME}.service" ]]; then
        systemctl disable "${SERVICE_NAME}" --quiet 2>/dev/null || true
        rm -f "/etc/systemd/system/${SERVICE_NAME}.service"
        systemctl daemon-reload
        ok "Layanan systemd dihapus"
    fi

    if command -v docker &>/dev/null && docker ps -a --format '{{.Names}}' | grep -q "^${SERVICE_NAME}$"; then
        docker rm -f "${SERVICE_NAME}" >/dev/null 2>&1
        ok "Kontainer Docker dihapus"
    fi

    if [[ -d "${INSTALL_DIR}" ]]; then
        rm -rf "${INSTALL_DIR}"
        ok "Direktori instalasi dibersihkan"
    fi

    ok "OBI telah sepenuhnya diuninstal"
}

# ========================= Pemeriksaan Status =========================
show_status() {
    echo -e "${BOLD}========== Status Berjalan OBI ==========${NC}

    if [[ -f "/etc/systemd/system/${SERVICE_NAME}.service" ]]; then
        echo -e "\n${CYAN}[Layanan Systemd]${NC}
        systemctl status "${SERVICE_NAME}" --no-pager 2>/dev/null || true
        echo -e "\n${CYAN}[Log Terbaru]${NC}
        journalctl -u "${SERVICE_NAME}" -n 20 --no-pager 2>/dev/null || true
    fi

    if command -v docker &>/dev/null && docker ps -a --format '{{.Names}}' | grep -q "^${SERVICE_NAME}$"; then
        echo -e "\n${CYAN}[Kontainer Docker]${NC}
        docker ps -f "name=${SERVICE_NAME}"
        echo -e "\n${CYAN}[Log Terbaru]${NC}
        docker logs "${SERVICE_NAME}" --tail 20 2>&1 || true
    fi

    if [[ -f "${CONFIG_FILE}" ]]; then
        echo -e "\n${CYAN}[File Konfigurasi: ${CONFIG_FILE}]${NC}
        cat "${CONFIG_FILE}"
    fi
}

# ========================= Alur Utama Instalasi Binary =========================
install_binary() {
    check_env || die "Pemeriksaan lingkungan gagal"
    collect_config
    download_obi
    generate_config
    install_systemd
    start_service

    echo ""
    echo -e "${GREEN}============================================${NC}
    echo -e "${GREEN}  Penerapan OBI Selesai!${NC}
    echo -e "${GREEN}============================================${NC}
    echo ""
    echo -e "${BOLD}Direktori instalasi:${NC}  ${INSTALL_DIR}"
    echo -e "${BOLD}File konfigurasi:${NC}     ${CONFIG_FILE}"
    echo ""
    echo -e "Perintah umum:"
    echo "  Lihat status:    sudo systemctl status ${SERVICE_NAME}"
    echo "  Lihat log:       sudo journalctl -u ${SERVICE_NAME} -f"
    echo "  Restart layanan: sudo systemctl restart ${SERVICE_NAME}"
    echo "  Uninstal:        sudo bash $0 uninstall"
    echo ""
}

# ========================= Titik Masuk =========================
print_usage() {
    echo ""
    echo -e "${BOLD}Skrip Penerapan Satu Klik OBI v${VERSION}${NC}
    echo ""
    echo "Penggunaan: sudo bash $0 <perintah>"
    echo ""
    echo "Perintah:"
    echo "  install    Instal menggunakan binary (dikelola oleh systemd)"
    echo "  docker     Terapkan menggunakan Docker"
    echo "  check      Jalankan hanya pemeriksaan lingkungan"
    echo "  status     Lihat status berjalan dan log"
    echo "  uninstall  Uninstal OBI"
    echo ""
    echo "Tipe pencocokan aplikasi (APP_MATCH_TYPE):"
    echo "  port       Pencocokan nomor port (open_ports)"
    echo "  cmd        Pencocokan baris perintah (exe_path + cmd_args)"
    echo "  exe        Pencocokan path executable (exe_path)"
    echo "  lang       Penemuan otomatis bahasa (languages)"
    echo "  container  Pencocokan nama kontainer Docker (container_name)"
    echo "  pid        Penentuan PID (target_pids)"
    echo ""
}

main() {
    local action="${1:-}"
    case "$action" in
        install)   check_root "$@"; install_binary ;;
        docker)    check_root "$@"; check_env || die "Pemeriksaan lingkungan gagal"; deploy_docker ;;
        check)     check_root "$@"; check_env ;;
        uninstall) check_root "$@"; uninstall ;;
        status)    check_root "$@"; show_status ;;
        *)         print_usage; exit 1 ;;
    esac
}

main "$@"

Langkah 1: Dapatkan informasi endpoint

Login ke Konsol ARMS. Di panel navigasi kiri, klik Pusat Integrasi. Di bagian aplikasi sisi server, klik kartu OpenTelemetry dan dapatkan dua nilai berikut:

  • OTEL_EXPORTER_OTLP_ENDPOINT (misalnya, http://xxx:4318)

  • OTEL_EXPORTER_OTLP_HEADERS (misalnya, Authentication=xxx)

Langkah 2: Unduh dan siapkan skrip

chmod +x obi-setup.sh

Langkah 3: Instalasi interaktif (binary + systemd)

sudo bash obi-setup.sh install

Skrip secara berurutan melakukan langkah-langkah berikut: pemeriksaan lingkungan > pengumpulan endpoint/header > pemilihan metode pencocokan aplikasi (6 skenario didukung) > dukungan penambahan beberapa aplikasi > opsi konfigurasi aturan eksklusi/sampling/kontrol ekspor > deteksi otomatis arsitektur CPU dan pengunduhan OBI > pembuatan config.yaml > pembuatan layanan systemd dan pengaktifannya.

Langkah 4: Penerapan Docker

sudo bash obi-setup.sh docker

Langkah 5: Penerapan non-interaktif (skenario batch)

Teruskan parameter melalui variabel lingkungan untuk melewati prompt interaktif. Tipe pencocokan berikut didukung:

# Pencocokan berdasarkan port
export OTLP_ENDPOINT="http://xxx:4318"
export OTLP_HEADERS="Authentication=xxx"
export APP_NAME="my-app"
export APP_MATCH_TYPE="port"
export APP_MATCH_VALUE="8080"
sudo -E bash obi-setup.sh install

# Aplikasi Java (exe_path + cmd_args)
export APP_MATCH_TYPE="cmd"
export APP_EXE_PATH="*/java"
export APP_CMD_ARGS="*petclinic*"

# Pencocokan berdasarkan bahasa pemrograman
export APP_MATCH_TYPE="lang"
export APP_MATCH_VALUE="java"

# Pencocokan berdasarkan path file executable
export APP_MATCH_TYPE="exe"
export APP_MATCH_VALUE="*/my-server"

# Pencocokan berdasarkan nama kontainer Docker
export APP_MATCH_TYPE="container"
export APP_MATCH_VALUE="my-container-*"

# Pencocokan berdasarkan PID
export APP_MATCH_TYPE="pid"
export APP_MATCH_VALUE="12345,67890"

Langkah 6: Perintah lainnya

sudo bash obi-setup.sh check      # Jalankan hanya pemeriksaan lingkungan
sudo bash obi-setup.sh status     # Lihat status berjalan dan log
sudo bash obi-setup.sh uninstall  # Uninstal OBI

Metode 2: Penerapan manual langkah demi langkah

Jika Anda memerlukan kontrol lebih detail atas setiap langkah, ikuti langkah-langkah manual berikut.

Langkah 1: Dapatkan informasi endpoint

Sama seperti di atas. Dapatkan OTEL_EXPORTER_OTLP_ENDPOINT dan OTEL_EXPORTER_OTLP_HEADERS dari Konsol ARMS.

Langkah 2: Unduh OBI

# Arsitektur amd64
wget https://arms-apm-cn-hangzhou-pre.oss-cn-hangzhou.aliyuncs.com/obi-agent/0.10.0/obi-linux-amd64 -O obi

# Arsitektur arm64
wget https://arms-apm-cn-hangzhou-pre.oss-cn-hangzhou.aliyuncs.com/obi-agent/0.10.0/obi-linux-arm64 -O obi

chmod +x obi

Langkah 3: Buat file konfigurasi

Buat file config.yaml. Ganti <OTLP_ENDPOINT> dengan nilai aktual dan sesuaikan bagian discovery.instrument berdasarkan aplikasi Anda (lihat bagian "Metode pencocokan penemuan aplikasi" di atas untuk konfigurasi yang sesuai):

log_level: WARN

otel_metrics_export:
  endpoint: <OTLP_ENDPOINT>/v1/metrics

metrics:
  features:
    - application
    - network
    - stats_tcp_rtt

routes:
  nmatched: low-cardinality
  max_path_segment_cardinality: 500

ebpf:
  context_propagation: all
  track_request_headers: true
  payload_extraction:
    http:
      genai:
        openai:
          enabled: true
        anthropic:
          enabled: true
        jsonrpc:
          enabled: true
        mcp:
          enabled: true
        qwen:
          enabled: true
        rerank:
          enabled: true
        embedding:
          enabled: true
        gemini:
          enabled: true
        rerank:
          enabled: true
  buffer_sizes:
    http: 262144

otel_traces_export:
  endpoint: <OTLP_ENDPOINT>
  instrumentations:
    - http
    - grpc
    - sql
    - redis
    - kafka
    - mqtt
    - mongo
    - couchbase
    - memcached
    - genai

nodejs:
  enabled: true

discovery:
  instrument:
    # Pilih metode pencocokan berdasarkan skenario Anda. Lihat bagian "Metode pencocokan penemuan aplikasi".
    - name: my-app
      open_ports: 8080

Langkah 4: Terapkan layanan

Penerapan binary (dikelola oleh systemd):

Buat file layanan systemd /etc/systemd/system/obi.service:

[Unit]
Description=OBI eBPF Instrumentation Service
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=root
WorkingDirectory=/path/to/obi-dir
Environment="OTEL_EBPF_CONFIG_PATH=config.yaml"
Environment="OTEL_EXPORTER_OTLP_HEADERS=<Ganti dengan nilai aktual>"
ExecStart=/path/to/obi-dir/obi
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
SyslogIdentifier=obi

[Install]
WantedBy=multi-user.target

Mulai layanan:

sudo systemctl daemon-reload
sudo systemctl enable obi
sudo systemctl start obi
sudo systemctl status obi

Penerapan Docker:

docker pull registry.cn-hangzhou.aliyuncs.com/private-mesh/obi:0.10.0

docker run -d \
  --name obi \
  --pid=host \
  --privileged \
  --restart=always \
  -v $(pwd)/config.yaml:/config/config.yaml:ro \
  -e OTEL_EXPORTER_OTLP_HEADERS="<Ganti dengan nilai aktual>" \
  -e OTEL_EXPORTER_OTLP_ENDPOINT="<Ganti dengan nilai aktual>" \
  registry.cn-hangzhou.aliyuncs.com/private-mesh/obi:0.10.0 \
  --config=/config/config.yaml

Verifikasi data pemantauan

Masuk ke Konsol ARMS. Di panel navigasi sebelah kiri, klik Application Monitoring. Temukan nama aplikasi yang telah Anda konfigurasikan dalam daftar aplikasi, lalu klik nama tersebut untuk melihat detail pemantauan, seperti topologi, jejak, dan anomali.

Perintah O&M umum

Operasi

Metode systemd

Metode Docker

Lihat status

sudo systemctl status obi

docker ps -f name=obi

Lihat log

sudo journalctl -u obi -f

docker logs -f obi

Restart

sudo systemctl restart obi

docker restart obi

Hentikan

sudo systemctl stop obi

docker stop obi

Uninstal

sudo bash obi-setup.sh uninstall

docker rm -f obi