Skip to content

Commit f55a9bb

Browse files
Igor Drozdove_forbes
authored andcommitted
Merge branch 'ef-migrate-shell-check-and-principals-to-slog' into 'main'
migrate all bar gitlab-shell to new slog labkit setup See merge request https://gitlab.com/gitlab-org/gitlab-shell/-/merge_requests/1380 Merged-by: Igor Drozdov <idrozdov@gitlab.com> Approved-by: Vasilii Iakliushin <viakliushin@gitlab.com> Approved-by: Igor Drozdov <idrozdov@gitlab.com> Reviewed-by: Vasilii Iakliushin <viakliushin@gitlab.com> Co-authored-by: e_forbes <eforbes@gitlab.com>
2 parents 319fefc + e52bee7 commit f55a9bb

7 files changed

Lines changed: 77 additions & 36 deletions

File tree

cmd/gitlab-shell-authorized-keys-check/main.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,10 @@ func execute(readWriter *readwriter.ReadWriter) (int, error) {
5454
return exitCodeFailure, fmt.Errorf("failed to read config, exiting")
5555
}
5656

57-
logCloser := logger.Configure(config)
58-
defer func() { _ = logCloser.Close() }()
57+
logCloser := logger.ConfigureLogger(config)
58+
if logCloser != nil {
59+
defer logCloser.Close() //nolint:errcheck
60+
}
5961

6062
cmd, err := cmd.New(os.Args[1:], config, readWriter)
6163
if err != nil {

cmd/gitlab-shell-authorized-principals-check/main.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@ func run() int {
4646
return 1
4747
}
4848

49-
logCloser := logger.Configure(config)
50-
defer logCloser.Close() //nolint:errcheck
49+
logCloser := logger.ConfigureLogger(config)
50+
if logCloser != nil {
51+
defer logCloser.Close() //nolint:errcheck
52+
}
5153

5254
cmd, err := cmd.New(os.Args[1:], config, readWriter)
5355
if err != nil {

cmd/gitlab-shell-check/main.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,10 @@ func run() int {
5151
return code
5252
}
5353

54-
logCloser := logger.Configure(config)
55-
defer logCloser.Close() //nolint:errcheck
54+
logCloser := logger.ConfigureLogger(config)
55+
if logCloser != nil {
56+
defer logCloser.Close() //nolint:errcheck
57+
}
5658

5759
cmd, err := checkCmd.New(config, readWriter)
5860
if code := exitOnError(err, "Failed to create command"); code != 0 {

cmd/gitlab-sshd/main.go

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -59,26 +59,19 @@ func main() {
5959
))
6060
}
6161
}
62-
log, logCloser, err := logger.ConfigureLogger(cfg)
63-
if err != nil {
64-
log.ErrorContext(ctx, "failed to log to file, reverting to stderr", slog.String(fields.ErrorMessage, err.Error()))
65-
} else {
66-
// nolint
67-
defer func() {
68-
if err = logCloser.Close(); err != nil {
69-
log.ErrorContext(ctx, "failed to close log file", slog.String(fields.ErrorMessage, err.Error()))
70-
}
71-
}()
62+
logCloser := logger.ConfigureLogger(cfg)
63+
if logCloser != nil {
64+
defer logCloser.Close() //nolint:errcheck
7265
}
73-
log.InfoContext(ctx, "gitlab-sshd starting up...")
66+
slog.InfoContext(ctx, "gitlab-sshd starting up...")
7467

7568
overrideConfigFromEnvironment(cfg)
7669
if err := isConfigSane(cfg); err != nil {
7770
ctx = v2log.WithFields(ctx, slog.String(fields.ErrorMessage, err.Error()))
7871
if *configDir == "" {
79-
log.ErrorContext(ctx, "no config-dir provided, using only environment variables")
72+
slog.ErrorContext(ctx, "no config-dir provided, using only environment variables")
8073
} else {
81-
log.ErrorContext(ctx, "configuration error")
74+
slog.ErrorContext(ctx, "configuration error")
8275
}
8376
}
8477

@@ -90,14 +83,14 @@ func main() {
9083

9184
server, err := sshd.NewServer(cfg)
9285
if err != nil {
93-
log.ErrorContext(ctx, "Failed to start Gitlab built-in sshd", slog.String(
86+
slog.ErrorContext(ctx, "Failed to start Gitlab built-in sshd", slog.String(
9487
fields.ErrorMessage, err.Error(),
9588
))
9689
}
9790

9891
// Startup monitoring endpoint.
9992
if cfg.Server.WebListen != "" {
100-
startupMonitoringEndpoint(ctx, cfg, server, log)
93+
startupMonitoringEndpoint(ctx, cfg, server)
10194
}
10295

10396
ctx, cancel := context.WithCancel(ctx)
@@ -106,10 +99,10 @@ func main() {
10699
done := make(chan os.Signal, 1)
107100
signal.Notify(done, syscall.SIGINT, syscall.SIGTERM)
108101

109-
gracefulShutdown(ctx, done, cfg, server, cancel, log)
102+
gracefulShutdown(ctx, done, cfg, server, cancel)
110103

111104
if err := server.ListenAndServe(ctx); err != nil {
112-
log.ErrorContext(ctx, "GitLab built-in sshd failed to listen for new connections",
105+
slog.ErrorContext(ctx, "GitLab built-in sshd failed to listen for new connections",
113106
slog.String(fields.ErrorMessage, err.Error()))
114107
}
115108
}
@@ -120,18 +113,17 @@ func gracefulShutdown(
120113
cfg *config.Config,
121114
server *sshd.Server,
122115
cancel context.CancelFunc,
123-
log *slog.Logger,
124116
) {
125117
go func() {
126118
sig := <-done
127119
signal.Reset(syscall.SIGINT, syscall.SIGTERM)
128120

129121
gracePeriod := time.Duration(cfg.Server.GracePeriod)
130-
log.InfoContext(ctx, fmt.Sprintf("Shutdown initiated with grace period: %f", gracePeriod.Seconds()),
122+
slog.InfoContext(ctx, fmt.Sprintf("Shutdown initiated with grace period: %f", gracePeriod.Seconds()),
131123
slog.String("signal", sig.String()))
132124

133125
if err := server.Shutdown(); err != nil {
134-
log.ErrorContext(ctx, "Error shutting down the server", slog.String(
126+
slog.ErrorContext(ctx, "Error shutting down the server", slog.String(
135127
fields.ErrorMessage, err.Error()))
136128
}
137129
<-time.After(gracePeriod)
@@ -140,15 +132,15 @@ func gracefulShutdown(
140132
}()
141133
}
142134

143-
func startupMonitoringEndpoint(ctx context.Context, cfg *config.Config, server *sshd.Server, log *slog.Logger) {
135+
func startupMonitoringEndpoint(ctx context.Context, cfg *config.Config, server *sshd.Server) {
144136
go func() {
145137
err := monitoring.Start(
146138
monitoring.WithListenerAddress(cfg.Server.WebListen),
147139
monitoring.WithBuildInformation(Version, BuildTime),
148140
monitoring.WithServeMux(server.MonitoringServeMux()),
149141
)
150142

151-
log.ErrorContext(ctx, "monitoring service raised an error", slog.String(
143+
slog.ErrorContext(ctx, "monitoring service raised an error", slog.String(
152144
fields.ErrorMessage, err.Error(),
153145
))
154146
panic(err)

internal/command/command.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@ package command
66
import (
77
"context"
88
"fmt"
9+
"log/slog"
910
"os"
1011
"path"
1112
"strings"
1213

1314
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/config"
1415
"gitlab.com/gitlab-org/labkit/correlation"
16+
"gitlab.com/gitlab-org/labkit/fields"
1517
"gitlab.com/gitlab-org/labkit/tracing"
18+
"gitlab.com/gitlab-org/labkit/v2/log"
1619
)
1720

1821
// Command is the interface that all gitlab-shell commands must implement.
@@ -82,6 +85,7 @@ func Setup(serviceName string, config *config.Config) (context.Context, func())
8285
if correlationID == "" {
8386
correlationID := correlation.SafeRandomID()
8487
ctx = correlation.ContextWithCorrelation(ctx, correlationID)
88+
ctx = log.WithFields(ctx, slog.String(fields.CorrelationID, correlationID))
8589
}
8690

8791
return ctx, func() {

internal/logger/logger.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,21 @@ import (
1818
// ConfigureLogger - gitlab-sshd's log output can be configured to text as per the documentation:
1919
// https://docs.gitlab.com/omnibus/settings/logs/#json-logging
2020
// This is currently controlled by the GITLAB_LOG_FORMAT environment variable.
21-
func ConfigureLogger(cfg *config.Config) (*slog.Logger, io.Closer, error) {
21+
func ConfigureLogger(cfg *config.Config) io.Closer {
2222
logConfig := &v2log.Config{
2323
LogLevel: parseLogLevel(cfg.LogLevel),
2424
}
2525
if gitlabLogFormat := os.Getenv("GITLAB_LOG_FORMAT"); gitlabLogFormat == "text" {
2626
logConfig.UseTextFormat = true
2727
}
28-
return v2log.NewWithFile(cfg.LogFile, logConfig)
28+
logger, logCloser, err := v2log.NewWithFile(cfg.LogFile, logConfig)
29+
slog.SetDefault(logger)
30+
if err != nil {
31+
fmt.Fprintf(os.Stderr, "failed to configure log file %q: %v\n", cfg.LogFile, err)
32+
return nil
33+
}
34+
35+
return logCloser
2936
}
3037

3138
func parseLogLevel(level string) slog.Level {

internal/logger/logger_test.go

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package logger
22

33
import (
4+
"bytes"
45
"io"
6+
"log/slog"
57
"os"
68
"regexp"
79
"testing"
810

11+
"github.com/stretchr/testify/assert"
912
"github.com/stretchr/testify/require"
1013
"gitlab.com/gitlab-org/labkit/log"
1114

@@ -60,7 +63,6 @@ func TestConfigureWithPermissionError(t *testing.T) {
6063
LogFile: tempDir,
6164
LogFormat: "json",
6265
}
63-
6466
closer := Configure(&config)
6567
defer MustClose(t, closer)
6668

@@ -108,11 +110,12 @@ func TestConfigureLabkitV2Log(t *testing.T) {
108110
LogLevel: "debug",
109111
}
110112

111-
logger, closer, err := ConfigureLogger(&config)
112-
require.NoError(t, err)
113-
defer MustClose(t, closer)
114-
logger.Info("this is a test")
115-
logger.Debug("debug log message")
113+
closer := ConfigureLogger(&config)
114+
if closer != nil {
115+
defer MustClose(t, closer)
116+
}
117+
slog.Info("this is a test")
118+
slog.Debug("debug log message")
116119

117120
data, err := os.ReadFile(tmpFile)
118121
dataStr := string(data)
@@ -128,3 +131,32 @@ func TestConfigureLabkitV2Log(t *testing.T) {
128131
func MustClose(tb testing.TB, closer io.Closer) {
129132
require.NoError(tb, closer.Close())
130133
}
134+
135+
func TestConfigureLoggerDirectoryFailure(t *testing.T) {
136+
tempDir := t.TempDir()
137+
138+
config := config.Config{
139+
LogFile: tempDir,
140+
LogFormat: "json",
141+
}
142+
143+
fileInfo, err := os.Stat(tempDir)
144+
require.NoError(t, err)
145+
assert.True(t, fileInfo.IsDir())
146+
147+
old := os.Stderr
148+
r, w, _ := os.Pipe()
149+
os.Stderr = w
150+
151+
closer := ConfigureLogger(&config)
152+
assert.Nil(t, closer)
153+
slog.Info("this is a test")
154+
155+
w.Close()
156+
var buf bytes.Buffer
157+
io.Copy(&buf, r)
158+
os.Stderr = old
159+
160+
assert.Contains(t, buf.String(), "failed to configure log file", "capture the error in stderr")
161+
assert.Contains(t, buf.String(), "this is a test", "we should still be logging to stderr in this case")
162+
}

0 commit comments

Comments
 (0)