Skip to content

Commit a4e61b4

Browse files
committed
Support structured logging
1 parent c1d180a commit a4e61b4

File tree

3 files changed

+64
-20
lines changed

3 files changed

+64
-20
lines changed

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,9 @@ CMDS=livenessprobe
1616
all: build
1717

1818
include release-tools/build.make
19+
20+
# Check contextual logging.
21+
.PHONY: logcheck
22+
test: logcheck
23+
logcheck:
24+
hack/verify-logcheck.sh

cmd/livenessprobe/main.go

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222
"fmt"
2323
"net"
2424
"net/http"
25-
"os"
2625
"time"
2726

2827
"k8s.io/klog/v2"
@@ -58,36 +57,37 @@ type healthProbe struct {
5857

5958
func (h *healthProbe) checkProbe(w http.ResponseWriter, req *http.Request) {
6059
ctx, cancel := context.WithTimeout(req.Context(), *probeTimeout)
60+
logger := klog.FromContext(ctx)
6161
defer cancel()
6262

6363
conn, err := connlib.Connect(ctx, *csiAddress, h.metricsManager, connlib.WithTimeout(*probeTimeout))
6464
if err != nil {
6565
w.WriteHeader(http.StatusInternalServerError)
6666
w.Write([]byte(err.Error()))
67-
klog.ErrorS(err, "Failed to establish connection to CSI driver")
67+
logger.Error(err, "Failed to establish connection to CSI driver")
6868
return
6969
}
7070
defer conn.Close()
7171

72-
klog.V(5).InfoS("Sending probe request to CSI driver", "driver", h.driverName)
72+
logger.V(5).Info("Sending probe request to CSI driver", "driver", h.driverName)
7373
ready, err := rpc.Probe(ctx, conn)
7474
if err != nil {
7575
w.WriteHeader(http.StatusInternalServerError)
7676
w.Write([]byte(err.Error()))
77-
klog.ErrorS(err, "Health check failed")
77+
logger.Error(err, "Health check failed")
7878
return
7979
}
8080

8181
if !ready {
8282
w.WriteHeader(http.StatusInternalServerError)
8383
w.Write([]byte("driver responded but is not ready"))
84-
klog.ErrorS(nil, "Driver responded but is not ready")
84+
logger.Error(nil, "Driver responded but is not ready")
8585
return
8686
}
8787

8888
w.WriteHeader(http.StatusOK)
8989
w.Write([]byte(`ok`))
90-
klog.V(5).InfoS("Health check succeeded")
90+
logger.V(5).Info("Health check succeeded")
9191
}
9292

9393
func main() {
@@ -97,18 +97,19 @@ func main() {
9797
logsapi.AddGoFlags(c, flag.CommandLine)
9898
logs.InitLogs()
9999
flag.Parse()
100+
logger := klog.Background()
100101
if err := logsapi.ValidateAndApply(c, fg); err != nil {
101-
klog.ErrorS(err, "LoggingConfiguration is invalid")
102-
os.Exit(1)
102+
logger.Error(err, "LoggingConfiguration is invalid")
103+
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
103104
}
104105

105106
if *healthzPort != defaultHealthzPort && *httpEndpoint != "" {
106-
klog.ErrorS(nil, "Only one of `--health-port` and `--http-endpoint` can be explicitly set")
107-
os.Exit(1)
107+
logger.Error(nil, "Only one of `--health-port` and `--http-endpoint` can be explicitly set")
108+
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
108109
}
109110
if *metricsAddress != "" && *httpEndpoint != "" {
110-
klog.ErrorS(nil, "Only one of `--metrics-address` and `--http-endpoint` can be explicitly set")
111-
os.Exit(1)
111+
logger.Error(nil, "Only one of `--metrics-address` and `--http-endpoint` can be explicitly set")
112+
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
112113
}
113114
var addr string
114115
if *httpEndpoint != "" {
@@ -127,19 +128,19 @@ func main() {
127128
if err != nil {
128129
// connlib should retry forever so a returned error should mean
129130
// the grpc client is misconfigured rather than an error on the network or CSI driver.
130-
klog.ErrorS(err, "Failed to establish connection to CSI driver")
131+
logger.Error(err, "Failed to establish connection to CSI driver")
131132
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
132133
}
133134

134-
klog.InfoS("Calling CSI driver to discover driver name")
135+
logger.Info("Calling CSI driver to discover driver name")
135136
csiDriverName, err := rpc.GetDriverName(context.Background(), csiConn)
136137
csiConn.Close()
137138
if err != nil {
138139
// The CSI driver does not support GetDriverName, which is serious enough to crash the probe.
139-
klog.ErrorS(err, "Failed to get CSI driver name")
140+
logger.Error(err, "Failed to get CSI driver name")
140141
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
141142
}
142-
klog.InfoS("CSI driver name", "driver", csiDriverName)
143+
logger.Info("CSI driver name", "driver", csiDriverName)
143144

144145
hp := &healthProbe{
145146
driverName: csiDriverName,
@@ -158,19 +159,19 @@ func main() {
158159
metricsMux := http.NewServeMux()
159160
metricsManager.RegisterToServer(metricsMux, *metricsPath)
160161
go func() {
161-
klog.InfoS("Separate metrics ServeMux listening", "address", *metricsAddress)
162+
logger.Info("Separate metrics ServeMux listening", "address", *metricsAddress)
162163
err := http.ListenAndServe(*metricsAddress, metricsMux)
163164
if err != nil {
164-
klog.ErrorS(err, "Failed to start prometheus metrics endpoint on specified address and path", "addr", *metricsAddress, "path", *metricsPath)
165+
logger.Error(err, "Failed to start prometheus metrics endpoint on specified address and path", "addr", *metricsAddress, "path", *metricsPath)
165166
klog.FlushAndExit(klog.ExitFlushTimeout, 1)
166167
}
167168
}()
168169
}
169170

170171
mux.HandleFunc("/healthz", hp.checkProbe)
171-
klog.InfoS("ServeMux listening", "address", addr)
172+
logger.Info("ServeMux listening", "address", addr)
172173
err = http.ListenAndServe(addr, mux)
173174
if err != nil {
174-
klog.ErrorS(err, "Failed to start http server")
175+
logger.Error(err, "Failed to start http server")
175176
}
176177
}

hack/verify-logcheck.sh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/usr/bin/env bash
2+
3+
# Copyright 2024 The Kubernetes Authors.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
# This script uses the logcheck tool to analyze the source code
18+
# for proper usage of klog contextual logging.
19+
20+
set -o errexit
21+
set -o nounset
22+
set -o pipefail
23+
24+
LOGCHECK_VERSION=${1:-0.8.1}
25+
26+
# This will canonicalize the path
27+
LIVENESSPROBE_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. && pwd -P)
28+
29+
# Create a temporary directory for installing logcheck and
30+
# set up a trap command to remove it when the script exits.
31+
LIVENESSPROBE_TEMP=$(mktemp -d 2>/dev/null || mktemp -d -t livenessprobe.XXXXXX)
32+
trap 'rm -rf "${LIVENESSPROBE_TEMP}"' EXIT
33+
34+
echo "Installing logcheck to temp dir: sigs.k8s.io/logtools/logcheck@v${LOGCHECK_VERSION}"
35+
GOBIN="${LIVENESSPROBE_TEMP}" go install "sigs.k8s.io/logtools/logcheck@v${LOGCHECK_VERSION}"
36+
echo "Verifing logcheck: ${LIVENESSPROBE_TEMP}/logcheck -check-contextual ${LIVENESSPROBE_ROOT}/..."
37+
"${LIVENESSPROBE_TEMP}/logcheck" -check-contextual -check-with-helpers "${LIVENESSPROBE_ROOT}/..."

0 commit comments

Comments
 (0)