21.6.2.2 Prometheus 연동을 위한 Node.js 익스포터(Metrics Exporter) 변환 전술

21.6.2.2 Prometheus 연동을 위한 Node.js 익스포터(Metrics Exporter) 변환 전술

Admin Space 로 라우터 데몬의 두개골을 열고 curl 한 줄로 세션 바이트(Bytes) 통계값을 뽑아내는 데 성공했다(21.6.2.1장 참조).
그러나 터미널에 쏟아지는 수 천 줄짜리 JSON 껍데기 텍스트를 인간의 눈으로 24시간 감시한다는 것은 정신병이나 다름없는 수동(Manual) 노예 짓이다.
현대 인프라 모니터링의 패권은 중앙 집중형 스크래핑 엔진인 프로메테우스(Prometheus) 가 쥐고 있다. 이 엔진이 Zenoh 라우터의 생체 정보를 15초마다 긁어가게(Scraping) 만들어야 비로소 “인프라 자율 관측(Autonomous Observability)” 이 완성된다.

문제는 프로메테우스는 바보라서 JSON 포맷 따윈 읽을 줄 모른다는 것이다! 오직 metric_name{label="value"} 1234 형태의 딱딱한 평문 징병 포맷(Text-based Format) 만을 씹어 삼킬 수 있다.
본 절에서는 낡은 JSON 을 강제로 뜯어고쳐, 프로메테우스의 입구멍으로 억지로 밀어넣는 Node.js 미들웨어 익스포터(Metrics Exporter) 개조 타격 런북을 갈파한다.

1. 이기종 데이터 규격 통일의 강박

Zenoh REST API 가 내뿜는 거추장스러운 JSON 트리를 프로메테우스 생태계로 동기화시키려면 파이프라인 중간에 가벼운 “통번역사(Exporter/Adapter)” 가 들어가야 한다.
이 통번역사는 1개의 포트(:9090/metrics)를 열어두고 프로메테우스의 간헐적 호출을 기다리는 얇은 Node.js 스크립트다.

// [Node.js: Zenoh Admin Space JSON ➔ Prometheus Text 포맷 정제 공격 무기]
const express = require('express');
const axios = require('axios');
const app = express();

// Zenoh 의 Admin API 주소 (21.6.2.1장 설정값)
const ZENOH_ADMIN_URL = 'http://localhost:8000/@/router/*/session/*/link/*';

app.get('/metrics', async (req, res) => {
    // 1. 데몬한테서 현재 살아있는 모든 소켓 접속자(로봇)들의 정보를 빼앗아온다.
    const response = await axios.get(ZENOH_ADMIN_URL);
    const data = response.data;
    
    let promText = '';
    
    // 2. 이 거추장스러운 JSON 들을 싹 분해해서 프로메테우스가 좋아하는 납작한 문법으로 도축한다.
    for (const item of data) {
        // key를 파싱하여 누가 접속한 세션id 인지 끄집어냄
        const sessionId = extractSessionId(item.key); 
        const rx_bytes = item.value.rx_bytes;
        const tx_bytes = item.value.tx_bytes;
        
        // 3. 프로메테우스 게이지(Gauge) 포맷팅의 정수! 
        promText += `zenoh_link_rx_bytes_total{session="${sessionId}"} ${rx_bytes}\n`;
        promText += `zenoh_link_tx_bytes_total{session="${sessionId}"} ${tx_bytes}\n`;
    }
    
    // 4. Content-Type 을 text/plain 으로 던져서 프로메테우스의 아가리에 욱여넣는다.
    res.set('Content-Type', 'text/plain');
    res.send(promText);
});

app.listen(9090); // 프로메테우스 스크래핑 전용 포트 대기

2. 프로메테우스 타겟 정조준과 시계열 축적 주기성(Periodicity)

통번역사 익스포터(Exporter) 데몬이 :9090 포트로 불침번을 서고 있다면, 아키텍트는 궁극의 감시탑 거인(Prometheus)에게 이 타깃의 모가지를 집어주기만 하면 된다.

# [prometheus.yml 타겟 조준 런북]
scrape_configs:
  - job_name: 'zenoh_mesh_router'
    scrape_interval: 5s # [감시망의 가혹성] 5초마다 무자비하게 익스포터를 털어버려라!
    static_configs:
      - targets: ['localhost:9090']

3. 영구적 축적(Time-Series Store)과 사후 분석의 지배

이 파이프라인(Admin API \rightarrow Node.js Exporter \rightarrow Prometheus)이 안착하는 순간, 단지 “지금 당장 누가 많이 쓰냐” 의 찰나적 관측(Snapshot)은 영구적 시계열(Time-series) 데이터베이스로 응결된다.

“지난주 목요일 새벽 2시, 14번 로봇의 rx_bytes 기울기(Rate)가 갑자기 초당 100MB로 폭증하며 전체 스웜 망의 백프레셔를 역류시킨 범인임을 입증하라!”
이처럼 지나간 과거(Past) 시스템 붕괴의 원흉을 PromQL (rate(zenoh_link_rx_bytes_total[1m])) 함수 하나로 멱살 잡아 끌어올릴 수 있는 압도적 사후 증명을 쟁취해 낸 것이다.
데몬의 탯줄(Admin)을 끊고 생체 정보를 규격화시켜(Prometheus Format) 인프라 데이터 저장소의 먹이로 상납하는 행위. 이것이 분산 시스템이 폐쇄성을 극복하고 엔터프라이즈 모니터링 이데올로기로 복속되는 가장 강력하고 필수적인 아키텍처 개종 의식(Ritual)이다.