add Dockerfile
parent
f836ae401b
commit
391f703dec
|
|
@ -0,0 +1,7 @@
|
||||||
|
.devcontainer/
|
||||||
|
tests/
|
||||||
|
*.md
|
||||||
|
Dockerfile
|
||||||
|
.dockerignore
|
||||||
|
.gitignore
|
||||||
|
.git
|
||||||
|
|
@ -1,2 +1 @@
|
||||||
.devcontainer/
|
.devcontainer/
|
||||||
tmp/
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
FROM golang:1.23.5 as builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY go.mod go.sum ./
|
||||||
|
|
||||||
|
RUN go mod download
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
RUN go build -o /app/main ./cmd
|
||||||
|
|
||||||
|
FROM golang:1.23.5-alpine
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY --from=builder /app/main .
|
||||||
|
|
||||||
|
EXPOSE 9101
|
||||||
|
|
||||||
|
CMD ["./main"]
|
||||||
181
cmd/main.go
181
cmd/main.go
|
|
@ -1,195 +1,22 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"exporter/internal/app"
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Создаём кастомный реестр
|
|
||||||
var customRegistry = prometheus.NewRegistry()
|
|
||||||
|
|
||||||
// Структура JSON
|
|
||||||
type MetricRequest struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
URL string `json:"url"`
|
|
||||||
Method string `json:"method"`
|
|
||||||
Type string `json:"type"`
|
|
||||||
Metrics map[string]float64 `json:"metrics"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Экспортёр метрик
|
|
||||||
type MetricsExporter struct {
|
|
||||||
gaugeMetrics map[string]*prometheus.GaugeVec
|
|
||||||
counterMetrics map[string]*prometheus.CounterVec
|
|
||||||
histogramMetrics map[string]*prometheus.HistogramVec
|
|
||||||
summaryMetrics map[string]*prometheus.SummaryVec
|
|
||||||
mu sync.Mutex // Защита от одновременного доступа
|
|
||||||
}
|
|
||||||
|
|
||||||
// Создаём новый экспортёр
|
|
||||||
func NewMetricsExporter() *MetricsExporter {
|
|
||||||
return &MetricsExporter{
|
|
||||||
gaugeMetrics: make(map[string]*prometheus.GaugeVec),
|
|
||||||
counterMetrics: make(map[string]*prometheus.CounterVec),
|
|
||||||
histogramMetrics: make(map[string]*prometheus.HistogramVec),
|
|
||||||
summaryMetrics: make(map[string]*prometheus.SummaryVec),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обновление или создание метрики
|
|
||||||
func (me *MetricsExporter) UpdateMetric(request MetricRequest) {
|
|
||||||
me.mu.Lock()
|
|
||||||
defer me.mu.Unlock()
|
|
||||||
|
|
||||||
for metricName, value := range request.Metrics {
|
|
||||||
// Уникальное имя метрики
|
|
||||||
fullMetricName := fmt.Sprintf("vks_%s_%s", request.ID, metricName)
|
|
||||||
|
|
||||||
// Лейблы
|
|
||||||
labels := []string{"name", "url", "method"}
|
|
||||||
labelValues := []string{request.Name, request.URL, request.Method}
|
|
||||||
|
|
||||||
// Обработка метрик в зависимости от типа
|
|
||||||
switch request.Type {
|
|
||||||
case "gauge":
|
|
||||||
me.updateGauge(fullMetricName, labels, labelValues, value)
|
|
||||||
case "counter":
|
|
||||||
me.updateCounter(fullMetricName, labels, labelValues, value)
|
|
||||||
case "histogram":
|
|
||||||
me.updateHistogram(fullMetricName, labels, labelValues, value)
|
|
||||||
case "summary":
|
|
||||||
me.updateSummary(fullMetricName, labels, labelValues, value)
|
|
||||||
default:
|
|
||||||
log.Printf("Неподдерживаемый тип метрики: %s\n", request.Type)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обновление `Gauge` метрик
|
|
||||||
func (me *MetricsExporter) updateGauge(name string, labels []string, labelValues []string, value float64) {
|
|
||||||
if _, exists := me.gaugeMetrics[name]; !exists {
|
|
||||||
gaugeVec := prometheus.NewGaugeVec(
|
|
||||||
prometheus.GaugeOpts{
|
|
||||||
Name: name,
|
|
||||||
Help: fmt.Sprintf("Gauge metric %s", name),
|
|
||||||
},
|
|
||||||
labels,
|
|
||||||
)
|
|
||||||
customRegistry.MustRegister(gaugeVec)
|
|
||||||
me.gaugeMetrics[name] = gaugeVec
|
|
||||||
}
|
|
||||||
me.gaugeMetrics[name].WithLabelValues(labelValues...).Set(value)
|
|
||||||
log.Printf("Gauge обновлён: %s = %f\n", name, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обновление `Counter` метрик
|
|
||||||
func (me *MetricsExporter) updateCounter(name string, labels []string, labelValues []string, value float64) {
|
|
||||||
if value < 0 {
|
|
||||||
log.Printf("Ошибка: Counter %s не может быть отрицательным\n", name)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if _, exists := me.counterMetrics[name]; !exists {
|
|
||||||
counterVec := prometheus.NewCounterVec(
|
|
||||||
prometheus.CounterOpts{
|
|
||||||
Name: name,
|
|
||||||
Help: fmt.Sprintf("Counter metric %s", name),
|
|
||||||
},
|
|
||||||
labels,
|
|
||||||
)
|
|
||||||
customRegistry.MustRegister(counterVec)
|
|
||||||
me.counterMetrics[name] = counterVec
|
|
||||||
}
|
|
||||||
me.counterMetrics[name].WithLabelValues(labelValues...).Add(value)
|
|
||||||
log.Printf("Counter обновлён: %s += %f\n", name, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обновление `Histogram` метрик
|
|
||||||
func (me *MetricsExporter) updateHistogram(name string, labels []string, labelValues []string, value float64) {
|
|
||||||
if _, exists := me.histogramMetrics[name]; !exists {
|
|
||||||
histogramVec := prometheus.NewHistogramVec(
|
|
||||||
prometheus.HistogramOpts{
|
|
||||||
Name: name,
|
|
||||||
Help: fmt.Sprintf("Histogram metric %s", name),
|
|
||||||
Buckets: prometheus.LinearBuckets(10, 10, 10), // Пример диапазонов
|
|
||||||
},
|
|
||||||
labels,
|
|
||||||
)
|
|
||||||
customRegistry.MustRegister(histogramVec)
|
|
||||||
me.histogramMetrics[name] = histogramVec
|
|
||||||
}
|
|
||||||
me.histogramMetrics[name].WithLabelValues(labelValues...).Observe(value)
|
|
||||||
log.Printf("Histogram обновлён: %s = %f\n", name, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обновление `Summary` метрик
|
|
||||||
func (me *MetricsExporter) updateSummary(name string, labels []string, labelValues []string, value float64) {
|
|
||||||
if _, exists := me.summaryMetrics[name]; !exists {
|
|
||||||
summaryVec := prometheus.NewSummaryVec(
|
|
||||||
prometheus.SummaryOpts{
|
|
||||||
Name: name,
|
|
||||||
Help: fmt.Sprintf("Summary metric %s", name),
|
|
||||||
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}, // Пример целей
|
|
||||||
},
|
|
||||||
labels,
|
|
||||||
)
|
|
||||||
customRegistry.MustRegister(summaryVec)
|
|
||||||
me.summaryMetrics[name] = summaryVec
|
|
||||||
}
|
|
||||||
me.summaryMetrics[name].WithLabelValues(labelValues...).Observe(value)
|
|
||||||
log.Printf("Summary обновлён: %s = %f\n", name, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обработчик для приёма JSON
|
|
||||||
func (me *MetricsExporter) JSONHandler(w http.ResponseWriter, r *http.Request) {
|
|
||||||
if r.Method != http.MethodPost {
|
|
||||||
log.Printf("Неверный метод: %s (ожидался POST)", r.Method)
|
|
||||||
http.Error(w, "Only POST method is allowed", http.StatusMethodNotAllowed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Читаем тело запроса
|
|
||||||
body, err := io.ReadAll(r.Body)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Ошибка чтения тела запроса: %s\n", err)
|
|
||||||
http.Error(w, "Failed to read request body", http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer r.Body.Close()
|
|
||||||
|
|
||||||
// Парсим JSON
|
|
||||||
var request MetricRequest
|
|
||||||
if err := json.Unmarshal(body, &request); err != nil {
|
|
||||||
log.Printf("Ошибка парсинга JSON: %s\nТело запроса: %s\n", err, string(body))
|
|
||||||
http.Error(w, "Invalid JSON format", http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Обновляем метрики
|
|
||||||
log.Printf("Обновление метрик для запроса ID: %s\n", request.ID)
|
|
||||||
me.UpdateMetric(request)
|
|
||||||
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
w.Write([]byte("Metrics updated"))
|
|
||||||
log.Printf("Метрики обновлены успешно для ID: %s\n", request.ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
log.SetOutput(os.Stdout) // Логируем в стандартный вывод
|
log.SetOutput(os.Stdout) // Логируем в стандартный вывод
|
||||||
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
|
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
|
||||||
|
|
||||||
exporter := NewMetricsExporter()
|
exporter := app.NewMetricsExporter()
|
||||||
|
|
||||||
// Используем кастомный реестр в обработчике /metrics
|
// Используем кастомный реестр в обработчике /metrics
|
||||||
http.Handle("/metrics", promhttp.HandlerFor(customRegistry, promhttp.HandlerOpts{}))
|
http.Handle("/metrics", promhttp.HandlerFor(app.CustomRegistry, promhttp.HandlerOpts{}))
|
||||||
http.HandleFunc("/update", exporter.JSONHandler) // Обработчик для приёма JSON
|
http.HandleFunc("/update", exporter.JSONHandler) // Обработчик для приёма JSON
|
||||||
|
|
||||||
port := ":9101"
|
port := ":9101"
|
||||||
|
|
@ -199,4 +26,4 @@ func main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: сделать переменные окружения, настроить канал, дописать тесты
|
//TODO: сделать переменные окружения, настроить канал, дописать юнит тесты, добавить интеграционные тесты
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,181 @@
|
||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Создаём кастомный реестр
|
||||||
|
var CustomRegistry = prometheus.NewRegistry()
|
||||||
|
|
||||||
|
// Структура JSON
|
||||||
|
type MetricRequest struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
Method string `json:"method"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Metrics map[string]float64 `json:"metrics"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Экспортёр метрик
|
||||||
|
type MetricsExporter struct {
|
||||||
|
GaugeMetrics map[string]*prometheus.GaugeVec
|
||||||
|
CounterMetrics map[string]*prometheus.CounterVec
|
||||||
|
HistogramMetrics map[string]*prometheus.HistogramVec
|
||||||
|
SummaryMetrics map[string]*prometheus.SummaryVec
|
||||||
|
mu sync.Mutex // Защита от одновременного доступа
|
||||||
|
}
|
||||||
|
|
||||||
|
// Создаём новый экспортёр
|
||||||
|
func NewMetricsExporter() *MetricsExporter {
|
||||||
|
return &MetricsExporter{
|
||||||
|
GaugeMetrics: make(map[string]*prometheus.GaugeVec),
|
||||||
|
CounterMetrics: make(map[string]*prometheus.CounterVec),
|
||||||
|
HistogramMetrics: make(map[string]*prometheus.HistogramVec),
|
||||||
|
SummaryMetrics: make(map[string]*prometheus.SummaryVec),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновление или создание метрики
|
||||||
|
func (me *MetricsExporter) UpdateMetric(request MetricRequest) {
|
||||||
|
me.mu.Lock()
|
||||||
|
defer me.mu.Unlock()
|
||||||
|
|
||||||
|
for metricName, value := range request.Metrics {
|
||||||
|
// Уникальное имя метрики
|
||||||
|
fullMetricName := fmt.Sprintf("vks_%s_%s", request.ID, metricName)
|
||||||
|
|
||||||
|
// Лейблы
|
||||||
|
labels := []string{"name", "url", "method"}
|
||||||
|
labelValues := []string{request.Name, request.URL, request.Method}
|
||||||
|
|
||||||
|
// Обработка метрик в зависимости от типа
|
||||||
|
switch request.Type {
|
||||||
|
case "gauge":
|
||||||
|
me.updateGauge(fullMetricName, labels, labelValues, value)
|
||||||
|
case "counter":
|
||||||
|
me.updateCounter(fullMetricName, labels, labelValues, value)
|
||||||
|
case "histogram":
|
||||||
|
me.updateHistogram(fullMetricName, labels, labelValues, value)
|
||||||
|
case "summary":
|
||||||
|
me.updateSummary(fullMetricName, labels, labelValues, value)
|
||||||
|
default:
|
||||||
|
log.Printf("Неподдерживаемый тип метрики: %s\n", request.Type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновление `Gauge` метрик
|
||||||
|
func (me *MetricsExporter) updateGauge(name string, labels []string, labelValues []string, value float64) {
|
||||||
|
if _, exists := me.GaugeMetrics[name]; !exists {
|
||||||
|
gaugeVec := prometheus.NewGaugeVec(
|
||||||
|
prometheus.GaugeOpts{
|
||||||
|
Name: name,
|
||||||
|
Help: fmt.Sprintf("Gauge metric %s", name),
|
||||||
|
},
|
||||||
|
labels,
|
||||||
|
)
|
||||||
|
CustomRegistry.MustRegister(gaugeVec)
|
||||||
|
me.GaugeMetrics[name] = gaugeVec
|
||||||
|
}
|
||||||
|
me.GaugeMetrics[name].WithLabelValues(labelValues...).Set(value)
|
||||||
|
log.Printf("Gauge обновлён: %s = %f\n", name, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновление `Counter` метрик
|
||||||
|
func (me *MetricsExporter) updateCounter(name string, labels []string, labelValues []string, value float64) {
|
||||||
|
if value < 0 {
|
||||||
|
log.Printf("Ошибка: Counter %s не может быть отрицательным\n", name)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, exists := me.CounterMetrics[name]; !exists {
|
||||||
|
counterVec := prometheus.NewCounterVec(
|
||||||
|
prometheus.CounterOpts{
|
||||||
|
Name: name,
|
||||||
|
Help: fmt.Sprintf("Counter metric %s", name),
|
||||||
|
},
|
||||||
|
labels,
|
||||||
|
)
|
||||||
|
CustomRegistry.MustRegister(counterVec)
|
||||||
|
me.CounterMetrics[name] = counterVec
|
||||||
|
}
|
||||||
|
me.CounterMetrics[name].WithLabelValues(labelValues...).Add(value)
|
||||||
|
log.Printf("Counter обновлён: %s += %f\n", name, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновление `Histogram` метрик
|
||||||
|
func (me *MetricsExporter) updateHistogram(name string, labels []string, labelValues []string, value float64) {
|
||||||
|
if _, exists := me.HistogramMetrics[name]; !exists {
|
||||||
|
histogramVec := prometheus.NewHistogramVec(
|
||||||
|
prometheus.HistogramOpts{
|
||||||
|
Name: name,
|
||||||
|
Help: fmt.Sprintf("Histogram metric %s", name),
|
||||||
|
Buckets: prometheus.LinearBuckets(10, 10, 10), // Пример диапазонов
|
||||||
|
},
|
||||||
|
labels,
|
||||||
|
)
|
||||||
|
CustomRegistry.MustRegister(histogramVec)
|
||||||
|
me.HistogramMetrics[name] = histogramVec
|
||||||
|
}
|
||||||
|
me.HistogramMetrics[name].WithLabelValues(labelValues...).Observe(value)
|
||||||
|
log.Printf("Histogram обновлён: %s = %f\n", name, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновление `Summary` метрик
|
||||||
|
func (me *MetricsExporter) updateSummary(name string, labels []string, labelValues []string, value float64) {
|
||||||
|
if _, exists := me.SummaryMetrics[name]; !exists {
|
||||||
|
summaryVec := prometheus.NewSummaryVec(
|
||||||
|
prometheus.SummaryOpts{
|
||||||
|
Name: name,
|
||||||
|
Help: fmt.Sprintf("Summary metric %s", name),
|
||||||
|
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}, // Пример целей
|
||||||
|
},
|
||||||
|
labels,
|
||||||
|
)
|
||||||
|
CustomRegistry.MustRegister(summaryVec)
|
||||||
|
me.SummaryMetrics[name] = summaryVec
|
||||||
|
}
|
||||||
|
me.SummaryMetrics[name].WithLabelValues(labelValues...).Observe(value)
|
||||||
|
log.Printf("Summary обновлён: %s = %f\n", name, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обработчик для приёма JSON
|
||||||
|
func (me *MetricsExporter) JSONHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Method != http.MethodPost {
|
||||||
|
log.Printf("Неверный метод: %s (ожидался POST)", r.Method)
|
||||||
|
http.Error(w, "Only POST method is allowed", http.StatusMethodNotAllowed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Читаем тело запроса
|
||||||
|
body, err := io.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Ошибка чтения тела запроса: %s\n", err)
|
||||||
|
http.Error(w, "Failed to read request body", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer r.Body.Close()
|
||||||
|
|
||||||
|
// Парсим JSON
|
||||||
|
var request MetricRequest
|
||||||
|
if err := json.Unmarshal(body, &request); err != nil {
|
||||||
|
log.Printf("Ошибка парсинга JSON: %s\nТело запроса: %s\n", err, string(body))
|
||||||
|
http.Error(w, "Invalid JSON format", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обновляем метрики
|
||||||
|
log.Printf("Обновление метрик для запроса ID: %s\n", request.ID)
|
||||||
|
me.UpdateMetric(request)
|
||||||
|
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
w.Write([]byte("Metrics updated"))
|
||||||
|
log.Printf("Метрики обновлены успешно для ID: %s\n", request.ID)
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
package main
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"exporter/internal/app"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
|
@ -15,12 +16,12 @@ import (
|
||||||
|
|
||||||
// Тест: успешное обновление метрик через /update
|
// Тест: успешное обновление метрик через /update
|
||||||
func TestJSONHandler_ValidRequest(t *testing.T) {
|
func TestJSONHandler_ValidRequest(t *testing.T) {
|
||||||
exporter := NewMetricsExporter()
|
exporter := app.NewMetricsExporter()
|
||||||
server := httptest.NewServer(http.HandlerFunc(exporter.JSONHandler))
|
server := httptest.NewServer(http.HandlerFunc(exporter.JSONHandler))
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
// JSON-запрос
|
// JSON-запрос
|
||||||
requestData := MetricRequest{
|
requestData := app.MetricRequest{
|
||||||
ID: "test_api",
|
ID: "test_api",
|
||||||
Name: "Test API",
|
Name: "Test API",
|
||||||
URL: "http://localhost/api",
|
URL: "http://localhost/api",
|
||||||
|
|
@ -48,7 +49,7 @@ func TestJSONHandler_ValidRequest(t *testing.T) {
|
||||||
|
|
||||||
// Тест: успешная обработка некорректного JSON
|
// Тест: успешная обработка некорректного JSON
|
||||||
func TestJSONHandler_InvalidJSON(t *testing.T) {
|
func TestJSONHandler_InvalidJSON(t *testing.T) {
|
||||||
exporter := NewMetricsExporter()
|
exporter := app.NewMetricsExporter()
|
||||||
server := httptest.NewServer(http.HandlerFunc(exporter.JSONHandler))
|
server := httptest.NewServer(http.HandlerFunc(exporter.JSONHandler))
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
|
|
@ -60,9 +61,9 @@ func TestJSONHandler_InvalidJSON(t *testing.T) {
|
||||||
|
|
||||||
// Тест: проверка создания и обновления Gauge метрики
|
// Тест: проверка создания и обновления Gauge метрики
|
||||||
func TestUpdateMetric_Gauge(t *testing.T) {
|
func TestUpdateMetric_Gauge(t *testing.T) {
|
||||||
exporter := NewMetricsExporter()
|
exporter := app.NewMetricsExporter()
|
||||||
|
|
||||||
request := MetricRequest{
|
request := app.MetricRequest{
|
||||||
ID: "test",
|
ID: "test",
|
||||||
Name: "Test Gauge",
|
Name: "Test Gauge",
|
||||||
URL: "http://test.com",
|
URL: "http://test.com",
|
||||||
|
|
@ -77,16 +78,16 @@ func TestUpdateMetric_Gauge(t *testing.T) {
|
||||||
exporter.UpdateMetric(request)
|
exporter.UpdateMetric(request)
|
||||||
|
|
||||||
// Проверяем, что метрика существует
|
// Проверяем, что метрика существует
|
||||||
metric, exists := exporter.gaugeMetrics["vks_test_load"]
|
metric, exists := exporter.GaugeMetrics["vks_test_load"]
|
||||||
assert.True(t, exists, "Метрика должна быть зарегистрирована")
|
assert.True(t, exists, "Метрика должна быть зарегистрирована")
|
||||||
assert.NotNil(t, metric, "Метрика не должна быть nil")
|
assert.NotNil(t, metric, "Метрика не должна быть nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Тест: проверка создания и увеличения Counter метрики
|
// Тест: проверка создания и увеличения Counter метрики
|
||||||
func TestUpdateMetric_Counter(t *testing.T) {
|
func TestUpdateMetric_Counter(t *testing.T) {
|
||||||
exporter := NewMetricsExporter()
|
exporter := app.NewMetricsExporter()
|
||||||
|
|
||||||
request := MetricRequest{
|
request := app.MetricRequest{
|
||||||
ID: "test",
|
ID: "test",
|
||||||
Name: "Test Counter",
|
Name: "Test Counter",
|
||||||
URL: "http://test.com",
|
URL: "http://test.com",
|
||||||
|
|
@ -102,7 +103,7 @@ func TestUpdateMetric_Counter(t *testing.T) {
|
||||||
exporter.UpdateMetric(request)
|
exporter.UpdateMetric(request)
|
||||||
|
|
||||||
// Проверяем, что метрика существует
|
// Проверяем, что метрика существует
|
||||||
metric, exists := exporter.counterMetrics["vks_test_requests"]
|
metric, exists := exporter.CounterMetrics["vks_test_requests"]
|
||||||
assert.True(t, exists, "Метрика должна быть зарегистрирована")
|
assert.True(t, exists, "Метрика должна быть зарегистрирована")
|
||||||
assert.NotNil(t, metric, "Метрика не должна быть nil")
|
assert.NotNil(t, metric, "Метрика не должна быть nil")
|
||||||
}
|
}
|
||||||
|
|
@ -114,10 +115,10 @@ func TestMetricsEndpoint(t *testing.T) {
|
||||||
Name: "test_metric",
|
Name: "test_metric",
|
||||||
Help: "Test metric for /metrics endpoint",
|
Help: "Test metric for /metrics endpoint",
|
||||||
})
|
})
|
||||||
customRegistry.MustRegister(gauge)
|
app.CustomRegistry.MustRegister(gauge)
|
||||||
gauge.Set(50.5)
|
gauge.Set(50.5)
|
||||||
|
|
||||||
server := httptest.NewServer(promhttp.HandlerFor(customRegistry, promhttp.HandlerOpts{}))
|
server := httptest.NewServer(promhttp.HandlerFor(app.CustomRegistry, promhttp.HandlerOpts{}))
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
|
|
||||||
// Делаем GET-запрос к /metrics
|
// Делаем GET-запрос к /metrics
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue