From 640d56e9366339724c39fdf4765dd036fbfdfb53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20=C4=8Cerm=C3=A1k?= Date: Fri, 12 Apr 2024 15:14:45 +0200 Subject: [PATCH] Add flags for handling features of advanced logs (#471) * Add flags for handling features of advanced logs * Refactor log flags handling to common helpers * Add completion functions * Rename bootCompletions to hostBootCompletions to avoid confusion * Move log helper functions to host.go * Make --lines parameter unsigned * Remove boot ID from completion, add it to description --- cmd/addons_logs.go | 30 ++++++++-------------- cmd/audio_logs.go | 14 +++++----- cmd/core_logs.go | 14 +++++----- cmd/dns_logs.go | 14 +++++----- cmd/host.go | 58 ++++++++++++++++++++++++++++++++++++++++++ cmd/host_logs.go | 44 +++++--------------------------- cmd/host_logs_boots.go | 26 +++++++++++++++++++ cmd/multicast_logs.go | 15 ++++++----- cmd/supervisor_logs.go | 16 +++++++----- 9 files changed, 143 insertions(+), 88 deletions(-) diff --git a/cmd/addons_logs.go b/cmd/addons_logs.go index 722bd8f4..64c6f07f 100644 --- a/cmd/addons_logs.go +++ b/cmd/addons_logs.go @@ -1,7 +1,6 @@ package cmd import ( - "errors" "fmt" helper "github.com/home-assistant/cli/client" @@ -24,42 +23,33 @@ Allowing you to look at the log output generated by a Home Assistant add-on. Run: func(cmd *cobra.Command, args []string) { log.WithField("args", args).Debug("addons logs") - section := "addons" - command := "{slug}/logs" + section := "addons/{slug}" - url, err := helper.URLHelper(section, command) + request, err := processLogsFlags(section, cmd) if err != nil { - fmt.Println(err) + fmt.Printf("Error: %v", err) ExitWithError = true return } - request := helper.GetRequest() - slug := args[0] + request.SetPathParam("slug", slug) - request.SetPathParams(map[string]string{ - "slug": slug, - }) - - resp, err := request.SetHeader("Accept", "text/plain").Get(url) - - // returns 200 OK or 400, everything else is wrong - if err == nil && resp.StatusCode() != 200 && resp.StatusCode() != 400 { - err = errors.New("Unexpected server response") - log.Error(err) - } + resp, err := request.Send() if err != nil { fmt.Println(err) ExitWithError = true - } else { - fmt.Println(string(resp.Body())) + return } + + ExitWithError = !helper.StreamTextResponse(resp) }, } func init() { + addLogsFlags(addonsLogsCmd) + addonsCmd.AddCommand(addonsLogsCmd) } diff --git a/cmd/audio_logs.go b/cmd/audio_logs.go index 558182de..9a9cb513 100644 --- a/cmd/audio_logs.go +++ b/cmd/audio_logs.go @@ -23,27 +23,29 @@ running on your Home Assistant system.`, log.WithField("args", args).Debug("audio logs") section := "audio" - command := "logs" - url, err := helper.URLHelper(section, command) + request, err := processLogsFlags(section, cmd) + if err != nil { fmt.Printf("Error: %v", err) ExitWithError = true return } - request := helper.GetRequest() - resp, err := request.SetHeader("Accept", "text/plain").Get(url) + resp, err := request.Send() if err != nil { fmt.Println(err) ExitWithError = true - } else { - fmt.Println(resp.String()) + return } + + ExitWithError = !helper.StreamTextResponse(resp) }, } func init() { + addLogsFlags(audioLogsCmd) + audioCmd.AddCommand(audioLogsCmd) } diff --git a/cmd/core_logs.go b/cmd/core_logs.go index c5162c87..efa00d23 100644 --- a/cmd/core_logs.go +++ b/cmd/core_logs.go @@ -23,27 +23,29 @@ running on your Home Assistant system.`, log.WithField("args", args).Debug("core logs") section := "core" - command := "logs" - url, err := helper.URLHelper(section, command) + request, err := processLogsFlags(section, cmd) + if err != nil { fmt.Printf("Error: %v", err) ExitWithError = true return } - request := helper.GetRequest() - resp, err := request.SetHeader("Accept", "text/plain").Get(url) + resp, err := request.Send() if err != nil { fmt.Println(err) ExitWithError = true - } else { - fmt.Println(resp.String()) + return } + + ExitWithError = !helper.StreamTextResponse(resp) }, } func init() { + addLogsFlags(coreLogsCmd) + coreCmd.AddCommand(coreLogsCmd) } diff --git a/cmd/dns_logs.go b/cmd/dns_logs.go index cc0bcdc8..889677b0 100644 --- a/cmd/dns_logs.go +++ b/cmd/dns_logs.go @@ -24,26 +24,28 @@ Allowing you to look at the log output generated by the Home Assistant DNS serve log.WithField("args", args).Debug("dns logs") section := "dns" - command := "logs" - url, err := helper.URLHelper(section, command) + request, err := processLogsFlags(section, cmd) + if err != nil { fmt.Printf("Error: %v", err) + ExitWithError = true return } - request := helper.GetRequest() - resp, err := request.SetHeader("Accept", "text/plain").Get(url) + resp, err := request.Send() if err != nil { fmt.Println(err) ExitWithError = true - } else { - fmt.Println(resp.String()) + return } + ExitWithError = !helper.StreamTextResponse(resp) }, } func init() { + addLogsFlags(dnsLogsCmd) + dnsCmd.AddCommand(dnsLogsCmd) } diff --git a/cmd/host.go b/cmd/host.go index 803ed585..6de2d014 100644 --- a/cmd/host.go +++ b/cmd/host.go @@ -1,6 +1,10 @@ package cmd import ( + "fmt" + "github.com/go-resty/resty/v2" + "github.com/home-assistant/cli/client" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -21,3 +25,57 @@ system, but also provides option to change the hostname of the system.`, func init() { rootCmd.AddCommand(hostCmd) } + +func addLogsFlags(cmd *cobra.Command) { + cmd.Flags().BoolP("follow", "f", false, "Continuously print new log entries") + cmd.Flags().Uint32P("lines", "n", 0, "Number of log entries to show") + cmd.Flags().StringP("boot", "b", "", "Logs of particular boot ID") + cmd.Flags().BoolP("verbose", "v", false, "Return logs in verbose format") + cmd.Flags().Lookup("follow").NoOptDefVal = "true" + cmd.Flags().Lookup("verbose").NoOptDefVal = "true" + + cmd.RegisterFlagCompletionFunc("follow", boolCompletions) + cmd.RegisterFlagCompletionFunc("verbose", boolCompletions) + cmd.RegisterFlagCompletionFunc("lines", cobra.NoFileCompletions) + cmd.RegisterFlagCompletionFunc("boot", hostBootCompletions) +} + +func processLogsFlags(section string, cmd *cobra.Command) (*resty.Request, error) { + command := "logs" + + boot, _ := cmd.Flags().GetString("boot") + if len(boot) > 0 { + command += "/boots/{boot}" + } + + follow, _ := cmd.Flags().GetBool("follow") + if follow { + command += "/follow" + } + + URL, err := client.URLHelper(section, command) + if err != nil { + return nil, err + } + + accept := "text/plain" + verbose, _ := cmd.Flags().GetBool("verbose") + if verbose { + accept = "text/x-log" + } + + /* Disable timeouts to allow following forever */ + request := client.GetRequestTimeout(0).SetHeader("Accept", accept).SetDoNotParseResponse(true) + + lines, _ := cmd.Flags().GetInt32("lines") + if lines > 0 { + rangeHeader := fmt.Sprintf("entries=:%d:", -(lines - 1)) + log.WithField("value", rangeHeader).Debug("Range header") + request.SetHeader("Range", rangeHeader) + } + + request.SetPathParam("boot", boot) + request.URL = URL + + return request, nil +} diff --git a/cmd/host_logs.go b/cmd/host_logs.go index 571beb27..581a726d 100644 --- a/cmd/host_logs.go +++ b/cmd/host_logs.go @@ -25,23 +25,8 @@ across services and boots. log.WithField("args", args).Debug("host logs") section := "host" - command := "logs" - identifier, _ := cmd.Flags().GetString("identifier") - boot, _ := cmd.Flags().GetString("boot") - if len(boot) > 0 { - command += "/boots/{boot}" - } - if len(identifier) > 0 { - command += "/identifiers/{identifier}" - } - - follow, _ := cmd.Flags().GetBool("follow") - if follow { - command += "/follow" - } - - url, err := helper.URLHelper(section, command) + request, err := processLogsFlags(section, cmd) if err != nil { fmt.Printf("Error: %v", err) @@ -49,26 +34,13 @@ across services and boots. return } - /* Disable timeouts to allow following forever */ - request := helper.GetRequestTimeout(0).SetHeader("Accept", "text/plain").SetDoNotParseResponse(true) - - lines, _ := cmd.Flags().GetInt32("lines") - if lines > 0 { - rangeHeader := fmt.Sprintf("entries=:%d:", -(lines - 1)) - log.WithField("value", rangeHeader).Debug("Range header") - request.SetHeader("Range", rangeHeader) - } - - if err != nil { - fmt.Printf("Error: %v", err) - ExitWithError = true - return + identifier, _ := cmd.Flags().GetString("identifier") + if len(identifier) > 0 { + request.URL += "/identifiers/{identifier}" } - request.SetPathParam("identifier", identifier) - request.SetPathParam("boot", boot) - resp, err := request.Get(url) + resp, err := request.Send() if err != nil { fmt.Println(err) @@ -81,11 +53,9 @@ across services and boots. } func init() { - hostLogsCmd.Flags().BoolP("follow", "f", false, "Continuously print new log entries") - hostLogsCmd.Flags().Int32P("lines", "n", 0, "Number of log entries to show") + addLogsFlags(hostLogsCmd) + hostLogsCmd.Flags().StringP("identifier", "t", "", "Show entries with the specified syslog identifier") - hostLogsCmd.Flags().StringP("boot", "b", "", "Logs of particular boot ID") - hostLogsCmd.Flags().Lookup("follow").NoOptDefVal = "true" hostCmd.AddCommand(hostLogsCmd) } diff --git a/cmd/host_logs_boots.go b/cmd/host_logs_boots.go index d0f8a76e..c9b7c4bc 100644 --- a/cmd/host_logs_boots.go +++ b/cmd/host_logs_boots.go @@ -6,6 +6,7 @@ import ( helper "github.com/home-assistant/cli/client" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" + "strings" ) var hostLogsBootsCmd = &cobra.Command{ @@ -39,3 +40,28 @@ Show all values that can be used with the boot arg to find logs. func init() { hostLogsCmd.AddCommand(hostLogsBootsCmd) } + +func hostBootCompletions(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + resp, err := helper.GenericJSONGet("host/logs/boots", "") + if err != nil || !resp.IsSuccess() { + return nil, cobra.ShellCompDirectiveNoFileComp + } + + var ret []string + data := resp.Result().(*helper.Response) + if data.Result == "ok" && data.Data["boots"] != nil { + if boots, ok := data.Data["boots"].(map[string]interface{}); ok { + for bootID, bootName := range boots { + s := bootName.(string) + if toComplete == "" || strings.HasPrefix(s, toComplete) { + ret = append(ret, s+"\tboot offset "+bootID) + } + } + } + } + + return ret, cobra.ShellCompDirectiveNoFileComp +} diff --git a/cmd/multicast_logs.go b/cmd/multicast_logs.go index 22902600..32398726 100644 --- a/cmd/multicast_logs.go +++ b/cmd/multicast_logs.go @@ -24,26 +24,29 @@ Allowing you to look at the log output generated by the Home Assistant Multicast log.WithField("args", args).Debug("multicast logs") section := "multicast" - command := "logs" - url, err := helper.URLHelper(section, command) + request, err := processLogsFlags(section, cmd) + if err != nil { fmt.Printf("Error: %v", err) + ExitWithError = true return } - request := helper.GetRequest() - resp, err := request.SetHeader("Accept", "text/plain").Get(url) + resp, err := request.Send() if err != nil { fmt.Println(err) ExitWithError = true - } else { - fmt.Println(resp.String()) + return } + + ExitWithError = !helper.StreamTextResponse(resp) }, } func init() { + addLogsFlags(multicastLogsCmd) + multicastCmd.AddCommand(multicastLogsCmd) } diff --git a/cmd/supervisor_logs.go b/cmd/supervisor_logs.go index 1023fac3..f5672350 100644 --- a/cmd/supervisor_logs.go +++ b/cmd/supervisor_logs.go @@ -2,7 +2,6 @@ package cmd import ( "fmt" - helper "github.com/home-assistant/cli/client" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -23,26 +22,29 @@ Supervisor running on your Home Assistant system.`, log.WithField("args", args).Debug("supervisor logs") section := "supervisor" - command := "logs" - url, err := helper.URLHelper(section, command) + request, err := processLogsFlags(section, cmd) + if err != nil { fmt.Printf("Error: %v", err) + ExitWithError = true return } - request := helper.GetRequest() - resp, err := request.SetHeader("Accept", "text/plain").Get(url) + resp, err := request.Send() if err != nil { fmt.Println(err) ExitWithError = true - } else { - fmt.Println(resp.String()) + return } + + ExitWithError = !helper.StreamTextResponse(resp) }, } func init() { + addLogsFlags(supervisorLogsCmd) + supervisorCmd.AddCommand(supervisorLogsCmd) }