Skip to content

Commit 485ee13

Browse files
committed
Re-implement ability to use unix socket instead http connection
1 parent c03c8f4 commit 485ee13

File tree

3 files changed

+79
-8
lines changed

3 files changed

+79
-8
lines changed

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ tools:
123123
test-e2e: build collector/fixtures/sys/.unpacked collector/fixtures/udev/.unpacked tools
124124
@echo ">> running end-to-end tests"
125125
./end-to-end-test.sh -e "$(E2E_EXTRA_FLAGS)"
126+
@echo ">> running end-to-end tests with unix socket"
127+
./end-to-end-test.sh -e "$(E2E_EXTRA_FLAGS)" -s
126128

127129
.PHONY: skip-test-e2e
128130
skip-test-e2e:

end-to-end-test.sh

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ cd "$(dirname $0)"
105105

106106
port="$((10000 + (RANDOM % 10000)))"
107107
tmpdir=$(mktemp -d /tmp/node_exporter_e2e_test.XXXXXX)
108+
unix_socket="${tmpdir}/node_exporter.socket"
108109

109110
skip_re="^(go_|node_exporter_build_info|node_scrape_collector_duration_seconds|process_|node_textfile_mtime_seconds|node_time_(zone|seconds)|node_network_(receive|transmit)_(bytes|packets)_total)"
110111

@@ -127,8 +128,8 @@ case "${arch}" in
127128
;;
128129
esac
129130

130-
extra_flags=""; keep=0; update=0; verbose=0
131-
while getopts 'e:hkuv' opt
131+
extra_flags=""; keep=0; update=0; verbose=0; socket=0
132+
while getopts 'e:hkuvs' opt
132133
do
133134
case "$opt" in
134135
e)
@@ -140,15 +141,19 @@ do
140141
u)
141142
update=1
142143
;;
144+
s)
145+
socket=1
146+
;;
143147
v)
144148
verbose=1
145149
set -x
146150
;;
147151
*)
148-
echo "Usage: $0 [-k] [-u] [-v]"
152+
echo "Usage: $0 [-k] [-u] [-v] [-s]"
149153
echo " -k: keep temporary files and leave node_exporter running"
150154
echo " -u: update fixture_metrics"
151155
echo " -v: verbose output"
156+
echo " -s: use unix socket"
152157
exit 1
153158
;;
154159
esac
@@ -260,6 +265,13 @@ echo "IGNORED FLAGS============"
260265
echo "${ignored_flags:1}"| tr ' ' '\n' | sort | uniq
261266
echo "========================="
262267

268+
if [ ${socket} -ne 0 ]; then
269+
touch "${unix_socket}"
270+
connection_params="--web.socket-path=${unix_socket}"
271+
else
272+
connection_params="--web.listen-address=127.0.0.1:${port}"
273+
fi
274+
263275
./node_exporter \
264276
--path.rootfs="collector/fixtures" \
265277
--path.procfs="collector/fixtures/proc" \
@@ -268,7 +280,7 @@ echo "========================="
268280
$(for c in ${supported_enabled_collectors}; do echo --collector.${c} ; done) \
269281
$(for c in ${supported_disabled_collectors}; do echo --no-collector.${c} ; done) \
270282
${filtered_collector_flags} \
271-
--web.listen-address "127.0.0.1:${port}" \
283+
${connection_params} \
272284
--log.level="debug" > "${tmpdir}/node_exporter.log" 2>&1 &
273285

274286
echo $! > "${tmpdir}/node_exporter.pid"
@@ -302,7 +314,17 @@ EOF
302314
# This silences the "Killed" message
303315
set +e
304316
wait "$(cat ${tmpdir}/node_exporter.pid)" > /dev/null 2>&1
317+
rc=0
318+
if [ ${socket} -ne 0 ]; then
319+
if ls -l "${unix_socket}" &> /dev/null; then
320+
echo "Node exporter didn't remove the socket file after it exiting"
321+
rc=1
322+
fi
323+
fi
305324
rm -rf "${tmpdir}"
325+
if [ $rc -ne 0 ]; then
326+
exit $rc
327+
fi
306328
fi
307329
}
308330

@@ -323,7 +345,13 @@ get() {
323345

324346
sleep 1
325347

326-
get "127.0.0.1:${port}/metrics" | grep --text -E -v "${skip_re}" > "${generated_metrics}"
348+
(
349+
if [ ${socket} -ne 0 ]; then
350+
curl -s -X GET --unix-socket "${unix_socket}" http://localhost/metrics
351+
else
352+
get "127.0.0.1:${port}/metrics"
353+
fi
354+
) | grep --text -E -v "${skip_re}" > "${generated_metrics}"
327355

328356
# The following ignore-list is only applicable to the VMs used to run E2E tests on platforms for which containerized environments are not available.
329357
# However, owing to this, there are some non-deterministic metrics that end up generating samples, unlike their containerized counterparts, for e.g., node_network_receive_bytes_total.

node_exporter.go

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,16 @@ package main
1616
import (
1717
"fmt"
1818
"log/slog"
19+
"net"
1920
"net/http"
2021
_ "net/http/pprof"
2122
"os"
23+
"os/signal"
2224
"os/user"
2325
"runtime"
2426
"slices"
2527
"sort"
28+
"syscall"
2629

2730
"github.com/prometheus/common/promslog"
2831
"github.com/prometheus/common/promslog/flag"
@@ -181,6 +184,14 @@ func (h *handler) innerHandler(filters ...string) (http.Handler, error) {
181184

182185
func main() {
183186
var (
187+
socketPath = kingpin.Flag(
188+
"web.socket-path",
189+
"Path to a unix socket file on which to expose metrics and web interface.",
190+
).String()
191+
socketPermissions = kingpin.Flag(
192+
"web.socket-permissions",
193+
"Permissions of unix socket file.",
194+
).Default("0640").Int32()
184195
metricsPath = kingpin.Flag(
185196
"web.telemetry-path",
186197
"Path under which to expose metrics.",
@@ -244,8 +255,38 @@ func main() {
244255
}
245256

246257
server := &http.Server{}
247-
if err := web.ListenAndServe(server, toolkitFlags, logger); err != nil {
248-
logger.Error(err.Error())
249-
os.Exit(1)
258+
if *socketPath != "" {
259+
os.Remove(*socketPath)
260+
unixListener, err := net.Listen("unix", *socketPath)
261+
if err != nil {
262+
logger.Error("Error listening on socket", "err", err)
263+
os.Exit(1)
264+
}
265+
if err := os.Chmod(*socketPath, os.FileMode(*socketPermissions)); err != nil {
266+
logger.Error("Error changing socket permissions", "err", err)
267+
os.Exit(1)
268+
}
269+
defer os.Remove(*socketPath)
270+
271+
go func() {
272+
if err := server.Serve(unixListener); err != nil && err != http.ErrServerClosed {
273+
logger.Error("Error serving", "err", err)
274+
os.Exit(1)
275+
}
276+
}()
277+
278+
done := make(chan os.Signal, 1)
279+
signal.Notify(done, syscall.SIGINT, syscall.SIGTERM)
280+
logger.Info("Listening on", "path", *socketPath)
281+
<-done
282+
logger.Info("Connection closed on", "path", *socketPath)
283+
server.Close()
284+
os.Remove(*socketPath)
285+
os.Exit(0)
286+
} else {
287+
if err := web.ListenAndServe(server, toolkitFlags, logger); err != nil {
288+
logger.Error(err.Error())
289+
os.Exit(1)
290+
}
250291
}
251292
}

0 commit comments

Comments
 (0)