From d3c13b7bd6e4860ad6b135ae465dbd55c55644c0 Mon Sep 17 00:00:00 2001 From: belajarqywok Date: Tue, 9 Jul 2024 00:35:00 +0700 Subject: [PATCH] feat: add node exporter proxy feature --- main.go | 9 ++++ proxy/node_exporter/exporter_handler.go | 60 +++++++++++++++++++++++++ proxy/node_exporter/exporter_service.go | 41 +++++++++++++++++ proxy/node_exporter/interfaces.go | 11 +++++ 4 files changed, 121 insertions(+) create mode 100644 proxy/node_exporter/exporter_handler.go create mode 100644 proxy/node_exporter/exporter_service.go create mode 100644 proxy/node_exporter/interfaces.go diff --git a/main.go b/main.go index 5437582..76115df 100644 --- a/main.go +++ b/main.go @@ -8,9 +8,13 @@ import ( proxy "tebakaja_lb_proxy/proxy" + // Main Features stock_proxy "tebakaja_lb_proxy/proxy/stock" crypto_proxy "tebakaja_lb_proxy/proxy/crypto" national_currency_proxy "tebakaja_lb_proxy/proxy/national_currency" + + // Node Exporter + // exporter_proxy "tebakaja_lb_proxy/proxy/node_exporter" ) func main() { @@ -42,6 +46,11 @@ func main() { national_currency_proxy.NationalCurrencyPredictionHandler( &national_currency_proxy.NationalCurrencyServiceImpl{})) + // exporterGroup := proxyService.Group("/exporter") + // exporterGroup.Get("/metrics", + // exporter_proxy.ExporterMetricsHandler( + // &exporter_proxy.ExporterServiceImpl{})) + port := 7860 log.Fatal(proxyService.Listen(fmt.Sprintf("0.0.0.0:%d", port))) } diff --git a/proxy/node_exporter/exporter_handler.go b/proxy/node_exporter/exporter_handler.go new file mode 100644 index 0000000..5b39060 --- /dev/null +++ b/proxy/node_exporter/exporter_handler.go @@ -0,0 +1,60 @@ +package exporter + +import ( + "log" + "sync" + "time" + "context" + "net/http" + + "github.com/gofiber/fiber/v2" +) + + +/* + * --- Node Exporter Metric Handler --- + */ +func ExporterMetricsHandler(service ExporterService) fiber.Handler { + return func(c *fiber.Ctx) error { + ctx, cancel := context.WithTimeout(c.Context(), 120 * time.Second) + defer cancel() + + ch := make(chan string, 1) + var wg sync.WaitGroup + wg.Add(1) + + go func() { + defer wg.Done() + + apiResponse, err := service.ExporterMetricsService(ctx) + if err != nil { + log.Printf("[%s] %v", time.Now().Format("2006-01-02 15:04:05"), err) + ch <- apiResponse + return + } + + ch <- apiResponse + }() + + go func() { + wg.Wait() + close(ch) + }() + + select { + case apiResponse, ok := <-ch: + if !ok { + return c.Status(http.StatusInternalServerError).JSON(fiber.Map{ + "error": "Failed to get a response from the server", + }) + } + return c.SendString(apiResponse) + + case <-ctx.Done(): + log.Printf("[%s] Timeout: %v", time.Now().Format("2006-01-02 15:04:05"), ctx.Err()) + return c.Status(http.StatusRequestTimeout).JSON(fiber.Map{ + "error": "Request timeout", + }) + } + } +} diff --git a/proxy/node_exporter/exporter_service.go b/proxy/node_exporter/exporter_service.go new file mode 100644 index 0000000..1b2ef71 --- /dev/null +++ b/proxy/node_exporter/exporter_service.go @@ -0,0 +1,41 @@ +package exporter + +import ( + "context" + "fmt" + "io" + "net/http" +) + + +/* + * --- Node Exporter Metric Service --- + */ +func (s *ExporterServiceImpl) ExporterMetricsService(ctx context.Context) (string, error) { + endpoint := fmt.Sprintf("%s/metrics", "http://localhost:9100") + req, err := http.NewRequestWithContext(ctx, "GET", endpoint, nil) + if err != nil { + return "", fmt.Errorf("failed to create request: %v", err) + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return "", fmt.Errorf("failed to perform request: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return "", fmt.Errorf("request failed with status code: %d", resp.StatusCode) + } + + // Read the response body as plain text + body, err := io.ReadAll(resp.Body) + if err != nil { + return "", fmt.Errorf("failed to read response body: %v", err) + } + + // Convert []byte to string + metricsResponse := string(body) + + return metricsResponse, nil +} diff --git a/proxy/node_exporter/interfaces.go b/proxy/node_exporter/interfaces.go new file mode 100644 index 0000000..46757e0 --- /dev/null +++ b/proxy/node_exporter/interfaces.go @@ -0,0 +1,11 @@ +package exporter + +import "context" + +type ExporterService interface { + ExporterMetricsService(ctx context.Context) (string, error) + // ExporterVersionInfoService(ctx context.Context) (string, error) + // ExporterHealthCheckService(ctx context.Context) (string, error) +} + +type ExporterServiceImpl struct{} \ No newline at end of file