mirror of https://github.com/dapr/cli.git
Adding JSON logging format and simplifying/centralizing spinner output
This commit is contained in:
parent
a888f5a818
commit
47d369d490
11
cmd/dapr.go
11
cmd/dapr.go
|
|
@ -11,6 +11,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/dapr/cli/pkg/api"
|
||||
"github.com/dapr/cli/pkg/print"
|
||||
"github.com/dapr/cli/pkg/standalone"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
|
@ -31,6 +32,8 @@ var RootCmd = &cobra.Command{
|
|||
Distributed Application Runtime`,
|
||||
}
|
||||
|
||||
var logAsJSON bool
|
||||
|
||||
// Execute adds all child commands to the root command.
|
||||
func Execute(version, apiVersion string) {
|
||||
RootCmd.Version = version
|
||||
|
|
@ -52,7 +55,15 @@ func setVersion() {
|
|||
}
|
||||
|
||||
func initConfig() {
|
||||
if logAsJSON {
|
||||
print.EnableJSONFormat()
|
||||
}
|
||||
|
||||
viper.SetEnvPrefix("dapr")
|
||||
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
|
||||
viper.AutomaticEnv()
|
||||
}
|
||||
|
||||
func init() {
|
||||
RootCmd.PersistentFlags().BoolVarP(&logAsJSON, "log-as-json", "", false, "Log output in JSON format")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,10 +11,7 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/briandowns/spinner"
|
||||
"github.com/dapr/cli/pkg/print"
|
||||
helm "helm.sh/helm/v3/pkg/action"
|
||||
"helm.sh/helm/v3/pkg/chart"
|
||||
|
|
@ -43,30 +40,17 @@ type InitConfiguration struct {
|
|||
// Init deploys the Dapr operator using the supplied runtime version.
|
||||
func Init(config InitConfiguration) error {
|
||||
msg := "Deploying the Dapr control plane to your cluster..."
|
||||
var s *spinner.Spinner
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
print.InfoStatusEvent(os.Stdout, msg)
|
||||
} else {
|
||||
s = spinner.New(spinner.CharSets[0], 100*time.Millisecond)
|
||||
s.Writer = os.Stdout
|
||||
s.Color("cyan")
|
||||
s.Suffix = fmt.Sprintf(" %s", msg)
|
||||
s.Start()
|
||||
}
|
||||
stopSpinning := print.Spinner(os.Stdout, msg)
|
||||
defer stopSpinning(print.Failure)
|
||||
|
||||
err := install(config)
|
||||
if err != nil {
|
||||
if s != nil {
|
||||
s.Stop()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if s != nil {
|
||||
s.Stop()
|
||||
print.SuccessStatusEvent(os.Stdout, msg)
|
||||
}
|
||||
stopSpinning(print.Success)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,10 +6,14 @@
|
|||
package print
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"runtime"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/briandowns/spinner"
|
||||
"github.com/fatih/color"
|
||||
)
|
||||
|
||||
|
|
@ -17,6 +21,13 @@ const (
|
|||
windowsOS = "windows"
|
||||
)
|
||||
|
||||
type Result bool
|
||||
|
||||
const (
|
||||
Success Result = true
|
||||
Failure Result = false
|
||||
)
|
||||
|
||||
var (
|
||||
Yellow = color.New(color.FgHiYellow, color.Bold).SprintFunc()
|
||||
Green = color.New(color.FgHiGreen, color.Bold).SprintFunc()
|
||||
|
|
@ -27,9 +38,21 @@ var (
|
|||
WhiteBold = color.New(color.FgWhite, color.Bold).SprintFunc()
|
||||
)
|
||||
|
||||
var logAsJSON bool
|
||||
|
||||
func EnableJSONFormat() {
|
||||
logAsJSON = true
|
||||
}
|
||||
|
||||
func IsJSONFormat() bool {
|
||||
return logAsJSON
|
||||
}
|
||||
|
||||
// SuccessStatusEvent reports on a success event.
|
||||
func SuccessStatusEvent(w io.Writer, fmtstr string, a ...interface{}) {
|
||||
if runtime.GOOS == windowsOS {
|
||||
if logAsJSON {
|
||||
logJSON(w, "success", fmt.Sprintf(fmtstr, a...))
|
||||
} else if runtime.GOOS == windowsOS {
|
||||
fmt.Fprintf(w, "%s\n", fmt.Sprintf(fmtstr, a...))
|
||||
} else {
|
||||
fmt.Fprintf(w, "✅ %s\n", fmt.Sprintf(fmtstr, a...))
|
||||
|
|
@ -38,7 +61,9 @@ func SuccessStatusEvent(w io.Writer, fmtstr string, a ...interface{}) {
|
|||
|
||||
// FailureStatusEvent reports on a failure event.
|
||||
func FailureStatusEvent(w io.Writer, fmtstr string, a ...interface{}) {
|
||||
if runtime.GOOS == windowsOS {
|
||||
if logAsJSON {
|
||||
logJSON(w, "failure", fmt.Sprintf(fmtstr, a...))
|
||||
} else if runtime.GOOS == windowsOS {
|
||||
fmt.Fprintf(w, "%s\n", fmt.Sprintf(fmtstr, a...))
|
||||
} else {
|
||||
fmt.Fprintf(w, "❌ %s\n", fmt.Sprintf(fmtstr, a...))
|
||||
|
|
@ -47,7 +72,9 @@ func FailureStatusEvent(w io.Writer, fmtstr string, a ...interface{}) {
|
|||
|
||||
// WarningStatusEvent reports on a failure event.
|
||||
func WarningStatusEvent(w io.Writer, fmtstr string, a ...interface{}) {
|
||||
if runtime.GOOS == windowsOS {
|
||||
if logAsJSON {
|
||||
logJSON(w, "warning", fmt.Sprintf(fmtstr, a...))
|
||||
} else if runtime.GOOS == windowsOS {
|
||||
fmt.Fprintf(w, "%s\n", fmt.Sprintf(fmtstr, a...))
|
||||
} else {
|
||||
fmt.Fprintf(w, "⚠ %s\n", fmt.Sprintf(fmtstr, a...))
|
||||
|
|
@ -56,7 +83,9 @@ func WarningStatusEvent(w io.Writer, fmtstr string, a ...interface{}) {
|
|||
|
||||
// PendingStatusEvent reports on a pending event.
|
||||
func PendingStatusEvent(w io.Writer, fmtstr string, a ...interface{}) {
|
||||
if runtime.GOOS == windowsOS {
|
||||
if logAsJSON {
|
||||
logJSON(w, "pending", fmt.Sprintf(fmtstr, a...))
|
||||
} else if runtime.GOOS == windowsOS {
|
||||
fmt.Fprintf(w, "%s\n", fmt.Sprintf(fmtstr, a...))
|
||||
} else {
|
||||
fmt.Fprintf(w, "⌛ %s\n", fmt.Sprintf(fmtstr, a...))
|
||||
|
|
@ -65,9 +94,68 @@ func PendingStatusEvent(w io.Writer, fmtstr string, a ...interface{}) {
|
|||
|
||||
// InfoStatusEvent reports status information on an event.
|
||||
func InfoStatusEvent(w io.Writer, fmtstr string, a ...interface{}) {
|
||||
if runtime.GOOS == windowsOS {
|
||||
if logAsJSON {
|
||||
logJSON(w, "info", fmt.Sprintf(fmtstr, a...))
|
||||
} else if runtime.GOOS == windowsOS {
|
||||
fmt.Fprintf(w, "%s\n", fmt.Sprintf(fmtstr, a...))
|
||||
} else {
|
||||
fmt.Fprintf(w, "ℹ️ %s\n", fmt.Sprintf(fmtstr, a...))
|
||||
}
|
||||
}
|
||||
|
||||
func Spinner(w io.Writer, fmtstr string, a ...interface{}) func(result Result) {
|
||||
msg := fmt.Sprintf(fmtstr, a...)
|
||||
var once sync.Once
|
||||
var s *spinner.Spinner
|
||||
|
||||
if logAsJSON {
|
||||
logJSON(w, "pending", msg)
|
||||
} else if runtime.GOOS == windowsOS {
|
||||
fmt.Fprintf(w, "%s\n", msg)
|
||||
|
||||
return func(Result) {} // Return a dummy func
|
||||
} else {
|
||||
s = spinner.New(spinner.CharSets[0], 100*time.Millisecond)
|
||||
s.Writer = w
|
||||
s.Color("cyan")
|
||||
s.Suffix = fmt.Sprintf(" %s", msg)
|
||||
s.Start()
|
||||
}
|
||||
|
||||
return func(result Result) {
|
||||
once.Do(func() {
|
||||
if s != nil {
|
||||
s.Stop()
|
||||
}
|
||||
if result {
|
||||
SuccessStatusEvent(w, msg)
|
||||
} else {
|
||||
FailureStatusEvent(w, msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func logJSON(w io.Writer, status, message string) {
|
||||
type jsonLog struct {
|
||||
Time time.Time `json:"time"`
|
||||
Status string `json:"status"`
|
||||
Message string `json:"msg"`
|
||||
}
|
||||
|
||||
l := jsonLog{
|
||||
Time: time.Now().UTC(),
|
||||
Status: status,
|
||||
Message: message,
|
||||
}
|
||||
jsonBytes, err := json.Marshal(&l)
|
||||
if err != nil {
|
||||
// Fall back on printing the simple message without JSON.
|
||||
// This is unlikely.
|
||||
fmt.Fprintln(w, message)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, "%s\n", string(jsonBytes))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,9 +21,7 @@ import (
|
|||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/briandowns/spinner"
|
||||
"github.com/dapr/cli/pkg/print"
|
||||
cli_ver "github.com/dapr/cli/pkg/version"
|
||||
"github.com/dapr/cli/utils"
|
||||
|
|
@ -134,16 +132,8 @@ func Init(runtimeVersion, dashboardVersion string, dockerNetwork string, slimMod
|
|||
wg.Add(len(initSteps))
|
||||
|
||||
msg := "Downloading binaries and setting up components..."
|
||||
var s *spinner.Spinner
|
||||
if runtime.GOOS == daprWindowsOS {
|
||||
print.InfoStatusEvent(os.Stdout, msg)
|
||||
} else {
|
||||
s = spinner.New(spinner.CharSets[0], 100*time.Millisecond)
|
||||
s.Writer = os.Stdout
|
||||
s.Color("cyan")
|
||||
s.Suffix = fmt.Sprintf(" %s", msg)
|
||||
s.Start()
|
||||
}
|
||||
stopSpinning := print.Spinner(os.Stdout, msg)
|
||||
defer stopSpinning(print.Failure)
|
||||
|
||||
// Make default components directory
|
||||
err = makeDefaultComponentsDir()
|
||||
|
|
@ -174,16 +164,11 @@ func Init(runtimeVersion, dashboardVersion string, dockerNetwork string, slimMod
|
|||
|
||||
for err := range errorChan {
|
||||
if err != nil {
|
||||
if s != nil {
|
||||
s.Stop()
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if s != nil {
|
||||
s.Stop()
|
||||
}
|
||||
stopSpinning(print.Success)
|
||||
|
||||
msg = "Downloaded binaries and completed components set up."
|
||||
print.SuccessStatusEvent(os.Stdout, msg)
|
||||
|
|
|
|||
Loading…
Reference in New Issue