package common import ( "bufio" "fmt" "os" "strconv" "strings" ) // ErrWithExitCode wraps error and exposes an ExitCode method type ErrWithExitCode interface { ExitCode() int } // LogFail is the failure log formatter // prints text to stderr and exits with status 1 func LogFail(text string) { fmt.Fprintln(os.Stderr, fmt.Sprintf(" ! %s", text)) os.Exit(1) } // LogFailWithError is the failure log formatter // prints text to stderr and exits with the specified exit code func LogFailWithError(err error) { fmt.Fprintln(os.Stderr, fmt.Sprintf(" ! %s", err.Error())) if errExit, ok := err.(ErrWithExitCode); ok { os.Exit(errExit.ExitCode()) } os.Exit(1) } // LogFailQuiet is the failure log formatter (with quiet option) // prints text to stderr and exits with status 1 func LogFailQuiet(text string) { if os.Getenv("DOKKU_QUIET_OUTPUT") == "" { fmt.Fprintln(os.Stderr, fmt.Sprintf(" ! %s", text)) } os.Exit(1) } // Log is the log formatter func Log(text string) { fmt.Println(text) } // LogQuiet is the log formatter (with quiet option) func LogQuiet(text string) { if os.Getenv("DOKKU_QUIET_OUTPUT") == "" { fmt.Println(text) } } // LogInfo1 is the info1 header formatter func LogInfo1(text string) { fmt.Println(fmt.Sprintf("-----> %s", text)) } // LogInfo1Quiet is the info1 header formatter (with quiet option) func LogInfo1Quiet(text string) { if os.Getenv("DOKKU_QUIET_OUTPUT") == "" { LogInfo1(text) } } // LogInfo2 is the info2 header formatter func LogInfo2(text string) { fmt.Println(fmt.Sprintf("=====> %s", text)) } // LogInfo2Quiet is the info2 header formatter (with quiet option) func LogInfo2Quiet(text string) { if os.Getenv("DOKKU_QUIET_OUTPUT") == "" { LogInfo2(text) } } // LogVerbose is the verbose log formatter // prints indented text to stdout func LogVerbose(text string) { fmt.Println(fmt.Sprintf(" %s", text)) } // LogVerboseQuiet is the verbose log formatter // prints indented text to stdout (with quiet option) func LogVerboseQuiet(text string) { if os.Getenv("DOKKU_QUIET_OUTPUT") == "" { LogVerbose(text) } } // LogVerboseQuietContainerLogs is the verbose log formatter for container logs func LogVerboseQuietContainerLogs(containerID string) { sc := NewShellCmdWithArgs(DockerBin(), "container", "logs", containerID) sc.ShowOutput = false b, err := sc.CombinedOutput() if err != nil { LogExclaim(fmt.Sprintf("Failed to fetch container logs: %s", containerID)) } output := strings.TrimSpace(string(b)) if len(output) == 0 { return } for _, line := range strings.Split(output, "\n") { if line != "" { LogVerboseQuiet(line) } } } // LogVerboseQuietContainerLogsTail is the verbose log formatter for container logs with tail mode enabled func LogVerboseQuietContainerLogsTail(containerID string, lines int, tail bool) { args := []string{"container", "logs", containerID} if lines > 0 { args = append(args, "--tail", strconv.Itoa(lines)) } if tail { args = append(args, "--follow") } sc := NewShellCmdWithArgs(DockerBin(), args...) stdout, _ := sc.Command.StdoutPipe() sc.Command.Start() scanner := bufio.NewScanner(stdout) scanner.Split(bufio.ScanLines) for scanner.Scan() { m := scanner.Text() LogVerboseQuiet(m) } sc.Command.Wait() } // LogWarn is the warning log formatter func LogWarn(text string) { fmt.Fprintln(os.Stderr, fmt.Sprintf(" ! %s", text)) } // LogExclaim is the log exclaim formatter func LogExclaim(text string) { fmt.Println(fmt.Sprintf(" ! %s", text)) } // LogStderr is the stderr log formatter func LogStderr(text string) { fmt.Fprintln(os.Stderr, text) } // LogDebug is the debug log formatter func LogDebug(text string) { if os.Getenv("DOKKU_TRACE") == "1" { fmt.Fprintln(os.Stderr, fmt.Sprintf(" ? %s", strings.TrimPrefix(text, " ? "))) } }