Aggregation을 수행할 때 사용할 데이터

terms

terms는 데이터의 keyword별 종류 및 개수를 집계하는데 사용합니다.

 

모든 도큐먼트의 level의 종류와 개수 구하기

우리는 데이터를 가져오는 것이 목적이 아닌 Aggregation을 수행하는 것이 목적이기 때문에 "size"를 0으로 설정하였습니다.

level 필드의 데이터 종류와 각 종류별로 도큐먼트가 몇개 있는지 확인합니다.

api POST http://localhost:9200/test-log-index-2021-09-12/_search
header content-type: application/json
body {
    "size": 0,
    "query": {
        "match_all": {}
    },
    "aggs": {
        "byLevel": {
            "terms": {
                "field": "level"
            }
        }
    }
}

결과 보기

"byLevel" 내부의 buckets를 보면 "key"에는 level필드의 값이 "doc_count"에는 개수를 표현하고 있습니다.

즉 "info"는 9개가 있고, "warn"은 6개, "debug"는 5개가 있는 것을 확인할 수 있습니다.

 

range

값의 범위 별로 도큐먼트의 개수를 측정하는데 사용할 수 있습니다.

 

모든 도큐먼트의 duration의 범위별 개수 측정하기

우리는 데이터를 가져오는 것이 목적이 아닌 Aggregations을 수행하는 것이 목적이기 때문에 "size"를 0으로 설정하였습니다.

duration의 범위 100이하, 100부터 200까지, 200부터 300까지, 300부터 400까지, 400이상 으로 범위를 지정하여 검색하겠습니다.

api POST http://localhost:9200/test-log-index-2021-09-12/_search
header content-type: application/json
body {
    "size": 0,
    "query": {
        "match_all": {}
    },
    "aggs": {
        "byDuration": {
            "range": {
                "field": "duration",
                "ranges": [
                    {
                        "to": 100
                    },
                    {
                        "from": 100,
                        "to": 200
                    },
                    {
                        "from": 200,
                        "to": 300
                    },
                    {
                        "from": 300,
                        "to": 400
                    },
                    {
                        "from": 400
                    }
                ]
            }
        }
    }
}

결과 보기

 

histogram

range의 경우 from, to를 통하여 범위를 지정했다면 histogram은 range와 다르게 interval옵션을 통하여 interval단위 별로 필드의 개수를 측정하는 Aggregations입니다.

 

모든 도큐먼트의 duration을 100 단위로 개수 측정하기

우리는 데이터를 가져오는 것이 목적이 아닌 Aggregations을 수행하는 것이 목적이기 때문에 "size"를 0으로 설정하였습니다.

api POST http://localhost:9200/test-log-index-2021-09-12/_search
header content-type: application/json
body {
    "size": 0,
    "query": {
        "match_all": {}
    },
    "aggs": {
        "byDuration": {
            "histogram": {
                "field": "duration",
                "interval": 100
            }
        }
    }
}

결과 보기

100 단위 별로 도큐먼트의 개수를 확인할 수 있습니다.

 

date_range

range처럼 date필드 또한 범위를 지정하여 집계를 할 수 있습니다.

 

모든 도큐먼트의 start_time 필드를 범위 별로 측정하기

우리는 데이터를 가져오는 것이 목적이 아닌 Aggregations을 수행하는 것이 목적이기 때문에 "size"를 0으로 설정하였습니다.

"start_time"필드의 값을 범위 별로 측정하도록 하겠습니다.

api POST http://localhost:9200/test-log-index-2021-09-12/_search
header content-type: application/json
body {
    "size": 0,
    "query": {
        "match_all": {}
    },
    "aggs": {
        "date_range": {
            "date_range": {
                "field": "start_time",
                "ranges": [
                    {
                        "from": "2021-09-12 10:10:10",
                        "to": "2021-09-12 10:10:15"
                    },
                    {
                        "from": "2021-09-12 10:10:15",
                        "to": "2021-09-12 10:10:20"
                    },
                    {
                        "from": "2021-09-12 10:10:20"
                    }
                ]
            }
        }
    }
}

결과 보기

각 시간대별로 도큐먼트의 개수를 확인할 수 있습니다.

 

date_histogram

histogram과 같이 date_histogram도 interval 옵션을 넣어 각 interval별 집계를 측정할 수 있습니다.

interval옵션에 second, minute, hour, day, month, week 등을 넣을 수 있습니다.

 

모든 도큐먼트의 start_time 필드를 1분 별로 측정하기

우리는 데이터를 가져오는 것이 목적이 아닌 Aggregations을 수행하는 것이 목적이기 때문에 "size"를 0으로 설정하였습니다.

api POST http://localhost:9200/test-log-index-2021-09-12/_search
header content-type: application/json
body {
    "size": 0,
    "query": {
        "match_all": {}
    },
    "aggs": {
        "date_his": {
            "date_histogram": {
                "field": "start_time",
                "interval": "minute"
            }
        }
    }
}

결과 보기

 

 

 

 

Prometheus Metric Type

Counter 카운터

Counter는 개수를 측정하거나 증가하는 값을 측정할 때 사용합니다. 카운터는 0으로 초기화는 가능하지만 값을 감소할 수 없고 증가만 할 수 있습니다. 대표적으로 함수 호출 횟수 및 접속 요청 수, 실패 개수를 측정할 때 많이 사용할 수 있습니다.

 

Gauge 게이지

Gauge는 현재의 값을 나타내는 데 사용합니다. 값이 증가할 수 있으며 감소할 수도 있습니다. 증가 감소 모두 가능하다 보니 여러 방면에서 사용할 수 있습니다. 대표적으로 현재 메모리 사용량, CPU 사용 시간, 저장된 데이터의 수, 스레드 개수 등 여러 방면에서 사용합니다.

 

Summary 서머리

Summary는 _count, _sum을 제공하여 평균을 측정할 수 있으며, 슬라이딩 시간 윈도우를 측정할 때 사용합니다.

 

Histogram 히스토그램

Histogram은 시간 동안의 값을 측정하고 측정한 값을 통하여 quantile을 측정할 수 있습니다.

 

Go언어로 Metric 생성하기

먼저 다음 명령으로 모듈을 받습니다.

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

 

Counter 생성하기

package main

import (
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promauto"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"net/http"
	"time"
)

var (
	MyCounter prometheus.Counter
)

func Init() {
	MyCounter = promauto.NewCounter(prometheus.CounterOpts{
		Name: "my_test_count",
		Help: "my test count",
	})
}

func RunCounter() {
	for i := 0; ; i++ {
		MyCounter.Inc()
		//MyCounter.Add(10)
		time.Sleep(time.Second * 2)
	}
}

func main() {
	Init()
	go RunCounter()

	http.Handle("/metrics", promhttp.Handler())
	http.ListenAndServe(":30001", nil)
}

코드설명

promauto.NewCounter를 통하여 카운터를 생성하고 카운터의 이름을 my_test_count로 만들었다. 카운터는 2초에 한 번씩 MyCounter.Inc()를 통하여 1씩 증가하고 있다. MyCounter.Add()를 이용하면 1 이상의 값을 증가시킬 수도 있다.

 

확인하기

Gauge 생성하기

package main

import (
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promauto"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"net/http"
	"time"
)

var (
	MyGauge prometheus.Gauge
)

func Init() {
	MyGauge = promauto.NewGauge(prometheus.GaugeOpts{
		Name: "my_test_gauge",
		Help: "my test gauge",
	})
}

func RunGauge() {
	for i := 0; ; i++ {
		MyGauge.Set(float64(i))
		time.Sleep(time.Second * 2)
	}
}

func main() {
	Init()
	go RunGauge()

	http.Handle("/metrics", promhttp.Handler())
	http.ListenAndServe(":30001", nil)
}

코드설명

promauto.NewGauge를 통하여 my_test_gauge를 생성하였습니다. 2초마다 i의 값으로 gauge값을 세팅합니다.

 

 

Summary 생성하기

package main

import (
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promauto"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"math/rand"
	"net/http"
	"time"
)

var (
	MySummary prometheus.Summary
)

func Init() {
	MySummary = promauto.NewSummary(prometheus.SummaryOpts{
		Name: "my_test_summary",
		Help: "my test summary",
	})
}

func RunSummary() {
	for {
		MySummary.Observe(float64(rand.Int63n(10)))
		time.Sleep(time.Second * 2)
	}
}

func main() {
	Init()
	go RunSummary()

	http.Handle("/metrics", promhttp.Handler())
	http.ListenAndServe(":30001", nil)
}

코드설명

promauto.NewSummary를 통하여 my_test_summary를 생성하고 2초마다 0 ~ 10까지의 난수로 Observe를 통하여 값을 등록합니다.

 

확인하기

 

Histogram 생성하기

package main

import (
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promauto"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"math/rand"
	"net/http"
	"time"
)

var (
	MyHistogram prometheus.Histogram
)

func Init() {
	MyHistogram = promauto.NewHistogram(prometheus.HistogramOpts{
		Name: "my_test_histogram",
		Help: "my test histogram",
	})
}

func RunHistogram() {
	for {
		MyHistogram.Observe(rand.Float64())
		time.Sleep(time.Second * 2)
	}
}

func main() {
	Init()
	go RunHistogram()

	http.Handle("/metrics", promhttp.Handler())
	http.ListenAndServe(":30001", nil)
}

코드설명

역시나 promauto.NewHistogram을 통해 생성합니다. 2초마다 난수를 등록합니다.

 

확인하기

다른 방식의 Metric 생성

지금까지 promauto를 통하여 Metric을 생성했습니다. 그러나 promauto를 사용하지 않고 다른 방식으로 Metric을 생성하는 방법을 알아보겠습니다.

package main

import (
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"net/http"
	"time"
)

var (
	MyCounter prometheus.Counter
)

func Init() {
	MyCounter = prometheus.NewCounter(prometheus.CounterOpts{
		Name: "my_test_count",
		Help: "my test count",
	})
}

func RunFunc() {
	for {
		MyCounter.Inc()
		time.Sleep(time.Second * 2)
	}
}

func main() {
	Init()
	prometheus.MustRegister(MyCounter)

	go RunFunc()

	http.Handle("/metrics", promhttp.Handler())
	http.ListenAndServe(":30001", nil)
}

코드설명

promauto.NewCounter가 아닌 prometheus.NewCounter를 통하여 Metric을 생성했습니다. promauto를 사용하지 않으면 prometheus.MustRegister를 통하여 Collector를 등록해야 됩니다.

 

 

'Go언어' 카테고리의 다른 글

go work 사용해보기  (0) 2023.07.06
Ubuntu(Linux)에서 Go 재설치  (0) 2022.10.30
Go언어 interface reflect  (0) 2021.08.15
Go언어 Cron  (0) 2021.06.15
Prometheus Go언어 Metric label  (0) 2021.06.14

+ Recent posts