Skip to content

Commit baf986a

Browse files
authored
feat(debug): log API requests and responses when using --debug (#607)
1 parent 2590f76 commit baf986a

41 files changed

Lines changed: 77 additions & 1296 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Log API requests and responses when using global `--debug` option.
13+
1014
## [3.27.0] - 2025-12-31
1115

1216
### Added

go.mod

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ require (
99
github.com/UpCloudLtd/upcloud-go-api/v8 v8.33.0
1010
github.com/adrg/xdg v0.5.3
1111
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
12-
github.com/gemalto/flume v1.0.0
1312
github.com/jedib0t/go-pretty/v6 v6.7.8
1413
github.com/joho/godotenv v1.5.1
1514
github.com/m7shapan/cidr v0.0.0-20200427124835-7eba0889a5d2
@@ -43,8 +42,6 @@ require (
4342
github.com/Masterminds/semver/v3 v3.4.0 // indirect
4443
github.com/Masterminds/sprig/v3 v3.3.0 // indirect
4544
github.com/Masterminds/squirrel v1.5.4 // indirect
46-
github.com/ansel1/merry v1.7.0 // indirect
47-
github.com/ansel1/merry/v2 v2.1.1 // indirect
4845
github.com/blang/semver/v4 v4.0.0 // indirect
4946
github.com/chai2010/gettext-go v1.0.2 // indirect
5047
github.com/containerd/containerd v1.7.29 // indirect
@@ -94,7 +91,6 @@ require (
9491
github.com/mailru/easyjson v0.7.7 // indirect
9592
github.com/mattn/go-colorable v0.1.13 // indirect
9693
github.com/mattn/go-runewidth v0.0.16 // indirect
97-
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
9894
github.com/mitchellh/copystructure v1.2.0 // indirect
9995
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
10096
github.com/mitchellh/reflectwalk v1.0.2 // indirect
@@ -125,8 +121,6 @@ require (
125121
github.com/subosito/gotenv v1.6.0 // indirect
126122
github.com/x448/float16 v0.8.4 // indirect
127123
github.com/xlab/treeprint v1.2.0 // indirect
128-
go.uber.org/multierr v1.11.0 // indirect
129-
go.uber.org/zap v1.27.0 // indirect
130124
go.yaml.in/yaml/v2 v2.4.3 // indirect
131125
golang.org/x/net v0.47.0 // indirect
132126
golang.org/x/oauth2 v0.30.0 // indirect

go.sum

Lines changed: 0 additions & 1119 deletions
Large diffs are not rendered by default.

internal/commands/account/delete_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99

1010
"github.com/UpCloudLtd/upcloud-go-api/v8/upcloud"
1111
"github.com/UpCloudLtd/upcloud-go-api/v8/upcloud/request"
12-
"github.com/gemalto/flume"
1312
"github.com/stretchr/testify/assert"
1413
)
1514

@@ -40,7 +39,7 @@ func TestDeleteCommand(t *testing.T) {
4039
conf := config.New()
4140
c := commands.BuildCommand(DeleteCommand(), nil, conf)
4241

43-
_, err := c.(commands.MultipleArgumentCommand).Execute(commands.NewExecutor(conf, &mService, flume.New("test")), test.arg)
42+
_, err := c.(commands.MultipleArgumentCommand).Execute(commands.NewExecutor(conf, &mService, conf.NewLogger("test")), test.arg)
4443

4544
if test.error != "" {
4645
assert.EqualError(t, err, test.error)

internal/commands/account/token/delete_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"github.com/UpCloudLtd/upcloud-cli/v3/internal/config"
88
smock "github.com/UpCloudLtd/upcloud-cli/v3/internal/mock"
99
"github.com/UpCloudLtd/upcloud-go-api/v8/upcloud/request"
10-
"github.com/gemalto/flume"
1110
"github.com/stretchr/testify/assert"
1211
)
1312

@@ -19,7 +18,7 @@ func TestDeleteCommand(t *testing.T) {
1918
svc.On("DeleteToken", dr).Once().Return(nil)
2019

2120
command := commands.BuildCommand(DeleteCommand(), nil, conf)
22-
_, err := command.(commands.MultipleArgumentCommand).Execute(commands.NewExecutor(conf, svc, flume.New("test")), dr.ID)
21+
_, err := command.(commands.MultipleArgumentCommand).Execute(commands.NewExecutor(conf, svc, conf.NewLogger("test")), dr.ID)
2322
assert.NoError(t, err)
2423

2524
svc.AssertExpectations(t)

internal/commands/account/token/list_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111

1212
"github.com/UpCloudLtd/upcloud-cli/v3/internal/testutils"
1313
"github.com/UpCloudLtd/upcloud-go-api/v8/upcloud"
14-
"github.com/gemalto/flume"
1514
"github.com/jedib0t/go-pretty/v6/text"
1615
"github.com/stretchr/testify/assert"
1716
)
@@ -57,7 +56,7 @@ func TestListCommand(t *testing.T) {
5756
conf.Viper().Set(config.KeyOutput, config.ValueOutputHuman)
5857

5958
command := commands.BuildCommand(ListCommand(), nil, conf)
60-
out, err := command.(commands.NoArgumentCommand).ExecuteWithoutArguments(commands.NewExecutor(conf, svc, flume.New("test")))
59+
out, err := command.(commands.NoArgumentCommand).ExecuteWithoutArguments(commands.NewExecutor(conf, svc, conf.NewLogger("test")))
6160
assert.NoError(t, err)
6261

6362
buf := bytes.NewBuffer(nil)

internal/commands/account/token/show_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"github.com/UpCloudLtd/upcloud-cli/v3/internal/testutils"
1313
"github.com/UpCloudLtd/upcloud-go-api/v8/upcloud"
1414
"github.com/UpCloudLtd/upcloud-go-api/v8/upcloud/request"
15-
"github.com/gemalto/flume"
1615
"github.com/jedib0t/go-pretty/v6/text"
1716
"github.com/stretchr/testify/assert"
1817
)
@@ -52,7 +51,7 @@ func TestShowCommand(t *testing.T) {
5251
conf.Viper().Set(config.KeyOutput, config.ValueOutputHuman)
5352

5453
command := commands.BuildCommand(ShowCommand(), nil, conf)
55-
out, err := command.(commands.MultipleArgumentCommand).Execute(commands.NewExecutor(conf, svc, flume.New("test")), token.ID)
54+
out, err := command.(commands.MultipleArgumentCommand).Execute(commands.NewExecutor(conf, svc, conf.NewLogger("test")), token.ID)
5655
assert.NoError(t, err)
5756

5857
buf := bytes.NewBuffer(nil)

internal/commands/database/delete_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99

1010
"github.com/UpCloudLtd/upcloud-go-api/v8/upcloud"
1111
"github.com/UpCloudLtd/upcloud-go-api/v8/upcloud/request"
12-
"github.com/gemalto/flume"
1312
"github.com/stretchr/testify/assert"
1413
)
1514

@@ -41,7 +40,7 @@ func TestDeleteCommand(t *testing.T) {
4140
conf := config.New()
4241
c := commands.BuildCommand(DeleteCommand(), nil, conf)
4342

44-
_, err := c.(commands.MultipleArgumentCommand).Execute(commands.NewExecutor(conf, &mService, flume.New("test")), test.arg)
43+
_, err := c.(commands.MultipleArgumentCommand).Execute(commands.NewExecutor(conf, &mService, conf.NewLogger("test")), test.arg)
4544

4645
if test.error != "" {
4746
assert.EqualError(t, err, test.error)

internal/commands/executor.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package commands
33
import (
44
"context"
55
"fmt"
6+
"log/slog"
67
"os"
78
"os/signal"
89
"time"
@@ -15,7 +16,6 @@ import (
1516
internal "github.com/UpCloudLtd/upcloud-cli/v3/internal/service"
1617

1718
"github.com/UpCloudLtd/upcloud-go-api/v8/upcloud/service"
18-
"github.com/gemalto/flume"
1919
)
2020

2121
// Executor represents the execution context for commands
@@ -51,7 +51,7 @@ type executorImpl struct {
5151
Config *config.Config
5252
progress *progress.Progress
5353
service internal.AllServices
54-
logger flume.Logger
54+
logger *slog.Logger
5555
sigIntChan chan os.Signal
5656
}
5757

@@ -153,10 +153,10 @@ func (e executorImpl) All() internal.AllServices {
153153
}
154154

155155
// NewExecutor creates the default Executor
156-
func NewExecutor(cfg *config.Config, svc internal.AllServices, logger flume.Logger) Executor {
156+
func NewExecutor(cfg *config.Config, svc internal.AllServices, logger *slog.Logger) Executor {
157157
executor := &executorImpl{
158158
Config: cfg,
159-
progress: progress.NewProgress(config.GetProgressOutputConfig()),
159+
progress: progress.NewProgress(config.GetProgressOutputConfig(cfg)),
160160
logger: logger,
161161
service: svc,
162162
sigIntChan: make(chan os.Signal, 1),

internal/commands/executor_test.go

Lines changed: 3 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,13 @@ import (
88
"github.com/UpCloudLtd/upcloud-cli/v3/internal/config"
99
smock "github.com/UpCloudLtd/upcloud-cli/v3/internal/mock"
1010

11-
"github.com/gemalto/flume"
1211
"github.com/stretchr/testify/assert"
1312
)
1413

1514
func TestExecutor_WaitFor(t *testing.T) {
1615
mService := &smock.Service{}
1716
cfg := config.New()
18-
exec := NewExecutor(cfg, mService, flume.New("test"))
17+
exec := NewExecutor(cfg, mService, cfg.NewLogger("test"))
1918
finished := false
2019
// normal operation
2120
go func() {
@@ -34,7 +33,7 @@ func TestExecutor_WaitFor(t *testing.T) {
3433
func TestExecutor_WaitForTimeout(t *testing.T) {
3534
mService := &smock.Service{}
3635
cfg := config.New()
37-
exec := NewExecutor(cfg, mService, flume.New("test"))
36+
exec := NewExecutor(cfg, mService, cfg.NewLogger("test"))
3837
err := exec.WaitFor(func() error {
3938
time.Sleep(50 * time.Minute)
4039
return nil
@@ -45,74 +44,10 @@ func TestExecutor_WaitForTimeout(t *testing.T) {
4544
func TestExecutor_WaitForError(t *testing.T) {
4645
mService := &smock.Service{}
4746
cfg := config.New()
48-
exec := NewExecutor(cfg, mService, flume.New("test"))
47+
exec := NewExecutor(cfg, mService, cfg.NewLogger("test"))
4948
err := exec.WaitFor(func() error {
5049
time.Sleep(10 * time.Millisecond)
5150
return fmt.Errorf("mockmock")
5251
}, 100*time.Millisecond)
5352
assert.EqualError(t, err, "mockmock")
5453
}
55-
56-
type mockLogEntry struct {
57-
Msg string
58-
Args []any
59-
}
60-
61-
type mockLogger struct {
62-
debugLines []mockLogEntry
63-
infoLines []mockLogEntry
64-
errorLines []mockLogEntry
65-
context []any
66-
}
67-
68-
func (m *mockLogger) Debug(msg string, args ...any) {
69-
m.debugLines = append(m.debugLines, mockLogEntry{msg, args})
70-
}
71-
72-
func (m *mockLogger) Info(msg string, args ...any) {
73-
m.infoLines = append(m.infoLines, mockLogEntry{msg, args})
74-
}
75-
76-
func (m *mockLogger) Error(msg string, args ...any) {
77-
m.errorLines = append(m.errorLines, mockLogEntry{msg, args})
78-
}
79-
80-
func (m mockLogger) IsDebug() bool {
81-
return true
82-
}
83-
84-
func (m mockLogger) IsInfo() bool {
85-
return true
86-
}
87-
88-
func (m mockLogger) With(args ...any) flume.Logger {
89-
return &mockLogger{
90-
context: append(m.context, args...),
91-
}
92-
}
93-
94-
func TestExecutor_Logging(t *testing.T) {
95-
mService := &smock.Service{}
96-
cfg := config.New()
97-
logger := &mockLogger{context: []any{"base", "context"}}
98-
exec := NewExecutor(cfg, mService, logger)
99-
exec.Debug("debug1", "hello", "world")
100-
// create a contexted executor
101-
contextExec := exec.WithLogger("added", "newcontext")
102-
contextExec.Debug("debugcontext", "helloz", "worldz")
103-
exec.Debug("debug2", "hi", "earth")
104-
// make sure the main executor does not leak to the contexted one or vice versa
105-
assert.Equal(t, &mockLogger{
106-
debugLines: []mockLogEntry{
107-
{Msg: "debug1", Args: []any{"hello", "world"}},
108-
{Msg: "debug2", Args: []any{"hi", "earth"}},
109-
},
110-
context: []any{"base", "context"},
111-
}, logger)
112-
assert.Equal(t, &mockLogger{
113-
debugLines: []mockLogEntry{
114-
{Msg: "debugcontext", Args: []any{"helloz", "worldz"}},
115-
},
116-
context: []any{"base", "context", "added", "newcontext"},
117-
}, contextExec.(*executorImpl).logger)
118-
}

0 commit comments

Comments
 (0)