본문 바로가기
golang

[TIL] golang promauto metric register시 panic

by marble25 2023. 12. 21.

golang에서 prometheus metric을 등록할 때 ‘-’가 들어가면 panic이 나는 경우가 있었다. 물론 ‘-’를 ‘_’로 바꿔주면 되는 이슈였지만, 애초에 prometheus metric을 logging하지 못한다고 panic이 나는게 이상하다. panic이 아니라 error를 리턴하여 에러 핸들링 로직으로 처리할 수 있어야 한다.

AS-IS

prometheus의 promauto package를 사용해서 gauge를 만들어 주고 있었다.

newGauge := promauto.NewGauge(
	prometheus.GaugeOpts{
		Namespace:   PrometheusNameSpace,
		Name:        metricName,
		Help:        "Metric for " + metricName + ".",
		ConstLabels: labels,
	},
)

찾아보니 promauto 패키지는 prometheus의 MustRegister function을 사용한다고 한다. 즉, error를 리턴하지 않고 실패시 panic한다는 것이다.

이 때문에 metricName을 동적으로 생성해주는 로직 특성상 metricName에 ‘-’가 들어가면 안된다. metric 이름은 다음 regex를 따른다: [a-zA-Z_:][a-zA-Z0-9_:]*. 만약 이 regex에 맞지 않는 이름이 들어가면 panic한다.

prometheus에서는 메트릭 및 기타 collector의 생성이 등록과 별도로 이루어진다. 먼저 메트릭을 생성한 후 local / global registry에 등록할지, 오류를 처리할지를 명시적으로 결정할 수 있다. 다만 promauto 패키지는 등록이 자동으로 수행되고 실패하면 항상 panic이 발생한다.

registry 생성 등의 과정 없이 간단하게 시작할 수 있지만 어떤 큰 장점이 있는지 모르겠다. Panic보다는 error handling으로 내가 control하는게 나은 것 같다. 특히, metric name을 initialize할 때 모두 등록하는 static한 방법이 아니라, 사용자 입력에 따라 변경될 수 있는 값이기 때문에 더더욱 error handling으로 변경할 필요를 느꼈다.

TO-BE

pm.Registry := prometheus.NewRegistry()

newGauge := prometheus.NewGauge(
	prometheus.GaugeOpts{
		Namespace:   PrometheusNameSpace,
		Name:        metricName,
		Help:        "Metric for " + metricName + ".",
		ConstLabels: labels,
	},
)

err := pm.Registry.Register(newGauge)
if err != nil {
	return fmt.Errorf("fail to add metrics [name : %s] (pm): %w", metricName, err)
}

register를 명시적으로 해주고, error가 발생한 경우 error를 리턴하도록 변경했다. 이 과정을 통해 적어도 잘못된 metricName으로 패닉이 나지는 않고 error가 나도록 바꿀 수 있었다.

'golang' 카테고리의 다른 글

[TIL] golang http server에 timeout handler 추가하기  (0) 2023.12.25
[TIL] golang buffer 복사  (1) 2023.12.21
Go google style guides - decisions  (0) 2023.12.09
Go google style guide - overview & guide  (1) 2023.11.19
Go garbage collection  (1) 2023.10.30