Skip to content

Commit 239b401

Browse files
feat(client): add debug struct logging (#304)
Signed-off-by: Yaroslav Pershin <[email protected]> Signed-off-by: Aleksei Igrychev <[email protected]> Co-authored-by: Aleksei Igrychev <[email protected]>
1 parent aee04d8 commit 239b401

23 files changed

+329
-97
lines changed

client/cmd/trdl/command/template.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ const (
1212
`{{$visibleFlags := visibleFlags .Flags}}` +
1313
`{{$explicitlyExposedFlags := exposed .}}` +
1414
`{{$optionsCmdFor := optionsCmdFor .}}` +
15-
`{{$usageLine := usageLine .}}`
15+
`{{$usageLine := usageLine .}}` +
16+
`{{$versionLine := versionLine .}}`
1617

1718
// SectionAliases is the help template section that displays command aliases.
1819
SectionAliases = `{{if gt .Aliases 0}}Aliases:
@@ -45,6 +46,10 @@ const (
4546
// SectionTipsHelp is the help template section that displays the '--help' hint.
4647
SectionTipsHelp = `{{if .HasSubCommands}}Use "{{$rootCmd}} <command> --help" for more information about a given command.
4748
{{end}}`
49+
50+
// SectionVersion is the help template section that displays the command's version.
51+
SectionVersion = `
52+
{{ $versionLine }}`
4853
)
4954

5055
// MainHelpTemplate if the template for 'help' used by most commands.
@@ -63,6 +68,7 @@ func MainUsageTemplate() string {
6368
SectionFlags,
6469
SectionUsage,
6570
SectionTipsHelp,
71+
SectionVersion,
6672
}
6773
return strings.TrimRightFunc(strings.Join(sections, ""), unicode.IsSpace)
6874
}

client/cmd/trdl/command/templater.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313

1414
"github.com/werf/logboek"
1515
"github.com/werf/logboek/pkg/types"
16+
"github.com/werf/trdl/client/pkg/trdl"
1617
)
1718

1819
type FlagExposer interface {
@@ -82,6 +83,7 @@ func (t *templater) templateFuncs(exposedFlags ...string) template.FuncMap {
8283
"isRootCmd": t.isRootCmd,
8384
"optionsCmdFor": t.optionsCmdFor,
8485
"usageLine": t.usageLine,
86+
"versionLine": t.versionLine,
8587
"exposed": func(c *cobra.Command) *flag.FlagSet {
8688
exposed := flag.NewFlagSet("exposed", flag.ContinueOnError)
8789
if len(exposedFlags) > 0 {
@@ -186,6 +188,10 @@ func UsageLine(c *cobra.Command) string {
186188
return usage
187189
}
188190

191+
func (t *templater) versionLine(c *cobra.Command) string {
192+
return fmt.Sprintf("Version: %s\n", trdl.Version)
193+
}
194+
189195
func FlagsUsages(f *flag.FlagSet) string {
190196
x := new(bytes.Buffer)
191197

client/cmd/trdl/main.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@ import (
77
"github.com/gookit/color"
88
"github.com/spf13/cobra"
99

10+
"github.com/werf/common-go/pkg/util"
1011
"github.com/werf/trdl/client/cmd/trdl/command"
12+
"github.com/werf/trdl/client/pkg/logger"
1113
)
1214

13-
var homeDir string
15+
var (
16+
homeDir string
17+
debug bool
18+
)
1419

1520
func main() {
1621
if err := rootCmd().Execute(); err != nil {
@@ -26,6 +31,16 @@ func rootCmd() *cobra.Command {
2631
Long: "The universal package manager for delivering your software updates securely from a TUF repository (more details on https://trdl.dev)",
2732
SilenceUsage: true,
2833
SilenceErrors: true,
34+
PersistentPreRun: func(cmd *cobra.Command, args []string) {
35+
logLevel := "info"
36+
if debug {
37+
logLevel = "debug"
38+
}
39+
logger.GlobalLogger = logger.SetupGlobalLogger(logger.LoggerOptions{
40+
Level: logLevel,
41+
LogFormat: "text",
42+
})
43+
},
2944
CompletionOptions: cobra.CompletionOptions{
3045
DisableDefaultCmd: true,
3146
},
@@ -34,6 +49,8 @@ func rootCmd() *cobra.Command {
3449
rootCmd.SetHelpCommand(&cobra.Command{Hidden: true})
3550
SetupHomeDir(rootCmd)
3651

52+
rootCmd.PersistentFlags().BoolVarP(&debug, "debug", "d", util.GetBoolEnvironmentDefaultFalse("TRDL_DEBUG"), "Enable debug output (default $TRDL_DEBUG or false)")
53+
3754
groups := &command.Groups{}
3855
*groups = append(*groups, command.Groups{
3956
{

client/pkg/logger/log.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package logger
2+
3+
import (
4+
"log/slog"
5+
"os"
6+
)
7+
8+
var GlobalLogger *Logger
9+
10+
type LoggerInterface interface {
11+
Debug(msg string, args ...any)
12+
Error(msg string, args ...any)
13+
Info(msg string, args ...any)
14+
Warn(msg string, args ...any)
15+
With(args ...any) LoggerInterface
16+
}
17+
18+
type Logger struct {
19+
LoggerInterface
20+
}
21+
22+
type LoggerOptions struct {
23+
Level string
24+
LogFormat string
25+
}
26+
27+
func SetupGlobalLogger(opts LoggerOptions) *Logger {
28+
return NewLogger(&SlogWrapper{
29+
logger: NewSlogLogger(SlogOptions{
30+
Handler: slogHandler(opts.LogFormat, slogLevel(opts.Level)),
31+
}),
32+
})
33+
}
34+
35+
func NewLogger(l LoggerInterface) *Logger {
36+
return &Logger{LoggerInterface: l}
37+
}
38+
39+
type SlogOptions struct {
40+
Handler slog.Handler
41+
}
42+
43+
func NewSlogLogger(opts SlogOptions) *slog.Logger {
44+
return slog.New(opts.Handler)
45+
}
46+
47+
type SlogWrapper struct {
48+
logger *slog.Logger
49+
}
50+
51+
func (s *SlogWrapper) Debug(msg string, args ...any) {
52+
s.logger.Debug(msg, args...)
53+
}
54+
55+
func (s *SlogWrapper) Error(msg string, args ...any) {
56+
s.logger.Error(msg, args...)
57+
}
58+
59+
func (s *SlogWrapper) Info(msg string, args ...any) {
60+
s.logger.Info(msg, args...)
61+
}
62+
63+
func (s *SlogWrapper) Warn(msg string, args ...any) {
64+
s.logger.Warn(msg, args...)
65+
}
66+
67+
func (s *SlogWrapper) With(args ...any) LoggerInterface {
68+
return &SlogWrapper{
69+
logger: s.logger.With(args...),
70+
}
71+
}
72+
73+
func (l *Logger) With(args ...any) *Logger {
74+
return &Logger{LoggerInterface: l.LoggerInterface.With(args...)}
75+
}
76+
77+
func slogLevel(l string) slog.Level {
78+
switch l {
79+
case "debug":
80+
return slog.LevelDebug
81+
case "info":
82+
return slog.LevelInfo
83+
case "warn":
84+
return slog.LevelWarn
85+
case "error":
86+
return slog.LevelError
87+
default:
88+
return slog.LevelInfo
89+
}
90+
}
91+
92+
func slogHandler(format string, level slog.Level) slog.Handler {
93+
options := &slog.HandlerOptions{
94+
Level: level,
95+
}
96+
switch format {
97+
case "json":
98+
return slog.NewJSONHandler(os.Stdout, options)
99+
default:
100+
return slog.NewTextHandler(os.Stdout, options)
101+
}
102+
}

client/pkg/tuf/client.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package tuf
22

33
import (
44
"fmt"
5+
"net/http"
56
"os"
67
"time"
78

@@ -11,6 +12,7 @@ import (
1112

1213
"github.com/werf/lockgate"
1314
"github.com/werf/lockgate/pkg/file_locker"
15+
"github.com/werf/trdl/client/pkg/logger"
1416
"github.com/werf/trdl/client/pkg/util"
1517
)
1618

@@ -85,7 +87,14 @@ func (c *Client) initTufClient() error {
8587
}
8688
}
8789

88-
remote, err := tufClient.HTTPRemoteStore(c.repoUrl, nil, nil)
90+
var remote tufClient.RemoteStore
91+
httpClient := &http.Client{
92+
Transport: &TracingTransport{
93+
Transport: http.DefaultTransport,
94+
Logger: *logger.GlobalLogger,
95+
},
96+
}
97+
remote, err = tufClient.HTTPRemoteStore(c.repoUrl, nil, httpClient)
8998
if err != nil {
9099
return fmt.Errorf("unable to init http remote store: %w", err)
91100
}

client/pkg/tuf/trace.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package tuf
2+
3+
import (
4+
"net/http"
5+
"net/http/httptrace"
6+
"time"
7+
8+
"github.com/werf/trdl/client/pkg/logger"
9+
)
10+
11+
type TracingTransport struct {
12+
Transport http.RoundTripper
13+
Logger logger.Logger
14+
}
15+
16+
func (t *TracingTransport) RoundTrip(req *http.Request) (*http.Response, error) {
17+
log := t.Logger.With("source", "tuf-client")
18+
startTime := time.Now()
19+
20+
log.Debug("Request started",
21+
"method", req.Method,
22+
"url", req.URL.String(),
23+
)
24+
25+
trace := &httptrace.ClientTrace{
26+
DNSDone: func(info httptrace.DNSDoneInfo) {
27+
log.Debug("DNS lookup done", "host", info.Addrs)
28+
},
29+
ConnectDone: func(network, addr string, err error) {
30+
if err != nil {
31+
log.Debug("Failed to connect",
32+
"host", addr,
33+
"error", err,
34+
)
35+
return
36+
}
37+
log.Debug("Connected", "address", addr)
38+
},
39+
}
40+
41+
req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
42+
43+
resp, err := t.Transport.RoundTrip(req)
44+
if err != nil {
45+
log.Debug("Failed to send request",
46+
"url", req.URL.String(),
47+
"error", err,
48+
)
49+
return nil, err
50+
}
51+
52+
log.Debug("Request completed",
53+
"status", resp.Status,
54+
"duration", time.Since(startTime).Seconds(),
55+
)
56+
57+
return resp, nil
58+
}

docs/_data/sidebars/_cli.yml

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,42 @@
22
# DO NOT EDIT!
33

44
cli: &cli
5+
56
- title: Overview
67
url: /reference/cli/overview.html
78

89
- title: Configuration commands
910
f:
10-
- title: trdl add
11-
url: /reference/cli/trdl_add.html
1211

13-
- title: trdl remove
14-
url: /reference/cli/trdl_remove.html
12+
- title: trdl add
13+
url: /reference/cli/trdl_add.html
1514

16-
- title: trdl list
17-
url: /reference/cli/trdl_list.html
15+
- title: trdl remove
16+
url: /reference/cli/trdl_remove.html
1817

19-
- title: trdl set-default-channel
20-
url: /reference/cli/trdl_set_default_channel.html
18+
- title: trdl list
19+
url: /reference/cli/trdl_list.html
20+
21+
- title: trdl set-default-channel
22+
url: /reference/cli/trdl_set_default_channel.html
2123

2224
- title: Main commands
2325
f:
24-
- title: trdl use
25-
url: /reference/cli/trdl_use.html
26+
27+
- title: trdl use
28+
url: /reference/cli/trdl_use.html
2629

2730
- title: Advanced commands
2831
f:
29-
- title: trdl update
30-
url: /reference/cli/trdl_update.html
3132

32-
- title: trdl exec
33-
url: /reference/cli/trdl_exec.html
33+
- title: trdl update
34+
url: /reference/cli/trdl_update.html
35+
36+
- title: trdl exec
37+
url: /reference/cli/trdl_exec.html
3438

35-
- title: trdl dir-path
36-
url: /reference/cli/trdl_dir_path.html
39+
- title: trdl dir-path
40+
url: /reference/cli/trdl_dir_path.html
3741

38-
- title: trdl bin-path
39-
url: /reference/cli/trdl_bin_path.html
42+
- title: trdl bin-path
43+
url: /reference/cli/trdl_bin_path.html

0 commit comments

Comments
 (0)