func (tokens LogTokens) Print() { defer color.ResetColor() var defColor color.Color = color.White var defBright bool = true for _, token := range tokens { if token.Type >= TOKEN_DEBUG { defColor, defBright, _ = token.Type.getFgColor() } } for _, token := range tokens { fg, bright, specific := token.Type.getFgColor() if !specific { fg = defColor bright = defBright } color.Foreground(fg, bright) fmt.Print(token.Text) } fmt.Print("\n") }
func init() { defer ct.ResetColor() // WriteOutLevel(OUT_LEVEL_WARNING) // WriteOut("#####################################\n Chandra Application") // WriteOut("\n#####################################\n") // WriteOutLevel(OUT_LEVEL_RESET) }
// outputColorStack is use when -logcolor is enabled. // colored stack printing is allowed to be inefficient because it's a local development feature. func outputColorStack(stacks []byte, s severity) { r := bytes.NewReader(stacks) scanner := bufio.NewScanner(r) for scanner.Scan() { l := scanner.Bytes() if len(l) > 0 && l[0] == "\t"[0] { addroffset := bytes.LastIndex(l, []byte(" ")) linumoffset := bytes.LastIndex(l, []byte(":")) if addroffset == -1 || linumoffset == -1 { os.Stderr.Write(l) goto eol } srcpath := l[0:linumoffset] hlstart := 0 hlstacksrc.Lock() if hlstacksrc.v != nil { for _, v := range hlstacksrc.v { offs := bytes.Index(srcpath, v) if offs > hlstart { hlstart = offs } } } hlstacksrc.Unlock() if hlstart > 0 { os.Stderr.Write(srcpath[:hlstart]) ct.Foreground(ct.Blue, true) os.Stderr.Write(srcpath[hlstart:]) ct.ResetColor() } else { os.Stderr.Write(srcpath) } os.Stderr.WriteString(":") printColor(s) os.Stderr.Write(l[linumoffset+1 : addroffset]) ct.ResetColor() os.Stderr.Write(l[addroffset:]) } else { os.Stderr.Write(l) } eol: os.Stderr.WriteString("\n") } if err := scanner.Err(); err != nil { fmt.Fprintln(os.Stderr, "reading standard input:", err) } }
func WriteOut(s string, ars ...interface{}) { if len(ars) > 0 { fmt.Printf(s, ars) } else { fmt.Print(s) } ct.ResetColor() }
// Write out a single coloured line func (of *OutletFactory) WriteLine(left, right string, leftC, rightC ct.Color, isError bool) { of.Lock() defer of.Unlock() ct.ChangeColor(leftC, true, ct.None, false) formatter := fmt.Sprintf("%%-%ds | ", of.Padding) fmt.Printf(formatter, left) if isError { ct.ChangeColor(ct.Red, true, ct.None, true) } else { ct.ResetColor() } fmt.Println(right) if isError { ct.ResetColor() } }
func (e *BigcommerceAppLogEvent) PrintLine(index int) { fmt.Printf("[%d] ", index) fmt.Printf("%s ", e.SyslogTime.Format("2006-01-02 15:04:05")) ct.ChangeColor(ct.Yellow, false, ct.None, false) fmt.Print("bigcommerce-app ") ct.ChangeColor(ct.Cyan, false, ct.None, false) fmt.Printf("%s-%d ", e.LogLevel, e.StoreContext.StoreId) ct.ResetColor() fmt.Printf("%s\n", e.Content) }
func (e *GenericLogEvent) PrintLine(index int) { fmt.Printf("[%d] ", index) fmt.Print(e.SyslogTime.Format("2006-01-02 15:04:05") + " ") ct.ChangeColor(ct.Yellow, false, ct.None, false) fmt.Print("generic ") ct.ChangeColor(ct.Cyan, false, ct.None, false) fmt.Printf("%s ", e.Name) ct.ResetColor() fmt.Printf("%s\n", e.Content) }
func (e *ProcessLogEvent) PrintLine(index int) { fmt.Printf("[%d] ", index) fmt.Print(e.SyslogTime.Format("2006-01-02 15:04:05") + " ") ct.ChangeColor(ct.Yellow, false, ct.None, false) fmt.Print("process ") ct.ChangeColor(ct.Cyan, false, ct.None, false) fmt.Printf("%s-%d ", e.Name, e.ProcessId) ct.ResetColor() fmt.Printf("%s\n", e.Content) }
func (e *PhpStackTraceLogEvent) PrintLine(index int) { fmt.Printf("[%d] ", index) fmt.Print(e.SyslogTime.Format("2006-01-02 15:04:05") + " ") ct.ChangeColor(ct.Yellow, false, ct.None, false) fmt.Print("php-stack-trace ") ct.ChangeColor(ct.Cyan, false, ct.None, false) fmt.Printf("%d-%s-%d ", e.Number, e.File, e.Line) ct.ResetColor() fmt.Printf("%s\n", e.Method) }
func WriteOutLevel(l string) { switch l { case OUT_LEVEL_WARNING: ct.ChangeColor(ct.Yellow, true, ct.None, false) case OUT_LEVEL_ERROR: ct.ChangeColor(ct.Red, true, ct.None, false) case OUT_LEVEL_INFO: ct.ChangeColor(ct.Cyan, true, ct.None, false) default: ct.ResetColor() } }
func print(timeFormat string, le *logEntry) { var level string switch le.level { case Info: level = "INFO " ct.Foreground(ct.Cyan, false) case Warning: level = "WARNING " ct.Foreground(ct.Yellow, false) case Error: level = "ERROR " ct.Foreground(ct.Red, false) case Critical: level = "CRITICAL" ct.ChangeColor(ct.Black, false, ct.Red, false) case Fatal: level = "FATAL " ct.ResetColor() } fmt.Println(le.time.Format(timeFormat), level, le.message) ct.ResetColor() }
func (e *NginxErrorLogEvent) PrintLine(index int) { fmt.Printf("[%d] ", index) if e.LogLevel == "error" { fmt.Print(e.SyslogTime.Format("2006-01-02 15:04:05") + " ") ct.ChangeColor(ct.Yellow, false, ct.Red, false) fmt.Print("nginx-error ") ct.ChangeColor(ct.Cyan, false, ct.Red, false) fmt.Printf("%s ", e.LogLevel) ct.ChangeColor(ct.None, false, ct.Red, false) fmt.Printf("%s %s\n", e.Request.Uri, e.Content) ct.ResetColor() } else { fmt.Print(e.SyslogTime.Format("2006-01-02 15:04:05") + " ") ct.ChangeColor(ct.Yellow, false, ct.None, false) fmt.Print("nginx-error ") ct.ChangeColor(ct.Cyan, false, ct.None, false) fmt.Printf("%s ", e.LogLevel) ct.ResetColor() fmt.Printf("%s %s\n", e.Request.Uri, e.Content) } }
func (cl *coloredLogger) ScenarioStart(scenarioHeading string) { msg := formatScenario(scenarioHeading) Log.Info(msg) indentedText := indent(msg, scenarioIndentation) if level == logging.INFO { cl.headingText.WriteString(indentedText + spaces(4)) cl.writeToConsole(cl.headingText.String(), ct.None, false) } else { ct.Foreground(ct.Yellow, false) ConsoleWrite(indentedText) ct.ResetColor() } }
// A simple function to print message with colors. func ColoredPrint(thecolor color.Color, bold bool, values ...interface{}) { // change the color of the terminal color.ChangeColor( thecolor, bold, None, false, ) // print fmt.Print(values...) // reset the color color.ResetColor() }
func TestGetConsoleColor(t *testing.T) { for b := uint32(0); b < 6; b++ { for g := uint32(0); g < 6; g++ { for r := uint32(0); r < 6; r++ { m, l, h, j, k := GetConsoleColor(r*0x33/4, g*0x33/4, b*0x33/4) ct.ChangeColor(l, h, j, k) c := clist64[m : m+1] c = c + c + c + c if k { fmt.Printf("%s%x", c, (j-1)<<1) } else { fmt.Printf("%s%x", c, (j - 1)) } ct.ResetColor() fmt.Printf("#%02x%02x%02x ", r*0x33, g*0x33, b*0x33) } fmt.Print("\n") } } }
// 将图片渲染到文字(有颜色版) func ShowColor(iw io.Writer, img image.Image, console Console) { // Lanczos3缩放图片到控制台屏幕大小 w := console.ScreenW - 1 // 标宽 换行符竟然也算一个? s := img.Bounds().Size() // 标高 = 结果高 * 宽高比 = (原高 / 原宽 * 标宽) * 宽高比 h := uint(float64(s.Y) / float64(s.X) * float64(w) * console.Ratio()) m := resize.Resize(w, h, img, resize.Bicubic) for y := 0; y < int(h); y++ { for x := (0); x < int(w); x++ { r, g, b, a := m.At(x, y).RGBA() r, g, b, a = r>>10, g>>10, b>>10, a>>10 // 转换到6位色 0~63 r, g, b = r*a/63, g*a/63, b*a/63 // Alpha混合 m, fg, fgl, bg, bgl := GetConsoleColor(r, g, b) ct.ChangeColor(fg, fgl, bg, bgl) // cindex := (r + g + b) / 3 io.WriteString(iw, clist64[m:m+1]) } io.WriteString(iw, "\n") } ct.ResetColor() }
func (e *NginxAccessLogEvent) PrintLine(index int) { background := ct.None bold := false if e.Request.StatusCode >= 500 { background = ct.Red bold = false } else { background = ct.None bold = true } fmt.Printf("[%d] ", index) fmt.Print(e.Time.Format("2006-01-02 15:04:05") + " ") ct.ChangeColor(ct.Yellow, bold, background, false) fmt.Print("nginx-access ") ct.ChangeColor(ct.Cyan, bold, background, false) fmt.Printf("%s-%d ", e.Request.Method, e.Request.StatusCode) fmt.Printf("%s\n", e.Request.Uri) ct.ResetColor() }
func (t *textLogger) Write(entry Entry) { if t.ttyOutput { ct.ChangeColor(entry.Level.Color, entry.Level.Bright, ct.None, false) } text := strings.TrimSpace(entry.Message) if entry.Level.Level >= WarnLevel.Level { text = fmt.Sprintf("[%s from %s]\n", entry.ID, entry.Origin) + text } if strings.Contains(text, "\n") { // separate multiline comments with newlines if !t.lastNewline { fmt.Fprintln(t.out) // separate from previous one-line log msg } text = text + "\n" t.lastNewline = true } else { t.lastNewline = false } fmt.Fprintln(t.out, entry.Level.Prefix+strings.Replace(text, "\n", "\n ", -1)) if t.ttyOutput { ct.ResetColor() } }
func (e *PhpLogEvent) PrintFull() { fmt.Printf("\n---------- PHP LOG EVENT ----------\n") writer := new(tabwriter.Writer) writer.Init(os.Stdout, 0, 8, 2, ' ', 0) fmt.Fprintf( writer, "SyslogTime:\t%s\n", e.SyslogTime.Format("2006-01-02 15:04:05"), ) fmt.Fprintf(writer, "LogLevel:\t%s\n", e.LogLevel) fmt.Fprintf(writer, "Content:\t%s\n", e.Content) fmt.Fprintf(writer, "File:\t%s\n", e.File) fmt.Fprintf(writer, "Line:\t%d\n", e.Line) writer.Flush() ct.ChangeColor(ct.White, true, ct.None, false) fmt.Print("\nStack trace\n") ct.ResetColor() for _, phpStackTraceLogEvent := range e.StackTraceEvents { fmt.Fprintf( writer, "%d.\t%s\t%s\t%d\n", phpStackTraceLogEvent.Number, phpStackTraceLogEvent.Method, phpStackTraceLogEvent.File, phpStackTraceLogEvent.Line, ) } writer.Flush() fmt.Printf("\n---------- PHP LOG EVENT ----------\n") }
func (e *PhpLogEvent) PrintLine(index int) { background := ct.None switch e.LogLevel { case "Notice": case "Warning": background = ct.None break case "Fatal error": background = ct.Red break case "Catchable fatal error": background = ct.Red break case "Parse error": background = ct.Red break case "SQL Error": background = ct.Red break case "Strict standards": background = ct.None break default: log.Fatalf(e.LogLevel) } fmt.Printf("[%d] ", index) fmt.Print(e.SyslogTime.Format("2006-01-02 15:04:05") + " ") ct.ChangeColor(ct.Yellow, false, background, false) fmt.Print("php ") ct.ChangeColor(ct.Cyan, false, background, false) fmt.Printf("%s-%s-%d ", e.LogLevel, e.File, e.Line) ct.ChangeColor(ct.None, false, background, false) fmt.Printf("%s\n", e.Content) ct.ResetColor() }
func Error(format string, a ...interface{}) { defer color.ResetColor() color.Foreground(color.Red, true) fmt.Println(fmt.Sprintf(format, a...)) }
func (c *coloredConsole) displayMessage(msg string, color ct.Color) { ct.Foreground(color, false) defer ct.ResetColor() fmt.Fprint(c.writer, msg) c.writer.Print() }
// Changes the color for error messages. Good for one line heading. Any lengthy response should probably not be colored with a red background. func errorLabel(message string) { ct.ChangeColor(ct.White, true, ct.Red, false) fmt.Print(message) ct.ResetColor() fmt.Println("") }
// Changes the color for the messages to green for success. func successLabel(message string) { ct.Foreground(ct.Green, true) fmt.Print(message) ct.ResetColor() fmt.Println("") }
func (gj *GithubJSON) summarize() (skipped bool) { switch gj.GetType() { case "Project": if summary == false { gcolor.ChangeColor(gcolor.Green, true, gcolor.None, false) fmt.Println(gj.Full_Name) gcolor.ResetColor() if len(gj.Description) > 0 { fmt.Println(gj.Description) } if gj.Open_Issues > 0 { fmt.Printf("https://github.com/%s/issues : %d issues\n", gj.Full_Name, gj.Open_Issues) } fmt.Printf("forked: %d watched: %d\n", gj.Forks_Count, gj.Watchers_Count) gcolor.ChangeColor(gcolor.Blue, true, gcolor.None, false) fmt.Printf("%s\n\n", gj.Html_Url) gcolor.ResetColor() } else { if gj.Open_Issues > 0 { format("%s %d - %d open", gj.Full_Name, gj.Watchers_Count, gj.Open_Issues) } else { format("%s %d", gj.Full_Name, gj.Watchers_Count) } } case "WatchEvent": skipped = format("%s star %s", gj.Actor.Login, gj.Repo.Name) case "FollowEvent": skipped = format("%s follow %s", gj.Actor.Login, gj.Payload.Target.Login) case "IssuesEvent": switch gj.Payload.Action { case "created": skipped = format("%s comment issue %d %s", gj.Actor.Login, gj.Payload.Issue.Number, gj.Repo.Name) case "opened": skipped = format("%s made issue %d %s", gj.Actor.Login, gj.Payload.Issue.Number, gj.Repo.Name) case "closed": skipped = format("%s close issue %d %s", gj.Actor.Login, gj.Payload.Issue.Number, gj.Repo.Name) case "reopened": skipped = format("%s reopened issue %d %s", gj.Actor.Login, gj.Payload.Issue.Number, gj.Repo.Name) default: skipped = format("-> %s %s %s", gj.Type, gj.Actor.Login, gj.Repo.Name) } case "IssueCommentEvent": skipped = format("%s comment issue %d %s", gj.Actor.Login, gj.Payload.Issue.Number, gj.Repo.Name) case "PushEvent": skipped = format("%s push to %s", gj.Actor.Login, gj.Repo.Name) case "ForkEvent": skipped = format("%s fork %s", gj.Actor.Login, gj.Repo.Name) case "CreateEvent": switch gj.Payload.Ref_Type { case "tag": skipped = format("%s tag %s %s", gj.Actor.Login, gj.Payload.Ref, gj.Repo.Name) case "repository": skipped = format("%s create %s", gj.Actor.Login, gj.Repo.Name) case "branch": skipped = format("%s branch %s", gj.Actor.Login, gj.Repo.Name) default: skipped = format("-> %s %s %s", gj.Type, gj.Actor.Login, gj.Repo.Name) } case "PullRequestReviewCommentEvent": skipped = format("%s pr comment on %s", gj.Actor.Login, gj.Repo.Name) case "PullRequestEvent": switch gj.Payload.Action { case "closed": skipped = format("%s close pr %d %s", gj.Actor.Login, gj.Payload.Number, gj.Repo.Name) case "opened": skipped = format("%s create pr %d %s", gj.Actor.Login, gj.Payload.Number, gj.Repo.Name) case "reopened": skipped = format("%s reopened pr %d %s", gj.Actor.Login, gj.Payload.Number, gj.Repo.Name) default: skipped = format("-> %s %s %s", gj.Type, gj.Actor.Login, gj.Repo.Name) } case "DeleteEvent": switch gj.Payload.Ref_Type { case "branch": skipped = format("%s del branch %s %s", gj.Actor.Login, gj.Payload.Ref, gj.Repo.Name) default: skipped = format("-> %s %s %s", gj.Type, gj.Actor.Login, gj.Repo.Name) } case "ReleaseEvent": switch gj.Payload.Action { case "published": skipped = format("%s published %s %s", gj.Actor.Login, gj.Payload.Release.Tag_Name, gj.Repo.Name) default: skipped = format("-> %s %s %s", gj.Type, gj.Actor.Login, gj.Repo.Name) } case "CommitCommentEvent": skipped = format("%s commit comment %s", gj.Actor.Login, gj.Repo.Name) case "GollumEvent": switch gj.Payload.Pages.Action { case "edited": skipped = format("%s wiki edit %s", gj.Actor.Login, gj.Repo.Name) } default: for _, event := range skipEvents { if event == gj.Type { return true // we skipped this event } } skipped = format("-> %s %s %s", gj.Type, gj.Actor.Login, gj.Repo.Name) } return skipped }
// output writes the data to the log files and releases the buffer. func (l *loggingT) output(s severity, buf *buffer, file string, line int, alsoToStderr bool) { l.mu.Lock() if l.traceLocation.isSet() { if l.traceLocation.match(file, line) { buf.Write(stacks(false)) } } data := buf.Bytes() if !flag.Parsed() { os.Stderr.Write([]byte("ERROR: logging before flag.Parse: ")) os.Stderr.Write(data) } else { if l.toMemory { logToMemory(data) } if alsoToStderr || l.toStderr || s >= l.stderrThreshold.get() { if !l.color { os.Stderr.Write(data) } else { // color printing is allowed to be inefficient. printColor(s) os.Stderr.Write(data[0:14]) ct.ResetColor() os.Stderr.Write(data[14:30]) ct.Foreground(ct.Blue, true) n, _ := os.Stderr.Write([]byte(file)) ct.ResetColor() os.Stderr.WriteString(":") printColor(s) rest := data[30+n+1:] end := bytes.IndexAny(rest, "]") os.Stderr.Write(rest[:end]) ct.Foreground(ct.Blue, true) os.Stderr.WriteString("]") ct.ResetColor() if l.traceLocation.isSet() && l.traceLocation.match(file, line) { outputColorStack(rest[end+1:], s) } else { os.Stderr.Write(rest[end+1:]) } } } if l.toFile { if l.file[s] == nil { if err := l.createFiles(s); err != nil { os.Stderr.Write(data) // Make sure the message appears somewhere. l.exit(err) } } switch s { case fatalLog: l.file[fatalLog].Write(data) fallthrough case errorLog: l.file[errorLog].Write(data) fallthrough case warningLog: l.file[warningLog].Write(data) fallthrough case infoLog: l.file[infoLog].Write(data) } } } if s == fatalLog { // If we got here via Exit rather than Fatal, print no stacks. if atomic.LoadUint32(&fatalNoStacks) > 0 { l.mu.Unlock() timeoutFlush(10 * time.Second) os.Exit(1) } // Dump all goroutine stacks before exiting. // First, make sure we see the trace for the current goroutine on standard error. // If -logtostderr has been specified, the loop below will do that anyway // as the first stack in the full dump. if !l.toStderr { trace := stacks(false) if l.color { outputColorStack(trace, s) } else { os.Stderr.Write(trace) } } // Write the stack trace for all goroutines to the files. trace := stacks(true) if l.toStderr { if l.color { outputColorStack(trace, s) } else { os.Stderr.Write(trace) } } logExitFunc = func(error) {} // If we get a write error, we'll still exit below. for log := fatalLog; log >= infoLog; log-- { if f := l.file[log]; f != nil { // Can be nil if -logtostderr is set. f.Write(trace) } } l.mu.Unlock() timeoutFlush(10 * time.Second) os.Exit(255) // C++ uses -1, which is silly because it's anded with 255 anyway. } l.putBuffer(buf) l.mu.Unlock() if stats := severityStats[s]; stats != nil { atomic.AddInt64(&stats.lines, 1) atomic.AddInt64(&stats.bytes, int64(len(data))) } }
func summary(args []string) { var duration time.Duration var err error if len(args) > 0 { if args[0] == "last-prompt" { duration = time.Now().Sub(lastPrompt) } else { duration, err = time.ParseDuration(args[0]) if err != nil { fmt.Println( "Invalid syntax: first argument to summary must be a valid " + "duration or empty", ) fmt.Println("summary [duration]\n") } } } else { duration, _ = time.ParseDuration("24h") } ct.ChangeColor(ct.Yellow, true, ct.None, false) fmt.Printf("\nSUMMARY (LAST %s)\n", duration) ct.ResetColor() writer := new(tabwriter.Writer) writer.Init(os.Stdout, 0, 8, 2, ' ', 0) for summary, events := range statistics { lastDuration := history[len(history)-1].GetSyslogTime().Sub( events[len(events)-1].GetSyslogTime(), ) count := 0 for _, event := range events { if event == nil { continue } if history[len(history)-1].GetSyslogTime().Sub(event.GetSyslogTime()) <= duration { count++ } } if count == 0 { continue } fmt.Fprintf( writer, "%s\t%d event(s)\tLast %s ago\n", summary, count, lastDuration, ) } writer.Flush() fmt.Print("\n") }
func (cl *coloredLogger) writeToConsole(text string, color ct.Color, isBright bool) { ct.Foreground(color, isBright) fmt.Print(text) ct.ResetColor() }
func (cl *coloredLogger) print(text string, color ct.Color, isBright bool) { ct.Foreground(color, isBright) fmt.Fprint(cl.writer, text) cl.writer.Print() ct.ResetColor() }
func Color(color ct.Color, msg ...interface{}) { ct.ChangeColor(color, false, ct.None, false) fmt.Print(msg...) ct.ResetColor() }