Skip to content

Prometheus:client golang

Prometheus instrumentation library for Go applications

Examples

go get github.com/prometheus/client_golang/prometheus
go get github.com/prometheus/client_golang/prometheus/promhttp

Main 코드:

package main

import (
    "log"
    "net/http"
    "time"

    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promauto"
    "github.com/prometheus/client_golang/prometheus/promhttp"
)

var (
    // Counter: 계속 증가하는 메트릭 (요청 수, 에러 수 등)
    // Counter: continuously increasing metric (request count, error count, etc.)
    requestsTotal = promauto.NewCounterVec(
        prometheus.CounterOpts{
            Name: "myapp_requests_total",
            Help: "Total number of requests",
        },
        []string{"method", "endpoint"},
    )

    // Gauge: 증가/감소 가능한 메트릭 (메모리 사용량, 동시 접속자 등)
    // Gauge: metric that can increase/decrease (memory usage, concurrent users, etc.)
    activeConnections = promauto.NewGauge(prometheus.GaugeOpts{
        Name: "myapp_active_connections",
        Help: "Number of active connections",
    })

    // Histogram: 값의 분포를 측정 (응답 시간, 요청 크기 등)
    // Histogram: measures distribution of values (response time, request size, etc.)
    requestDuration = promauto.NewHistogramVec(
        prometheus.HistogramOpts{
            Name:    "myapp_request_duration_seconds",
            Help:    "Request duration in seconds",
            Buckets: prometheus.DefBuckets,
        },
        []string{"endpoint"},
    )
)

func main() {
    // 메트릭 기록 예제
    // Example of recording metrics
    go func() {
        for {
            requestsTotal.WithLabelValues("GET", "/api/users").Inc()
            activeConnections.Set(42)
            requestDuration.WithLabelValues("/api/users").Observe(0.123)
            time.Sleep(5 * time.Second)
        }
    }()

    // /metrics 엔드포인트 등록
    // Register /metrics endpoint
    http.Handle("/metrics", promhttp.Handler())

    log.Println("Starting server on :8080")
    log.Fatal(http.ListenAndServe(":8080", nil))
}

v1 API Interface

// API provides bindings for Prometheus's v1 API.
type API interface {
    // Alerts returns a list of all active alerts.
    Alerts(ctx context.Context) (AlertsResult, error)
    // AlertManagers returns an overview of the current state of the Prometheus alert manager discovery.
    AlertManagers(ctx context.Context) (AlertManagersResult, error)
    // CleanTombstones removes the deleted data from disk and cleans up the existing tombstones.
    CleanTombstones(ctx context.Context) error
    // Config returns the current Prometheus configuration.
    Config(ctx context.Context) (ConfigResult, error)
    // DeleteSeries deletes data for a selection of series in a time range.
    DeleteSeries(ctx context.Context, matches []string, startTime, endTime time.Time) error
    // Flags returns the flag values that Prometheus was launched with.
    Flags(ctx context.Context) (FlagsResult, error)
    // LabelNames returns the unique label names present in the block in sorted order by given time range and matchers.
    LabelNames(ctx context.Context, matches []string, startTime, endTime time.Time, opts ...Option) ([]string, Warnings, error)
    // LabelValues performs a query for the values of the given label, time range and matchers.
    LabelValues(ctx context.Context, label string, matches []string, startTime, endTime time.Time, opts ...Option) (model.LabelValues, Warnings, error)
    // Query performs a query for the given time.
    Query(ctx context.Context, query string, ts time.Time, opts ...Option) (model.Value, Warnings, error)
    // QueryRange performs a query for the given range.
    QueryRange(ctx context.Context, query string, r Range, opts ...Option) (model.Value, Warnings, error)
    // QueryExemplars performs a query for exemplars by the given query and time range.
    QueryExemplars(ctx context.Context, query string, startTime, endTime time.Time) ([]ExemplarQueryResult, error)
    // Buildinfo returns various build information properties about the Prometheus server
    Buildinfo(ctx context.Context) (BuildinfoResult, error)
    // Runtimeinfo returns the various runtime information properties about the Prometheus server.
    Runtimeinfo(ctx context.Context) (RuntimeinfoResult, error)
    // Series finds series by label matchers.
    Series(ctx context.Context, matches []string, startTime, endTime time.Time, opts ...Option) ([]model.LabelSet, Warnings, error)
    // Snapshot creates a snapshot of all current data into snapshots/<datetime>-<rand>
    // under the TSDB's data directory and returns the directory as response.
    Snapshot(ctx context.Context, skipHead bool) (SnapshotResult, error)
    // Rules returns a list of alerting and recording rules that are currently loaded.
    Rules(ctx context.Context) (RulesResult, error)
    // Targets returns an overview of the current state of the Prometheus target discovery.
    Targets(ctx context.Context) (TargetsResult, error)
    // TargetsMetadata returns metadata about metrics currently scraped by the target.
    TargetsMetadata(ctx context.Context, matchTarget, metric, limit string) ([]MetricMetadata, error)
    // Metadata returns metadata about metrics currently scraped by the metric name.
    Metadata(ctx context.Context, metric, limit string) (map[string][]Metadata, error)
    // TSDB returns the cardinality statistics.
    TSDB(ctx context.Context, opts ...Option) (TSDBResult, error)
    // WalReplay returns the current replay status of the wal.
    WalReplay(ctx context.Context) (WalReplayStatus, error)
}

v1 Client Wrapper

package lib

import (
    "context"
    "fmt"
    "strconv"
    "time"

    "github.com/prometheus/client_golang/api"
    "github.com/prometheus/client_golang/api/prometheus/v1"
    "github.com/prometheus/common/model"
)

type PrometheusClient struct {
    client v1.API
}

func NewPrometheusClient(prometheusURL string) (*PrometheusClient, error) {
    client, err := api.NewClient(api.Config{Address: prometheusURL})
    if err != nil {
        return nil, fmt.Errorf("failed to create prometheus client: %w", err)
    }
    return &PrometheusClient{client: v1.NewAPI(client)}, nil
}

func (c *PrometheusClient) IsHealthy(ctx context.Context) bool {
    // Check if Prometheus is accessible and basic query works
    _, _, err := c.client.Query(ctx, "up", time.Now())
    return err == nil
}

목록 클리어하기

# HELP system_process_cpu_percent Process CPU usage percentage
# TYPE system_process_cpu_percent gauge
system_process_cpu_percent{name="bash",pid="547435"} 0.08847452218410178
system_process_cpu_percent{name="beam.smp",pid="803"} 0.190656949684157
system_process_cpu_percent{name="containerd",pid="809"} 0.08934410736701123
system_process_cpu_percent{name="docker-proxy",pid="524417"} 0.1208477126288767
...

이런식으로 현재 실행중인 프로세스 목록 출력할 때 목록이 안지워지고 계속 쌓일 때, 최신 목록만 유지하는 방법:

// 프로세스 메트릭 / Process metrics
processCPUUsage = prometheus.NewGaugeVec(prometheus.GaugeOpts{
    Name: "system_process_cpu_percent",
    Help: "Process CPU usage percentage",
}, []string{"pid", "name"})
processMemoryUsage = prometheus.NewGaugeVec(prometheus.GaugeOpts{
    Name: "system_process_memory_percent",
    Help: "Process memory usage percentage",
}, []string{"pid", "name"})
gpuProcessMemory = prometheus.NewGaugeVec(prometheus.GaugeOpts{
    Name: "gpu_process_memory_mb",
    Help: "GPU memory used by process",
}, []string{"gpu_id", "gpu_name", "pid", "process_name"})

// 기존 프로세스 메트릭 초기화
processCPUUsage.Reset()
processMemoryUsage.Reset()
gpuProcessMemory.Reset()

processCPUUsage.WithLabelValues(strconv.Itoa(int(proc.pid)), proc.name).Set(proc.cpuPercent)
processMemoryUsage.WithLabelValues(strconv.Itoa(int(proc.pid)), proc.name).Set(float64(proc.memPercent))
gpuProcessMemory.WithLabelValues(gpuID, gpuName, strconv.Itoa(proc.PID), proc.ProcessName).Set(procMemory)

GaugeVec 같은 클래스의 Reset()을 호출하자.

See also

Favorite site