Skip to content

Commit

Permalink
Merge pull request #20 from tulilirockz/better-logging
Browse files Browse the repository at this point in the history
feat: slog for pretty logging
  • Loading branch information
gerblesh authored Dec 4, 2024
2 parents 00a0150 + f01f05c commit 954079e
Show file tree
Hide file tree
Showing 12 changed files with 342 additions and 58 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ ublue-upd
output/*
*.key
*.private
*.log
58 changes: 53 additions & 5 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ package cmd
import (
"fmt"
"log"
"log/slog"
"os"
"os/user"
"path"
"path/filepath"

"github.com/spf13/cobra"
appLogging "github.com/ublue-os/uupd/pkg/logging"
"golang.org/x/term"
)

Expand All @@ -23,10 +27,11 @@ func assertRoot(cmd *cobra.Command, args []string) {

var (
rootCmd = &cobra.Command{
Use: "uupd",
Short: "uupd (Universal Update) is the successor to ublue-update, built for bootc",
PreRun: assertRoot,
Run: Update,
Use: "uupd",
Short: "uupd (Universal Update) is the successor to ublue-update, built for bootc",
PersistentPreRunE: initLogging,
PreRun: assertRoot,
Run: Update,
}

waitCmd = &cobra.Command{
Expand Down Expand Up @@ -56,6 +61,10 @@ var (
PreRun: assertRoot,
Run: ImageOutdated,
}

fLogFile string
fLogLevel string
fNoLogging bool
)

func Execute() {
Expand All @@ -65,14 +74,53 @@ func Execute() {
}
}

func initLogging(cmd *cobra.Command, args []string) error {
var logWriter *os.File = os.Stdout
if fLogFile != "-" {
abs, err := filepath.Abs(path.Clean(fLogFile))
if err != nil {
return err
}
logWriter, err = os.OpenFile(abs, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0755)
if err != nil {
return err
}
}

logLevel, err := appLogging.StrToLogLevel(fLogLevel)
if err != nil {
return err
}

main_app_logger := slog.New(appLogging.SetupAppLogger(logWriter, logLevel, fLogFile != "-"))

if fNoLogging {
slog.SetDefault(appLogging.NewMuteLogger())
} else {
slog.SetDefault(main_app_logger)
}
return nil
}

func init() {
rootCmd.AddCommand(waitCmd)
rootCmd.AddCommand(updateCheckCmd)
rootCmd.AddCommand(hardwareCheckCmd)
rootCmd.AddCommand(imageOutdatedCmd)
interactiveProgress := true
if fLogFile != "-" {
interactiveProgress = false
}
isTerminal := term.IsTerminal(int(os.Stdout.Fd()))
rootCmd.Flags().BoolP("no-progress", "p", !isTerminal, "Do not show progress bars")
if !isTerminal {
interactiveProgress = false
}
rootCmd.Flags().BoolP("no-progress", "p", interactiveProgress, "Do not show progress bars")
rootCmd.Flags().BoolP("hw-check", "c", false, "Run hardware check before running updates")
rootCmd.Flags().BoolP("dry-run", "n", false, "Do a dry run")
rootCmd.Flags().BoolP("verbose", "v", false, "Display command outputs after run")

rootCmd.PersistentFlags().StringVar(&fLogFile, "log-file", "-", "File where user-facing logs will be written to")
rootCmd.PersistentFlags().StringVar(&fLogLevel, "log-level", "info", "Log level for user-facing logs")
rootCmd.PersistentFlags().BoolVar(&fNoLogging, "quiet", false, "Make logs quiet")
}
57 changes: 29 additions & 28 deletions cmd/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,52 @@ package cmd

import (
"fmt"
"log"
"log/slog"

"github.com/jedib0t/go-pretty/v6/progress"
"github.com/spf13/cobra"
"github.com/ublue-os/uupd/checks"
"github.com/ublue-os/uupd/drv"
"github.com/ublue-os/uupd/lib"
"gopkg.in/yaml.v3"
)

func Update(cmd *cobra.Command, args []string) {
lock, err := lib.AcquireLock()
if err != nil {
log.Fatalf("%v, is uupd already running?", err)
slog.Error(fmt.Sprintf("%v, is uupd already running?", err))
return
}
defer lib.ReleaseLock(lock)

hwCheck, err := cmd.Flags().GetBool("hw-check")
if err != nil {
log.Fatalf("Failed to get hw-check flag: %v", err)
slog.Error("Failed to get hw-check flag", "error", err)
return
}
dryRun, err := cmd.Flags().GetBool("dry-run")
if err != nil {
log.Fatalf("Failed to get dry-run flag: %v", err)
slog.Error("Failed to get dry-run flag", "error", err)
return
}
verboseRun, err := cmd.Flags().GetBool("verbose")
if err != nil {
log.Fatalf("Failed to get verbose flag: %v", err)
slog.Error("Failed to get verbose flag", "error", err)
return
}

if hwCheck {
err := checks.RunHwChecks()
if err != nil {
log.Fatalf("Hardware checks failed: %v", err)
slog.Error("Hardware checks failed", "error", err)
return
}
log.Println("Hardware checks passed")
slog.Info("Hardware checks passed")
}

users, err := lib.ListUsers()
if err != nil {
log.Fatalf("Failed to list users")
slog.Error("Failed to list users", "users", users)
return
}

systemUpdater, err := drv.SystemUpdater{}.New(dryRun)
Expand Down Expand Up @@ -76,7 +81,8 @@ func Update(cmd *cobra.Command, args []string) {

progressEnabled, err := cmd.Flags().GetBool("no-progress")
if err != nil {
log.Fatalf("Failed to get no-progress flag: %v", err)
slog.Error("Failed to get no-progress flag", "error", err)
return
}
// Move this to its actual boolean value (~no-progress)
progressEnabled = !progressEnabled
Expand All @@ -100,19 +106,20 @@ func Update(cmd *cobra.Command, args []string) {
var outputs = []drv.CommandOutput{}

if systemUpdater.Outdated {
lib.Notify("System Warning", "There hasn't been an update in over a month. Consider rebooting or running updates manually")
log.Printf("There hasn't been an update in over a month. Consider rebooting or running updates manually")
const OUTDATED_WARNING = "There hasn't been an update in over a month. Consider rebooting or running updates manually"
lib.Notify("System Warning", OUTDATED_WARNING)
slog.Warn(OUTDATED_WARNING)
}

if systemUpdater.Config.Enabled {
lib.ChangeTrackerMessageFancy(pw, tracker, progressEnabled, fmt.Sprintf("Updating %s (%s)", systemUpdater.Config.Description, systemUpdater.Config.Title))
lib.ChangeTrackerMessageFancy(pw, tracker, progressEnabled, lib.TrackerMessage{Title: systemUpdater.Config.Title, Description: systemUpdater.Config.Description})
out, err := systemUpdater.Update()
outputs = append(outputs, *out...)
tracker.IncrementSection(err)
}

if brewUpdater.Config.Enabled {
lib.ChangeTrackerMessageFancy(pw, tracker, progressEnabled, fmt.Sprintf("Updating %s (%s)", brewUpdater.Config.Description, brewUpdater.Config.Title))
lib.ChangeTrackerMessageFancy(pw, tracker, progressEnabled, lib.TrackerMessage{Title: brewUpdater.Config.Title, Description: brewUpdater.Config.Description})
out, err := brewUpdater.Update()
outputs = append(outputs, *out...)
tracker.IncrementSection(err)
Expand All @@ -131,16 +138,13 @@ func Update(cmd *cobra.Command, args []string) {
}

pw.Stop()

if verboseRun {
log.Println("Verbose run requested")
slog.Info("Verbose run requested")

b, err := yaml.Marshal(outputs)
if err != nil {
log.Fatalf("Failure!")
return
for _, output := range outputs {
slog.Info("CommandOutput", slog.String("context", output.Context), slog.String("stdout", output.Stdout), slog.Any("stderr", output.Stderr))
}
log.Printf("%s", string(b))

return
}

Expand All @@ -152,17 +156,14 @@ func Update(cmd *cobra.Command, args []string) {
}

if len(failures) > 0 {
log.Println("Exited with failed updates.\nFailures found:")
slog.Warn("Exited with failed updates.")

b, err := yaml.Marshal(failures)
if err != nil {
log.Fatalf("Failure!")
return
for _, output := range failures {
slog.Info("CommandOutput", slog.String("context", output.Context), slog.String("stdout", output.Stdout), slog.Any("stderr", output.Stderr))
}
log.Printf("%s", string(b))

return
}

log.Printf("Updates Completed")
slog.Info("Updates Completed Successfully")
}
17 changes: 12 additions & 5 deletions drv/distrobox.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,14 @@ type DistroboxUpdater struct {
}

func (up DistroboxUpdater) Steps() int {
return (1 + len(up.users))
if up.Config.Enabled {
var steps = 1
if up.usersEnabled {
steps += len(up.users)
}
return steps
}
return 0
}

func (up DistroboxUpdater) New(dryrun bool) (DistroboxUpdater, error) {
Expand Down Expand Up @@ -47,19 +54,19 @@ func (up *DistroboxUpdater) Update() (*[]CommandOutput, error) {
var finalOutput = []CommandOutput{}

if up.Config.DryRun {
lib.ChangeTrackerMessageFancy(*up.Tracker.Writer, up.Tracker.Tracker, up.Tracker.Progress, fmt.Sprintf("Updating %s (%s)", up.Config.Description, up.Config.Title))
lib.ChangeTrackerMessageFancy(*up.Tracker.Writer, up.Tracker.Tracker, up.Tracker.Progress, lib.TrackerMessage{Title: up.Config.Title, Description: up.Config.Description})
up.Tracker.Tracker.IncrementSection(nil)

var err error = nil
for _, user := range up.users {
up.Tracker.Tracker.IncrementSection(err)
lib.ChangeTrackerMessageFancy(*up.Tracker.Writer, up.Tracker.Tracker, up.Tracker.Progress, fmt.Sprintf("Updating %s %s (%s)", *up.Config.UserDescription, user.Name, up.Config.Title))
lib.ChangeTrackerMessageFancy(*up.Tracker.Writer, up.Tracker.Tracker, up.Tracker.Progress, lib.TrackerMessage{Title: up.Config.Title, Description: *up.Config.UserDescription + " " + user.Name})
}
return &finalOutput, nil
}

// TODO: add env support for Flatpak and Distrobox updaters
lib.ChangeTrackerMessageFancy(*up.Tracker.Writer, up.Tracker.Tracker, up.Tracker.Progress, fmt.Sprintf("Updating %s (%s)", up.Config.Description, up.Config.Title))
lib.ChangeTrackerMessageFancy(*up.Tracker.Writer, up.Tracker.Tracker, up.Tracker.Progress, lib.TrackerMessage{Title: up.Config.Title, Description: up.Config.Description})
flatpakCmd := exec.Command("/usr/bin/distrobox", "upgrade", "-a")
out, err := flatpakCmd.CombinedOutput()
tmpout := CommandOutput{}.New(out, err)
Expand All @@ -71,7 +78,7 @@ func (up *DistroboxUpdater) Update() (*[]CommandOutput, error) {
err = nil
for _, user := range up.users {
up.Tracker.Tracker.IncrementSection(err)
lib.ChangeTrackerMessageFancy(*up.Tracker.Writer, up.Tracker.Tracker, up.Tracker.Progress, fmt.Sprintf("Updating %s %s (%s)", *up.Config.UserDescription, user.Name, up.Config.Title))
lib.ChangeTrackerMessageFancy(*up.Tracker.Writer, up.Tracker.Tracker, up.Tracker.Progress, lib.TrackerMessage{Title: up.Config.Title, Description: *up.Config.UserDescription + " " + user.Name})
out, err := lib.RunUID(user.UID, []string{"/usr/bin/flatpak", "update", "-y"}, nil)
tmpout = CommandOutput{}.New(out, err)
if err != nil {
Expand Down
17 changes: 12 additions & 5 deletions drv/flatpak.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,14 @@ type FlatpakUpdater struct {
}

func (up FlatpakUpdater) Steps() int {
return (1 + len(up.users))
if up.Config.Enabled {
var steps = 1
if up.usersEnabled {
steps += len(up.users)
}
return steps
}
return 0
}

func (up FlatpakUpdater) New(dryrun bool) (FlatpakUpdater, error) {
Expand Down Expand Up @@ -47,18 +54,18 @@ func (up FlatpakUpdater) Update() (*[]CommandOutput, error) {
var finalOutput = []CommandOutput{}

if up.Config.DryRun {
lib.ChangeTrackerMessageFancy(*up.Tracker.Writer, up.Tracker.Tracker, up.Tracker.Progress, fmt.Sprintf("Updating %s (%s)", up.Config.Description, up.Config.Title))
lib.ChangeTrackerMessageFancy(*up.Tracker.Writer, up.Tracker.Tracker, up.Tracker.Progress, lib.TrackerMessage{Title: up.Config.Title, Description: up.Config.Description})
up.Tracker.Tracker.IncrementSection(nil)

var err error = nil
for _, user := range up.users {
up.Tracker.Tracker.IncrementSection(err)
lib.ChangeTrackerMessageFancy(*up.Tracker.Writer, up.Tracker.Tracker, up.Tracker.Progress, fmt.Sprintf("Updating %s %s (%s)", *up.Config.UserDescription, user.Name, up.Config.Title))
lib.ChangeTrackerMessageFancy(*up.Tracker.Writer, up.Tracker.Tracker, up.Tracker.Progress, lib.TrackerMessage{Title: up.Config.Title, Description: *up.Config.UserDescription + " " + user.Name})
}
return &finalOutput, nil
}

lib.ChangeTrackerMessageFancy(*up.Tracker.Writer, up.Tracker.Tracker, up.Tracker.Progress, fmt.Sprintf("Updating %s (%s)", up.Config.Description, up.Config.Title))
lib.ChangeTrackerMessageFancy(*up.Tracker.Writer, up.Tracker.Tracker, up.Tracker.Progress, lib.TrackerMessage{Title: up.Config.Title, Description: up.Config.Description})
flatpakCmd := exec.Command("/usr/bin/flatpak", "update", "-y")
out, err := flatpakCmd.CombinedOutput()
tmpout := CommandOutput{}.New(out, err)
Expand All @@ -70,7 +77,7 @@ func (up FlatpakUpdater) Update() (*[]CommandOutput, error) {
err = nil
for _, user := range up.users {
up.Tracker.Tracker.IncrementSection(err)
lib.ChangeTrackerMessageFancy(*up.Tracker.Writer, up.Tracker.Tracker, up.Tracker.Progress, fmt.Sprintf("Updating %s %s (%s)", *up.Config.UserDescription, user.Name, up.Config.Title))
lib.ChangeTrackerMessageFancy(*up.Tracker.Writer, up.Tracker.Tracker, up.Tracker.Progress, lib.TrackerMessage{Title: up.Config.Title, Description: *up.Config.UserDescription + " " + user.Name})
out, err := lib.RunUID(user.UID, []string{"/usr/bin/flatpak", "update", "-y"}, nil)
tmpout = CommandOutput{}.New(out, err)
if err != nil {
Expand Down
6 changes: 3 additions & 3 deletions drv/generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ type CommandOutput struct {
Stdout string
Failure bool
Stderr error
Context *string
Context string
}

func (output CommandOutput) New(out []byte, err error) *CommandOutput {
return &CommandOutput{
Context: nil,
Context: "",
Failure: err != nil,
Stderr: nil,
Stdout: string(out),
Expand All @@ -23,7 +23,7 @@ func (output CommandOutput) New(out []byte, err error) *CommandOutput {

func (out *CommandOutput) SetFailureContext(context string) {
out.Failure = true
out.Context = &context
out.Context = context
}

type DriverConfiguration struct {
Expand Down
11 changes: 4 additions & 7 deletions drv/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,16 @@ type SystemUpdater struct {
}

func (up SystemUpdater) Steps() int {
var steps = 0

if up.UpdateAvailable && up.Config.Enabled {
steps += 1
if up.Config.Enabled {
return 1
}

return steps
return 0
}

func (up SystemUpdater) New(dryrun bool) (SystemUpdater, error) {
up.Config = DriverConfiguration{
Title: "System",
Description: "System Update",
Description: "System Updates",
Enabled: true,
DryRun: dryrun,
}
Expand Down
Loading

0 comments on commit 954079e

Please sign in to comment.