Skip to content
This repository was archived by the owner on Aug 2, 2024. It is now read-only.

Commit 4278b06

Browse files
Add debug logging
1 parent 103286d commit 4278b06

File tree

6 files changed

+207
-3
lines changed

6 files changed

+207
-3
lines changed

builder.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cmd
22

33
import (
4+
"fmt"
45
"log"
56
"os"
67
"reflect"
@@ -117,6 +118,10 @@ func Command(obj Runnable, cmd cobra.Command) *cobra.Command {
117118
defInt = 0
118119
}
119120

121+
if len(env) > 0 {
122+
usage += fmt.Sprintf(" (%s)", strings.Join(env, ","))
123+
}
124+
120125
flags := c.PersistentFlags()
121126
if fieldType.Tag.Get("local") == "true" {
122127
flags = c.Flags()
@@ -177,8 +182,8 @@ func Command(obj Runnable, cmd cobra.Command) *cobra.Command {
177182
envs = append(envs, func() {
178183
v := os.Getenv(env)
179184
if v != "" {
180-
fv, err := flags.GetString(name)
181-
if err == nil && (fv == "" || fv == defValue) {
185+
fv := flags.Lookup(name)
186+
if fv != nil && !fv.Changed {
182187
_ = flags.Set(name, v)
183188
}
184189
}

debug.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package cmd
2+
3+
import (
4+
"flag"
5+
"fmt"
6+
"log"
7+
"os"
8+
9+
// Enable logrus logging in baaah
10+
_ "github.com/acorn-io/baaah/pkg/logrus"
11+
12+
"github.com/acorn-io/cmd/pkg/logserver"
13+
"github.com/google/go-containerregistry/pkg/logs"
14+
"github.com/sirupsen/logrus"
15+
"k8s.io/klog/v2"
16+
)
17+
18+
type DebugLogging struct {
19+
Debug bool `usage:"Enable debug logging"`
20+
DebugLevel int `usage:"Debug log level (valid 0-9) (default 7)"`
21+
EnableDynamicLogLevel bool `usage:"Enable loglevel server to enable changing the log level at runtime"`
22+
}
23+
24+
func (d DebugLogging) InitLogging() error {
25+
if d.Debug || d.DebugLevel > 0 {
26+
logging := flag.NewFlagSet("", flag.PanicOnError)
27+
klog.InitFlags(logging)
28+
29+
level := d.DebugLevel
30+
if level == 0 {
31+
level = 6
32+
}
33+
if level > 7 {
34+
logrus.SetLevel(logrus.TraceLevel)
35+
logs.Debug = log.New(os.Stderr, "ggcr: ", log.LstdFlags)
36+
} else {
37+
logrus.SetLevel(logrus.DebugLevel)
38+
}
39+
if err := logging.Parse([]string{
40+
fmt.Sprintf("-v=%d", level),
41+
}); err != nil {
42+
return err
43+
}
44+
logrus.Debug("Debug logging enabled")
45+
}
46+
47+
if d.EnableDynamicLogLevel {
48+
logrus.Debug("Log server enabled")
49+
go logserver.StartServerWithDefaults()
50+
}
51+
52+
return nil
53+
}

go.mod

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,19 @@ module github.com/acorn-io/cmd
22

33
go 1.21.0
44

5-
require github.com/spf13/cobra v1.7.0
5+
require (
6+
github.com/acorn-io/baaah v0.0.0-20231009165317-af2b68361b8a
7+
github.com/google/go-containerregistry v0.16.1
8+
github.com/sirupsen/logrus v1.9.3
9+
github.com/spf13/cobra v1.7.0
10+
k8s.io/klog/v2 v2.100.1
11+
)
612

713
require (
14+
github.com/bombsimon/logrusr/v4 v4.0.0 // indirect
15+
github.com/go-logr/logr v1.2.4 // indirect
816
github.com/inconshreveable/mousetrap v1.1.0 // indirect
917
github.com/spf13/pflag v1.0.5 // indirect
18+
golang.org/x/sys v0.8.0 // indirect
19+
sigs.k8s.io/controller-runtime v0.15.0-beta.0 // indirect
1020
)

go.sum

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,55 @@
1+
github.com/acorn-io/baaah v0.0.0-20231009165317-af2b68361b8a h1:0bHfiYUw4ojXCUfGHUPmRewrgJ/EpLQ4BaR4yEy8BC4=
2+
github.com/acorn-io/baaah v0.0.0-20231009165317-af2b68361b8a/go.mod h1:1KSGxZt0E2MDedJESKUUYtxCwsJ3A+xZiw2QD8cVbjU=
3+
github.com/bombsimon/logrusr/v4 v4.0.0 h1:Pm0InGphX0wMhPqC02t31onlq9OVyJ98eP/Vh63t1Oo=
4+
github.com/bombsimon/logrusr/v4 v4.0.0/go.mod h1:pjfHC5e59CvjTBIU3V3sGhFWFAnsnhOR03TRc6im0l8=
15
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
6+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
7+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
8+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
9+
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
10+
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
11+
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
12+
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
13+
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
14+
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
15+
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
16+
github.com/google/go-containerregistry v0.16.1 h1:rUEt426sR6nyrL3gt+18ibRcvYpKYdpsa5ZW7MA08dQ=
17+
github.com/google/go-containerregistry v0.16.1/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ=
18+
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
19+
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
220
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
321
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
22+
github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q=
23+
github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
24+
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
25+
github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
26+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
27+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
428
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
29+
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
30+
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
531
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
632
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
733
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
834
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
35+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
36+
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
37+
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
38+
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
39+
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
40+
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
41+
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
42+
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
43+
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
44+
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
45+
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
46+
golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=
47+
golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
948
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
49+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
50+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
1051
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
52+
k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
53+
k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
54+
sigs.k8s.io/controller-runtime v0.15.0-beta.0 h1:pkhYMops8jZrVuI0kBHeF6q9UVu1JljIGGG4Ox5ZJmk=
55+
sigs.k8s.io/controller-runtime v0.15.0-beta.0/go.mod h1:YUTa+du31rqOu4mJaijiuhGFax9ecCJgO/v0/yW09gE=

pkg/logserver/init/init.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package init
2+
3+
import "github.com/acorn-io/cmd/pkg/logserver"
4+
5+
func init() {
6+
go logserver.StartServerWithDefaults()
7+
}

pkg/logserver/logserver.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Adapted from https://github.com/rancher/log/blob/52031d45f5fdb71cecb9a314865624b42514dbed/server/server.go
2+
// The only real differences here are that we are using logrus directly instead of a wrapper around it,
3+
// and that we are using an abstract namespace (non-file) socket.
4+
// This is only compatible with our fork of the client: https://github.com/acorn-io/loglevel
5+
6+
package logserver
7+
8+
import (
9+
"fmt"
10+
"net"
11+
"net/http"
12+
"os"
13+
14+
"github.com/sirupsen/logrus"
15+
)
16+
17+
var (
18+
DefaultSocketLocation = "\x00logserver"
19+
)
20+
21+
// Server structure is used to the store backend information
22+
type Server struct {
23+
SocketLocation string
24+
Debug bool
25+
}
26+
27+
// StartServerWithDefaults starts the server with default values. If the ACORN_LOG_LEVEL environment variable is set,
28+
// it will be parsed and used to set the log level.
29+
func StartServerWithDefaults() {
30+
if level, err := logrus.ParseLevel(os.Getenv("ACORN_LOG_LEVEL")); err == nil {
31+
logrus.SetLevel(level)
32+
} else {
33+
logrus.SetLevel(logrus.InfoLevel)
34+
}
35+
s := Server{
36+
SocketLocation: DefaultSocketLocation,
37+
}
38+
s.Start()
39+
}
40+
41+
// Start the server
42+
func (s *Server) Start() {
43+
_ = os.Remove(s.SocketLocation)
44+
go func() {
45+
_ = s.ListenAndServe()
46+
}()
47+
}
48+
49+
// ListenAndServe is used to setup handlers and
50+
// start listening on the specified location
51+
func (s *Server) ListenAndServe() error {
52+
server := http.Server{}
53+
http.HandleFunc("/v1/loglevel", s.loglevel)
54+
socketListener, err := net.Listen("unix", s.SocketLocation)
55+
if err != nil {
56+
logrus.Errorf("Failed to start logserver: %v", err)
57+
return err
58+
}
59+
return server.Serve(socketListener)
60+
}
61+
62+
func (s *Server) loglevel(rw http.ResponseWriter, req *http.Request) {
63+
// curl -X POST -d "level=debug" localhost:12345/v1/loglevel
64+
logrus.Debugf("Received loglevel request")
65+
if req.Method == http.MethodGet {
66+
level := logrus.GetLevel().String()
67+
_, _ = rw.Write([]byte(fmt.Sprintf("%s\n", level)))
68+
}
69+
70+
if req.Method == http.MethodPost {
71+
if err := req.ParseForm(); err != nil {
72+
rw.WriteHeader(http.StatusInternalServerError)
73+
_, _ = rw.Write([]byte(fmt.Sprintf("Failed to parse form: %v\n", err)))
74+
}
75+
level, err := logrus.ParseLevel(req.Form.Get("level"))
76+
if err != nil {
77+
rw.WriteHeader(http.StatusInternalServerError)
78+
_, _ = rw.Write([]byte(fmt.Sprintf("Failed to parse loglevel: %v\n", err)))
79+
} else {
80+
logrus.SetLevel(level)
81+
_, _ = rw.Write([]byte("OK\n"))
82+
}
83+
}
84+
}

0 commit comments

Comments
 (0)