From 8df0f9fce70d85af5d7fcce4b3df0b2cd8a5862b Mon Sep 17 00:00:00 2001 From: Dmytro Biloshytskyi Date: Thu, 17 Apr 2025 17:58:01 +0300 Subject: [PATCH] Added ability to override server name in prometheus metrics --- README.md | 12 ++++++++++-- entrypoint.sh | 4 ++-- main.go | 12 +++++++----- parser.go | 51 ++++++++++++++++++++++++++++----------------------- 4 files changed, 47 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 3c7a8c0..54574f2 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ docker run --net=host -it nethermindeth/nethermind:latest ``` 3. Run the interceptor: ```bash -docker run --net="host" -e LISTEN_PORT=0.0.0.0:8081 -e SERVICE_TO_PROXY=0.0.0.0:8545 -e LOG_SERVER_URL=0.0.0.0:514 jrpc-interceptor +docker run --net="host" -e LISTEN_PORT=0.0.0.0:8081 -e SERVICE_TO_PROXY=0.0.0.0:8545 -e LOG_SERVER_URL=0.0.0.0:514 -e SERVER_NAME="" jrpc-interceptor ``` Where: @@ -32,6 +32,7 @@ Where: - `PROMETHEUS_URL` - the IP / port of the Prometheus server. Optional, "0.0.0.0:9100" by default. - `USE_PROMETHEUS` - whether to publish metrics to Prometheus. Optional, "true" by default. - `LOG_SERVER_DEBUG` - whether to print the logs to stdout. Optional, "true" by default. +- `SERVER_NAME` - name to use for the `server` tag in Prometheus metrics. Optional, empty by default (uses dynamic hostname from syslog messages). 4. Send requests to the interceptor: ```bash @@ -54,9 +55,16 @@ go build . ``` 3. Run the interceptor: ```bash -./jrpc-interceptor -debug=${LOG_SERVER_DEBUG:-true} -listenSyslog=${LOG_SERVER_URL:-"0.0.0.0:514"} -listenHTTP=${PROMETHEUS_URL:-"0.0.0.0:9100"} -usePrometheus=${USE_PROMETHEUS:-true} +./jrpc-interceptor -debug=${LOG_SERVER_DEBUG:-true} -listenSyslog=${LOG_SERVER_URL:-"0.0.0.0:514"} -listenHTTP=${PROMETHEUS_URL:-"0.0.0.0:9100"} -usePrometheus=${USE_PROMETHEUS:-true} -serverName=${SERVER_NAME:-""} ``` +The following command-line flags are available: +- `-debug` - whether to print the logs to stdout. Optional, `false` by default. +- `-listenSyslog` - the IP / port of the syslog server. Optional, `0.0.0.0:514` by default. +- `-listenHTTP` - the IP / port of the Prometheus server. Optional, `0.0.0.0:9100` by default. +- `-usePrometheus` - whether to publish metrics to Prometheus. Optional, `true` by default. +- `-serverName` - name to use for the `server` tag in Prometheus metrics. When empty (default), the hostname from each syslog message is used. Set this when you want to override the default hostname with a custom name. + ### Download docker image from github container registry 1. Create a [personal access token ](https://github.com/settings/tokens)(PAT) on github with repo access diff --git a/entrypoint.sh b/entrypoint.sh index 179ea43..4a7af54 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,3 +1,3 @@ #!/bin/sh -./jrpc-interceptor -debug=${LOG_SERVER_DEBUG:-true} -listenSyslog=${LOG_SERVER_URL:-"0.0.0.0:514"} -listenHTTP=${PROMETHEUS_URL:-"0.0.0.0:9100"} -usePrometheus=${USE_PROMETHEUS:-true} & -envsubst '${SERVICE_TO_PROXY} ${LOG_SERVER_URL} ${LISTEN_PORT}' < /etc/nginx/templates/nginx.conf.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;' \ No newline at end of file +./jrpc-interceptor -debug=${LOG_SERVER_DEBUG:-true} -listenSyslog=${LOG_SERVER_URL:-"0.0.0.0:514"} -listenHTTP=${PROMETHEUS_URL:-"0.0.0.0:9100"} -serverName=${SERVER_NAME:-""} -usePrometheus=${USE_PROMETHEUS:-true} & +envsubst '${SERVICE_TO_PROXY} ${LOG_SERVER_URL} ${LISTEN_PORT} ${SERVER_NAME}' < /etc/nginx/templates/nginx.conf.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;' \ No newline at end of file diff --git a/main.go b/main.go index bf9181e..f4e69d2 100644 --- a/main.go +++ b/main.go @@ -8,13 +8,14 @@ import ( ) var ( - debug bool + debug bool + serverName string ) func receiveSyslog(ch syslog.LogPartsChannel) { var ( - l *logEntry - err error + l *logEntry + err error ) for msg := range ch { @@ -40,13 +41,14 @@ func receiveSyslog(ch syslog.LogPartsChannel) { func main() { var ( - listenSyslog string - listenHTTP string + listenSyslog string + listenHTTP string usePrometheus bool ) flag.StringVar(&listenSyslog, "listenSyslog", "0.0.0.0:514", "ip:port to listen for syslog messages") flag.StringVar(&listenHTTP, "listenHTTP", "0.0.0.0:9100", "ip:port to listen for http requests") + flag.StringVar(&serverName, "serverName", "", "Server name to use in Prometheus metrics (leave empty for dynamic hostname)") flag.BoolVar(&usePrometheus, "usePrometheus", true, "Enable posting metrics to Prometheus") flag.BoolVar(&debug, "debug", false, "Enable debug") flag.Parse() diff --git a/parser.go b/parser.go index d719f86..3aae629 100644 --- a/parser.go +++ b/parser.go @@ -11,24 +11,23 @@ import ( type logEntry struct { // Tags - server string - scheme string - method string - hostname string - status string - protocol string - uri string - jrpc_method string + server string + scheme string + method string + hostname string + status string + protocol string + uri string + jrpc_method string // Fields - clientIP net.IP - duration float64 - bytesSent uint64 - bytesReceived uint64 - response_duration float64 + clientIP net.IP + duration float64 + bytesSent uint64 + bytesReceived uint64 + response_duration float64 } - func parseSyslogMessage(msg format.LogParts) (l *logEntry, err error) { content := msg["content"].(string) @@ -37,15 +36,21 @@ func parseSyslogMessage(msg format.LogParts) (l *logEntry, err error) { return nil, fmt.Errorf("wrong number of fields in message: %s", content) } + // Use custom serverName if provided, otherwise use hostname from syslog message + server := msg["hostname"].(string) + if serverName != "" { + server = serverName + } + l = &logEntry{ - server: msg["hostname"].(string), - scheme: chunks[1], - hostname: chunks[2], - method: chunks[3], - protocol: chunks[4], - uri: strings.Split(chunks[5], "?")[0], - status: chunks[6], - jrpc_method: chunks[11], + server: server, + scheme: chunks[1], + hostname: chunks[2], + method: chunks[3], + protocol: chunks[4], + uri: strings.Split(chunks[5], "?")[0], + status: chunks[6], + jrpc_method: chunks[11], } if l.clientIP = net.ParseIP(chunks[0]); l.clientIP == nil { @@ -68,4 +73,4 @@ func parseSyslogMessage(msg format.LogParts) (l *logEntry, err error) { return nil, fmt.Errorf("unable to parse response duration as float: %s", err) } return -} \ No newline at end of file +}