refactor: enhance bird metrics polling with context support
CI / changes (push) Successful in 8s
CI / openapi (push) Has been skipped
CI / go (push) Successful in 40s
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, , evobgp-web) (push) Has been skipped
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, evobgp-all, evobgp-web-all) (push) Has been skipped
CI / docker-bird (push) Has been skipped
CI / bird2 (push) Successful in 15s
CI / docker-go-prime (push) Successful in 24s
CI / docker-go (deploy/docker/evobgp-agent/Dockerfile, , evobgp-agent) (push) Successful in 59s
CI / docker-go (evobgp-all, 1, deploy/docker/gobinary/Dockerfile, , evobgp-all) (push) Successful in 2m18s
CI / docker-go (evobgp-api, 1, deploy/docker/gobinary/Dockerfile, , evobgp-api) (push) Successful in 1m23s
CI / docker-go (evobgp-deploy, 0, deploy/docker/gobinary/Dockerfile, , evobgp-deploy) (push) Successful in 1m20s
CI / docker-go (evobgp-ingest, 0, deploy/docker/gobinary/Dockerfile, , evobgp-ingest) (push) Successful in 1m24s
CI / docker-go (evobgp-node, 0, deploy/docker/gobinary/Dockerfile, , evobgp-node) (push) Successful in 1m9s
CI / docker-go (evobgp-render, 0, deploy/docker/gobinary/Dockerfile, , evobgp-render) (push) Successful in 1m22s
CI / docker-go (evobgp-scheduler, 0, deploy/docker/gobinary/Dockerfile, , evobgp-scheduler) (push) Successful in 1m24s
CI / changes (push) Successful in 8s
CI / openapi (push) Has been skipped
CI / go (push) Successful in 40s
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, , evobgp-web) (push) Has been skipped
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, evobgp-all, evobgp-web-all) (push) Has been skipped
CI / docker-bird (push) Has been skipped
CI / bird2 (push) Successful in 15s
CI / docker-go-prime (push) Successful in 24s
CI / docker-go (deploy/docker/evobgp-agent/Dockerfile, , evobgp-agent) (push) Successful in 59s
CI / docker-go (evobgp-all, 1, deploy/docker/gobinary/Dockerfile, , evobgp-all) (push) Successful in 2m18s
CI / docker-go (evobgp-api, 1, deploy/docker/gobinary/Dockerfile, , evobgp-api) (push) Successful in 1m23s
CI / docker-go (evobgp-deploy, 0, deploy/docker/gobinary/Dockerfile, , evobgp-deploy) (push) Successful in 1m20s
CI / docker-go (evobgp-ingest, 0, deploy/docker/gobinary/Dockerfile, , evobgp-ingest) (push) Successful in 1m24s
CI / docker-go (evobgp-node, 0, deploy/docker/gobinary/Dockerfile, , evobgp-node) (push) Successful in 1m9s
CI / docker-go (evobgp-render, 0, deploy/docker/gobinary/Dockerfile, , evobgp-render) (push) Successful in 1m22s
CI / docker-go (evobgp-scheduler, 0, deploy/docker/gobinary/Dockerfile, , evobgp-scheduler) (push) Successful in 1m24s
Updated the `startBirdMetricsPoller` function to accept a context parameter, allowing for better control over the polling lifecycle. This change was applied in both `evobgp-all` and `evobgp-api` main files. Additionally, modified the `StartBirdProtocolsPoller` function to handle context cancellation, ensuring graceful shutdown of the polling routine. Introduced a new service in the Docker Compose configuration for logging runtime service outputs, improving observability during deployment.
This commit is contained in:
+41
-13
@@ -3,10 +3,17 @@ package pipeline
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/netip"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Защита от pathological JSON: глубокая рекурсия при обходе и взрыв числа узлов по пути.
|
||||
const (
|
||||
maxJSONWalkDepth = 512
|
||||
maxJSONPathBreadth = 50000
|
||||
)
|
||||
|
||||
// ParseCIDRLines extracts unique IPv4/IPv6 CIDRs from plain text (one per line, # comments, empty lines skipped).
|
||||
func ParseCIDRLines(body string) []netip.Prefix {
|
||||
seen := make(map[string]struct{})
|
||||
@@ -47,7 +54,10 @@ func parseCIDRsFromJSON(body, prefixPath string) ([]netip.Prefix, error) {
|
||||
if err := json.Unmarshal([]byte(body), &root); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
values := jsonValuesAtPath(root, prefixPath)
|
||||
values, err := jsonValuesAtPath(root, prefixPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
seen := make(map[string]struct{})
|
||||
var out []netip.Prefix
|
||||
for _, raw := range values {
|
||||
@@ -66,10 +76,10 @@ func parseCIDRsFromJSON(body, prefixPath string) ([]netip.Prefix, error) {
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func jsonValuesAtPath(root any, prefixPath string) []string {
|
||||
func jsonValuesAtPath(root any, prefixPath string) ([]string, error) {
|
||||
path := strings.TrimSpace(prefixPath)
|
||||
if path == "" {
|
||||
return flattenJSONStrings(root)
|
||||
return flattenJSONStrings(root, 0)
|
||||
}
|
||||
parts := strings.Split(path, ".")
|
||||
nodes := []any{root}
|
||||
@@ -98,36 +108,54 @@ func jsonValuesAtPath(root any, prefixPath string) []string {
|
||||
}
|
||||
next = append(next, child)
|
||||
}
|
||||
if len(next) > maxJSONPathBreadth {
|
||||
return nil, fmt.Errorf("json path: слишком много узлов на шаге (>%d)", maxJSONPathBreadth)
|
||||
}
|
||||
nodes = next
|
||||
if len(nodes) == 0 {
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
var out []string
|
||||
for _, n := range nodes {
|
||||
out = append(out, flattenJSONStrings(n)...)
|
||||
part, err := flattenJSONStrings(n, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, part...)
|
||||
}
|
||||
return out
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func flattenJSONStrings(v any) []string {
|
||||
func flattenJSONStrings(v any, depth int) ([]string, error) {
|
||||
if depth > maxJSONWalkDepth {
|
||||
return nil, fmt.Errorf("json: глубина вложенности превышает %d", maxJSONWalkDepth)
|
||||
}
|
||||
switch x := v.(type) {
|
||||
case string:
|
||||
return []string{strings.TrimSpace(x)}
|
||||
return []string{strings.TrimSpace(x)}, nil
|
||||
case []any:
|
||||
var out []string
|
||||
for _, item := range x {
|
||||
out = append(out, flattenJSONStrings(item)...)
|
||||
part, err := flattenJSONStrings(item, depth+1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, part...)
|
||||
}
|
||||
return out
|
||||
return out, nil
|
||||
case map[string]any:
|
||||
var out []string
|
||||
for _, item := range x {
|
||||
out = append(out, flattenJSONStrings(item)...)
|
||||
part, err := flattenJSONStrings(item, depth+1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, part...)
|
||||
}
|
||||
return out
|
||||
return out, nil
|
||||
default:
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user