Spaces:
Sleeping
Sleeping
feat: add node exporter proxy feature
Browse files- main.go +9 -0
- proxy/node_exporter/exporter_handler.go +60 -0
- proxy/node_exporter/exporter_service.go +41 -0
- proxy/node_exporter/interfaces.go +11 -0
main.go
CHANGED
@@ -8,9 +8,13 @@ import (
|
|
8 |
|
9 |
proxy "tebakaja_lb_proxy/proxy"
|
10 |
|
|
|
11 |
stock_proxy "tebakaja_lb_proxy/proxy/stock"
|
12 |
crypto_proxy "tebakaja_lb_proxy/proxy/crypto"
|
13 |
national_currency_proxy "tebakaja_lb_proxy/proxy/national_currency"
|
|
|
|
|
|
|
14 |
)
|
15 |
|
16 |
func main() {
|
@@ -42,6 +46,11 @@ func main() {
|
|
42 |
national_currency_proxy.NationalCurrencyPredictionHandler(
|
43 |
&national_currency_proxy.NationalCurrencyServiceImpl{}))
|
44 |
|
|
|
|
|
|
|
|
|
|
|
45 |
port := 7860
|
46 |
log.Fatal(proxyService.Listen(fmt.Sprintf("0.0.0.0:%d", port)))
|
47 |
}
|
|
|
8 |
|
9 |
proxy "tebakaja_lb_proxy/proxy"
|
10 |
|
11 |
+
// Main Features
|
12 |
stock_proxy "tebakaja_lb_proxy/proxy/stock"
|
13 |
crypto_proxy "tebakaja_lb_proxy/proxy/crypto"
|
14 |
national_currency_proxy "tebakaja_lb_proxy/proxy/national_currency"
|
15 |
+
|
16 |
+
// Node Exporter
|
17 |
+
// exporter_proxy "tebakaja_lb_proxy/proxy/node_exporter"
|
18 |
)
|
19 |
|
20 |
func main() {
|
|
|
46 |
national_currency_proxy.NationalCurrencyPredictionHandler(
|
47 |
&national_currency_proxy.NationalCurrencyServiceImpl{}))
|
48 |
|
49 |
+
// exporterGroup := proxyService.Group("/exporter")
|
50 |
+
// exporterGroup.Get("/metrics",
|
51 |
+
// exporter_proxy.ExporterMetricsHandler(
|
52 |
+
// &exporter_proxy.ExporterServiceImpl{}))
|
53 |
+
|
54 |
port := 7860
|
55 |
log.Fatal(proxyService.Listen(fmt.Sprintf("0.0.0.0:%d", port)))
|
56 |
}
|
proxy/node_exporter/exporter_handler.go
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package exporter
|
2 |
+
|
3 |
+
import (
|
4 |
+
"log"
|
5 |
+
"sync"
|
6 |
+
"time"
|
7 |
+
"context"
|
8 |
+
"net/http"
|
9 |
+
|
10 |
+
"github.com/gofiber/fiber/v2"
|
11 |
+
)
|
12 |
+
|
13 |
+
|
14 |
+
/*
|
15 |
+
* --- Node Exporter Metric Handler ---
|
16 |
+
*/
|
17 |
+
func ExporterMetricsHandler(service ExporterService) fiber.Handler {
|
18 |
+
return func(c *fiber.Ctx) error {
|
19 |
+
ctx, cancel := context.WithTimeout(c.Context(), 120 * time.Second)
|
20 |
+
defer cancel()
|
21 |
+
|
22 |
+
ch := make(chan string, 1)
|
23 |
+
var wg sync.WaitGroup
|
24 |
+
wg.Add(1)
|
25 |
+
|
26 |
+
go func() {
|
27 |
+
defer wg.Done()
|
28 |
+
|
29 |
+
apiResponse, err := service.ExporterMetricsService(ctx)
|
30 |
+
if err != nil {
|
31 |
+
log.Printf("[%s] %v", time.Now().Format("2006-01-02 15:04:05"), err)
|
32 |
+
ch <- apiResponse
|
33 |
+
return
|
34 |
+
}
|
35 |
+
|
36 |
+
ch <- apiResponse
|
37 |
+
}()
|
38 |
+
|
39 |
+
go func() {
|
40 |
+
wg.Wait()
|
41 |
+
close(ch)
|
42 |
+
}()
|
43 |
+
|
44 |
+
select {
|
45 |
+
case apiResponse, ok := <-ch:
|
46 |
+
if !ok {
|
47 |
+
return c.Status(http.StatusInternalServerError).JSON(fiber.Map{
|
48 |
+
"error": "Failed to get a response from the server",
|
49 |
+
})
|
50 |
+
}
|
51 |
+
return c.SendString(apiResponse)
|
52 |
+
|
53 |
+
case <-ctx.Done():
|
54 |
+
log.Printf("[%s] Timeout: %v", time.Now().Format("2006-01-02 15:04:05"), ctx.Err())
|
55 |
+
return c.Status(http.StatusRequestTimeout).JSON(fiber.Map{
|
56 |
+
"error": "Request timeout",
|
57 |
+
})
|
58 |
+
}
|
59 |
+
}
|
60 |
+
}
|
proxy/node_exporter/exporter_service.go
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package exporter
|
2 |
+
|
3 |
+
import (
|
4 |
+
"context"
|
5 |
+
"fmt"
|
6 |
+
"io"
|
7 |
+
"net/http"
|
8 |
+
)
|
9 |
+
|
10 |
+
|
11 |
+
/*
|
12 |
+
* --- Node Exporter Metric Service ---
|
13 |
+
*/
|
14 |
+
func (s *ExporterServiceImpl) ExporterMetricsService(ctx context.Context) (string, error) {
|
15 |
+
endpoint := fmt.Sprintf("%s/metrics", "http://localhost:9100")
|
16 |
+
req, err := http.NewRequestWithContext(ctx, "GET", endpoint, nil)
|
17 |
+
if err != nil {
|
18 |
+
return "", fmt.Errorf("failed to create request: %v", err)
|
19 |
+
}
|
20 |
+
|
21 |
+
resp, err := http.DefaultClient.Do(req)
|
22 |
+
if err != nil {
|
23 |
+
return "", fmt.Errorf("failed to perform request: %v", err)
|
24 |
+
}
|
25 |
+
defer resp.Body.Close()
|
26 |
+
|
27 |
+
if resp.StatusCode != http.StatusOK {
|
28 |
+
return "", fmt.Errorf("request failed with status code: %d", resp.StatusCode)
|
29 |
+
}
|
30 |
+
|
31 |
+
// Read the response body as plain text
|
32 |
+
body, err := io.ReadAll(resp.Body)
|
33 |
+
if err != nil {
|
34 |
+
return "", fmt.Errorf("failed to read response body: %v", err)
|
35 |
+
}
|
36 |
+
|
37 |
+
// Convert []byte to string
|
38 |
+
metricsResponse := string(body)
|
39 |
+
|
40 |
+
return metricsResponse, nil
|
41 |
+
}
|
proxy/node_exporter/interfaces.go
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
package exporter
|
2 |
+
|
3 |
+
import "context"
|
4 |
+
|
5 |
+
type ExporterService interface {
|
6 |
+
ExporterMetricsService(ctx context.Context) (string, error)
|
7 |
+
// ExporterVersionInfoService(ctx context.Context) (string, error)
|
8 |
+
// ExporterHealthCheckService(ctx context.Context) (string, error)
|
9 |
+
}
|
10 |
+
|
11 |
+
type ExporterServiceImpl struct{}
|