diff --git a/cmd/auto.go b/cmd/auto.go index e967eb0..ef6473f 100644 --- a/cmd/auto.go +++ b/cmd/auto.go @@ -4,7 +4,6 @@ import ( "crypto/tls" "crypto/x509" "fmt" - "log" "net" "net/http" "os" @@ -45,26 +44,26 @@ func runAuto(cmd *cobra.Command, args []string) { // Load root CA for client connections rootCA, err := os.ReadFile(rootCAFile) if err != nil { - log.Fatalf("Failed to read root CA certificate: %v", err) + logger.Fatal("Failed to read root CA certificate", "error", err) } rootCAPool := x509.NewCertPool() if ok := rootCAPool.AppendCertsFromPEM(rootCA); !ok { - log.Fatalf("Failed to append root CA certificate to pool") + logger.Fatal("Failed to append root CA certificate to pool") } // Test HTTP Server httpPort, err := getRandomPort() if err != nil { - log.Fatalf("Failed to get random port for HTTP: %v", err) + logger.Fatal("Failed to get random port for HTTP", "error", err) } httpAddr := fmt.Sprintf("%s:%d", host, httpPort) - log.Printf("Starting HTTP server on %s", httpAddr) + logger.Info("Starting HTTP server", "address", httpAddr) server, err := startHTTPServer(certFile, keyFile, httpAddr) if err != nil { - log.Fatalf("Failed to start HTTP server: %v", err) + logger.Fatal("Failed to start HTTP server", "error", err) } // Give the server a moment to start @@ -85,9 +84,9 @@ func runAuto(cmd *cobra.Command, args []string) { url := fmt.Sprintf("https://%s", httpAddr) resp, err := client.Get(url) if err != nil { - log.Printf("❌ HTTP connection test failed: %v", err) + logger.Error("HTTP connection test failed", "error", err) } else { - log.Printf("✅ HTTP connection test successful") + logger.Info("✅ HTTP connection test successful") resp.Body.Close() } @@ -97,24 +96,27 @@ func runAuto(cmd *cobra.Command, args []string) { // Test RabbitMQ amqpPort, err := getRandomPort() if err != nil { - log.Fatalf("Failed to get random port for AMQP: %v", err) + logger.Fatal("Failed to get random port for AMQP", "error", err) } mgmtPortTLS, err := getRandomPort() if err != nil { - log.Fatalf("Failed to get random port for RabbitMQ management TLS: %v", err) + logger.Fatal("Failed to get random port for RabbitMQ management TLS", "error", err) } - log.Printf("Starting RabbitMQ server (AMQPS: %d, Management: HTTPS=%d)", amqpPort, mgmtPortTLS) + logger.Info("Starting RabbitMQ server", + "amqps_port", amqpPort, + "management_port", mgmtPortTLS, + ) amqpAddr := fmt.Sprintf("%s:%d", host, amqpPort) containerID, err := startRabbitMQServer(certFile, keyFile, amqpPort, mgmtPortTLS) if err != nil { - log.Fatalf("Failed to start RabbitMQ: %v", err) + logger.Fatal("Failed to start RabbitMQ", "error", err) } // Give RabbitMQ time to start - log.Printf("Waiting for RabbitMQ to start...") + logger.Info("Waiting for RabbitMQ to start...") time.Sleep(10 * time.Second) // Test RabbitMQ connection @@ -125,9 +127,9 @@ func runAuto(cmd *cobra.Command, args []string) { conn, err := amqp.DialTLS(fmt.Sprintf("amqps://guest:guest@%s", amqpAddr), amqpTLSConfig) if err != nil { - log.Printf("❌ RabbitMQ connection test failed: %v", err) + logger.Error("RabbitMQ connection test failed", "error", err) } else { - log.Printf("✅ RabbitMQ connection test successful") + logger.Info("✅ RabbitMQ connection test successful") conn.Close() } diff --git a/cmd/logger.go b/cmd/logger.go new file mode 100644 index 0000000..1b3eab0 --- /dev/null +++ b/cmd/logger.go @@ -0,0 +1,17 @@ +package cmd + +import ( + "os" + + "github.com/charmbracelet/log" +) + +var logger *log.Logger + +func init() { + logger = log.NewWithOptions(os.Stderr, log.Options{ + ReportCaller: false, + Level: log.InfoLevel, + CallerFormatter: log.LongCallerFormatter, + }) +} diff --git a/cmd/server.go b/cmd/server.go index 2460617..ef7045a 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -4,7 +4,6 @@ import ( "context" "crypto/tls" "fmt" - "log" "net/http" "os" "os/signal" @@ -38,7 +37,7 @@ func runServer(cmd *cobra.Command, args []string) { if useRabbitMQ { containerID, err := startRabbitMQServer(certFile, keyFile, 5671, 15671) if err != nil { - log.Fatalf("Failed to start RabbitMQ: %v", err) + logger.Fatal("Failed to start RabbitMQ", "error", err) } // Wait for interrupt @@ -50,7 +49,7 @@ func runServer(cmd *cobra.Command, args []string) { } else { server, err := startHTTPServer(certFile, keyFile, addr) if err != nil { - log.Fatalf("Failed to start HTTP server: %v", err) + logger.Fatal("Failed to start HTTP server", "error", err) } // Wait for interrupt @@ -59,7 +58,7 @@ func runServer(cmd *cobra.Command, args []string) { <-sigChan if err := server.Close(); err != nil { - log.Printf("Error during shutdown: %v", err) + logger.Error("Error during shutdown", "error", err) } } } @@ -85,11 +84,11 @@ func startHTTPServer(certFile, keyFile, addr string) (*http.Server, error) { go func() { if err := server.ListenAndServeTLS("", ""); err != http.ErrServerClosed { - log.Printf("HTTP server error: %v", err) + logger.Error("HTTP server error", "error", err) } }() - log.Printf("Starting TLS server on %s...", addr) + logger.Info("Starting TLS server", "address", addr) return server, nil } @@ -173,9 +172,11 @@ management.ssl.keyfile = /etc/rabbitmq/certs/key.pem return "", fmt.Errorf("failed to start container: %v", err) } - log.Printf("Started RabbitMQ container with ID: %s", resp.ID[:12]) - log.Printf("Management UI available at: https://localhost:%d", mgmtPortTLS) - log.Printf("AMQPS available at: amqps://localhost:%d", amqpPort) + logger.Info("Started RabbitMQ container", + "container_id", resp.ID[:12], + "management_ui", fmt.Sprintf("https://localhost:%d", mgmtPortTLS), + "amqps", fmt.Sprintf("amqps://localhost:%d", amqpPort), + ) return resp.ID, nil } @@ -184,17 +185,17 @@ func cleanupRabbitMQ(containerID string) { ctx := context.Background() cli, err := client.NewClientWithOpts(client.FromEnv) if err != nil { - log.Printf("Failed to create Docker client for cleanup: %v", err) + logger.Error("Failed to create Docker client for cleanup", "error", err) return } defer cli.Close() timeout := 10 if err := cli.ContainerStop(ctx, containerID, container.StopOptions{Timeout: &timeout}); err != nil { - log.Printf("Failed to stop container: %v", err) + logger.Error("Failed to stop container", "error", err) } if err := cli.ContainerRemove(ctx, containerID, container.RemoveOptions{}); err != nil { - log.Printf("Failed to remove container: %v", err) + logger.Error("Failed to remove container", "error", err) } } diff --git a/go.mod b/go.mod index fff4e8c..60c5721 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/frgrisk/tls-checker go 1.23.3 require ( + github.com/charmbracelet/log v0.4.0 github.com/docker/docker v27.5.0+incompatible github.com/docker/go-connections v0.5.0 github.com/rabbitmq/amqp091-go v1.10.0 @@ -12,25 +13,34 @@ require ( require ( github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect + github.com/charmbracelet/lipgloss v1.0.0 // indirect + github.com/charmbracelet/x/ansi v0.7.0 // indirect github.com/containerd/log v0.1.0 // indirect github.com/distribution/reference v0.6.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.8.0 // indirect + github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/magiconair/properties v1.8.9 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/term v0.5.2 // indirect github.com/morikuni/aec v1.0.0 // indirect + github.com/muesli/termenv v0.15.2 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/sagikazarmark/locafero v0.7.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect diff --git a/go.sum b/go.sum index e25cde0..463427c 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,16 @@ github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEK github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= +github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/charmbracelet/lipgloss v1.0.0 h1:O7VkGDvqEdGi93X+DeqsQ7PKHDgtQfF8j8/O2qFMQNg= +github.com/charmbracelet/lipgloss v1.0.0/go.mod h1:U5fy9Z+C38obMs+T+tJqst9VGzlOYGj4ri9reL3qUlo= +github.com/charmbracelet/log v0.4.0 h1:G9bQAcx8rWA2T3pWvx7YtPTPwgqpk7D68BX21IRW8ZM= +github.com/charmbracelet/log v0.4.0/go.mod h1:63bXt/djrizTec0l11H20t8FDSvA4CRZJ1KH22MdptM= +github.com/charmbracelet/x/ansi v0.7.0 h1:/QfFmiXOGGwN6fRbzvQaYp7fu1pkxpZ3qFBZWBsP404= +github.com/charmbracelet/x/ansi v0.7.0/go.mod h1:KBUFw1la39nl0dLl10l5ORDAqGXaeurTQmwyyVKse/Q= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -24,6 +32,8 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M= github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= +github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -47,8 +57,14 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM= github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= @@ -57,6 +73,8 @@ github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ= github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= +github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= @@ -69,6 +87,9 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw= github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -137,6 +158,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=