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"
|
"strings"
|
||||||
|
|
||||||
"github.com/dapr/cli/pkg/api"
|
"github.com/dapr/cli/pkg/api"
|
||||||
|
"github.com/dapr/cli/pkg/print"
|
||||||
"github.com/dapr/cli/pkg/standalone"
|
"github.com/dapr/cli/pkg/standalone"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
|
@ -31,6 +32,8 @@ var RootCmd = &cobra.Command{
|
||||||
Distributed Application Runtime`,
|
Distributed Application Runtime`,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var logAsJSON bool
|
||||||
|
|
||||||
// Execute adds all child commands to the root command.
|
// Execute adds all child commands to the root command.
|
||||||
func Execute(version, apiVersion string) {
|
func Execute(version, apiVersion string) {
|
||||||
RootCmd.Version = version
|
RootCmd.Version = version
|
||||||
|
|
@ -52,7 +55,15 @@ func setVersion() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func initConfig() {
|
func initConfig() {
|
||||||
|
if logAsJSON {
|
||||||
|
print.EnableJSONFormat()
|
||||||
|
}
|
||||||
|
|
||||||
viper.SetEnvPrefix("dapr")
|
viper.SetEnvPrefix("dapr")
|
||||||
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
|
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
|
||||||
viper.AutomaticEnv()
|
viper.AutomaticEnv()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
RootCmd.PersistentFlags().BoolVarP(&logAsJSON, "log-as-json", "", false, "Log output in JSON format")
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/briandowns/spinner"
|
|
||||||
"github.com/dapr/cli/pkg/print"
|
"github.com/dapr/cli/pkg/print"
|
||||||
helm "helm.sh/helm/v3/pkg/action"
|
helm "helm.sh/helm/v3/pkg/action"
|
||||||
"helm.sh/helm/v3/pkg/chart"
|
"helm.sh/helm/v3/pkg/chart"
|
||||||
|
|
@ -43,30 +40,17 @@ type InitConfiguration struct {
|
||||||
// Init deploys the Dapr operator using the supplied runtime version.
|
// Init deploys the Dapr operator using the supplied runtime version.
|
||||||
func Init(config InitConfiguration) error {
|
func Init(config InitConfiguration) error {
|
||||||
msg := "Deploying the Dapr control plane to your cluster..."
|
msg := "Deploying the Dapr control plane to your cluster..."
|
||||||
var s *spinner.Spinner
|
|
||||||
|
|
||||||
if runtime.GOOS == "windows" {
|
stopSpinning := print.Spinner(os.Stdout, msg)
|
||||||
print.InfoStatusEvent(os.Stdout, msg)
|
defer stopSpinning(print.Failure)
|
||||||
} 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()
|
|
||||||
}
|
|
||||||
|
|
||||||
err := install(config)
|
err := install(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if s != nil {
|
|
||||||
s.Stop()
|
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if s != nil {
|
stopSpinning(print.Success)
|
||||||
s.Stop()
|
|
||||||
print.SuccessStatusEvent(os.Stdout, msg)
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,14 @@
|
||||||
package print
|
package print
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/briandowns/spinner"
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -17,6 +21,13 @@ const (
|
||||||
windowsOS = "windows"
|
windowsOS = "windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Result bool
|
||||||
|
|
||||||
|
const (
|
||||||
|
Success Result = true
|
||||||
|
Failure Result = false
|
||||||
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
Yellow = color.New(color.FgHiYellow, color.Bold).SprintFunc()
|
Yellow = color.New(color.FgHiYellow, color.Bold).SprintFunc()
|
||||||
Green = color.New(color.FgHiGreen, color.Bold).SprintFunc()
|
Green = color.New(color.FgHiGreen, color.Bold).SprintFunc()
|
||||||
|
|
@ -27,9 +38,21 @@ var (
|
||||||
WhiteBold = color.New(color.FgWhite, color.Bold).SprintFunc()
|
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.
|
// SuccessStatusEvent reports on a success event.
|
||||||
func SuccessStatusEvent(w io.Writer, fmtstr string, a ...interface{}) {
|
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...))
|
fmt.Fprintf(w, "%s\n", fmt.Sprintf(fmtstr, a...))
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(w, "✅ %s\n", fmt.Sprintf(fmtstr, a...))
|
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.
|
// FailureStatusEvent reports on a failure event.
|
||||||
func FailureStatusEvent(w io.Writer, fmtstr string, a ...interface{}) {
|
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...))
|
fmt.Fprintf(w, "%s\n", fmt.Sprintf(fmtstr, a...))
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(w, "❌ %s\n", fmt.Sprintf(fmtstr, a...))
|
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.
|
// WarningStatusEvent reports on a failure event.
|
||||||
func WarningStatusEvent(w io.Writer, fmtstr string, a ...interface{}) {
|
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...))
|
fmt.Fprintf(w, "%s\n", fmt.Sprintf(fmtstr, a...))
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(w, "⚠ %s\n", fmt.Sprintf(fmtstr, a...))
|
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.
|
// PendingStatusEvent reports on a pending event.
|
||||||
func PendingStatusEvent(w io.Writer, fmtstr string, a ...interface{}) {
|
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...))
|
fmt.Fprintf(w, "%s\n", fmt.Sprintf(fmtstr, a...))
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(w, "⌛ %s\n", fmt.Sprintf(fmtstr, a...))
|
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.
|
// InfoStatusEvent reports status information on an event.
|
||||||
func InfoStatusEvent(w io.Writer, fmtstr string, a ...interface{}) {
|
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...))
|
fmt.Fprintf(w, "%s\n", fmt.Sprintf(fmtstr, a...))
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintf(w, "ℹ️ %s\n", fmt.Sprintf(fmtstr, a...))
|
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"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/briandowns/spinner"
|
|
||||||
"github.com/dapr/cli/pkg/print"
|
"github.com/dapr/cli/pkg/print"
|
||||||
cli_ver "github.com/dapr/cli/pkg/version"
|
cli_ver "github.com/dapr/cli/pkg/version"
|
||||||
"github.com/dapr/cli/utils"
|
"github.com/dapr/cli/utils"
|
||||||
|
|
@ -134,16 +132,8 @@ func Init(runtimeVersion, dashboardVersion string, dockerNetwork string, slimMod
|
||||||
wg.Add(len(initSteps))
|
wg.Add(len(initSteps))
|
||||||
|
|
||||||
msg := "Downloading binaries and setting up components..."
|
msg := "Downloading binaries and setting up components..."
|
||||||
var s *spinner.Spinner
|
stopSpinning := print.Spinner(os.Stdout, msg)
|
||||||
if runtime.GOOS == daprWindowsOS {
|
defer stopSpinning(print.Failure)
|
||||||
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()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make default components directory
|
// Make default components directory
|
||||||
err = makeDefaultComponentsDir()
|
err = makeDefaultComponentsDir()
|
||||||
|
|
@ -174,16 +164,11 @@ func Init(runtimeVersion, dashboardVersion string, dockerNetwork string, slimMod
|
||||||
|
|
||||||
for err := range errorChan {
|
for err := range errorChan {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if s != nil {
|
|
||||||
s.Stop()
|
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if s != nil {
|
stopSpinning(print.Success)
|
||||||
s.Stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = "Downloaded binaries and completed components set up."
|
msg = "Downloaded binaries and completed components set up."
|
||||||
print.SuccessStatusEvent(os.Stdout, msg)
|
print.SuccessStatusEvent(os.Stdout, msg)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue