diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | TODO.md | 11 | ||||
| -rw-r--r-- | internal/color/brush/brush.go | 110 | ||||
| -rw-r--r-- | internal/color/paint.go | 59 | ||||
| -rw-r--r-- | internal/color/table.go | 2 | ||||
| -rw-r--r-- | internal/config/client.go | 164 | ||||
| -rw-r--r-- | internal/protocol/protocol.go | 4 | ||||
| -rw-r--r-- | internal/version/version.go | 8 | ||||
| -rwxr-xr-x | samples/dtail.schema.json | 9 |
9 files changed, 224 insertions, 145 deletions
@@ -1,5 +1,5 @@ GO ?= go -all: test build +all: clean test build build: dserver dcat dgrep dmap dtail dserver: ifndef USE_ACL @@ -0,0 +1,11 @@ +TODO +==== + +This is a loose list of what to do. Maybe for the next releae or maybe for a later one. + +[x] Finalize default color schema +[ ] Use a buffered string builder for brushing the colors in the client. +[ ] Extended color table output (print whole paragraphs in colors) +[ ] Implement Benchmark cat-ing a file and compare to prev version. +[ ] Client 4.x should print a warning when trying to connect to a 3.x server. +[ ] Fix paintClientStats diff --git a/internal/color/brush/brush.go b/internal/color/brush/brush.go index 87c02d0..415028a 100644 --- a/internal/color/brush/brush.go +++ b/internal/color/brush/brush.go @@ -1,7 +1,6 @@ package brush import ( - "fmt" "strings" "github.com/mimecast/dtail/internal/color" @@ -10,96 +9,133 @@ import ( ) // Add some color to log lines received from remote servers. -func paintRemote(line string) string { - splitted := strings.Split(line, protocol.FieldDelimiter) +func paintRemote(sb *strings.Builder, line string) { + splitted := strings.SplitN(line, protocol.FieldDelimiter, 6) + + color.PaintWithAttr(sb, splitted[0], + config.Client.TermColors.RemoteStrFg, + config.Client.TermColors.RemoteStrBg, + config.Client.TermColors.RemoteStrAttr) + + color.PaintWithAttr(sb, protocol.FieldDelimiter, + config.Client.TermColors.DelimiterFg, + config.Client.TermColors.DelimiterBg, + config.Client.TermColors.DelimiterAttr) + + color.PaintWithAttr(sb, splitted[1], + config.Client.TermColors.RemoteServerFg, + config.Client.TermColors.RemoteServerBg, + config.Client.TermColors.RemoteServerAttr) + + color.PaintWithAttr(sb, protocol.FieldDelimiter, + config.Client.TermColors.DelimiterFg, + config.Client.TermColors.DelimiterBg, + config.Client.TermColors.DelimiterAttr) + if splitted[2] == "100" { - splitted[2] = color.Paint(splitted[2], + color.PaintWithAttr(sb, splitted[2], config.Client.TermColors.RemoteStatsOkFg, - config.Client.TermColors.RemoteStatsOkBg) + config.Client.TermColors.RemoteStatsOkBg, + config.Client.TermColors.RemoteStatsOkAttr) } else { - splitted[2] = color.Paint(splitted[2], + color.PaintWithAttr(sb, splitted[2], config.Client.TermColors.RemoteStatsWarnFg, - config.Client.TermColors.RemoteStatsWarnBg) + config.Client.TermColors.RemoteStatsWarnBg, + config.Client.TermColors.RemoteStatsWarnAttr) } - info := strings.Join(splitted[0:5], protocol.FieldDelimiter) - log := strings.Join(splitted[5:], protocol.FieldDelimiter) + color.PaintWithAttr(sb, protocol.FieldDelimiter, + config.Client.TermColors.DelimiterFg, + config.Client.TermColors.DelimiterBg, + config.Client.TermColors.DelimiterAttr) + + color.PaintWithAttr(sb, splitted[3], + config.Client.TermColors.RemoteCountFg, + config.Client.TermColors.RemoteCountBg, + config.Client.TermColors.RemoteCountAttr) + + color.PaintWithAttr(sb, protocol.FieldDelimiter, + config.Client.TermColors.DelimiterFg, + config.Client.TermColors.DelimiterBg, + config.Client.TermColors.DelimiterAttr) + + color.PaintWithAttr(sb, splitted[4], + config.Client.TermColors.RemoteIdFg, + config.Client.TermColors.RemoteIdBg, + config.Client.TermColors.RemoteIdAttr) + color.PaintWithAttr(sb, protocol.FieldDelimiter, + config.Client.TermColors.DelimiterFg, + config.Client.TermColors.DelimiterBg, + config.Client.TermColors.DelimiterAttr) + + log := splitted[5] switch { case strings.HasPrefix(log, "WARN"): - log = color.PaintWithAttr(log, + color.PaintWithAttr(sb, log, config.Client.TermColors.RemoteWarnFg, config.Client.TermColors.RemoteWarnBg, config.Client.TermColors.RemoteWarnAttr) case strings.HasPrefix(log, "ERROR"): - log = color.PaintWithAttr(log, + color.PaintWithAttr(sb, log, config.Client.TermColors.RemoteErrorFg, config.Client.TermColors.RemoteErrorBg, config.Client.TermColors.RemoteErrorAttr) case strings.HasPrefix(log, "FATAL"): - log = color.PaintWithAttr(log, + color.PaintWithAttr(sb, log, config.Client.TermColors.RemoteFatalFg, config.Client.TermColors.RemoteFatalBg, config.Client.TermColors.RemoteFatalAttr) case strings.HasPrefix(log, "DEBUG"): - log = color.PaintWithAttr(log, + color.PaintWithAttr(sb, log, config.Client.TermColors.RemoteDebugFg, config.Client.TermColors.RemoteDebugBg, config.Client.TermColors.RemoteDebugAttr) case strings.HasPrefix(log, "TRACE"): - log = color.PaintWithAttr(log, + color.PaintWithAttr(sb, log, config.Client.TermColors.RemoteTraceFg, config.Client.TermColors.RemoteTraceBg, config.Client.TermColors.RemoteTraceAttr) default: - log = color.PaintWithAttr(log, + color.PaintWithAttr(sb, log, config.Client.TermColors.RemoteTextFg, config.Client.TermColors.RemoteTextBg, config.Client.TermColors.RemoteTextAttr) } - - return fmt.Sprintf("%s|%s", info, log) -} - -// Add some color to stats generated by the client. -func paintClientStats(line string) string { - splitted := strings.Split(line, protocol.FieldDelimiter) - first := strings.Join(splitted[0:4], protocol.FieldDelimiter) - connected := color.PaintWithAttr(splitted[4], - config.Client.TermColors.ClientStatsFg, - config.Client.TermColors.ClientStatsBg, - config.Client.TermColors.ClientStatsAttr) - last := strings.Join(splitted[5:], "|") - - return fmt.Sprintf("%s|%s|%s", first, connected, last) } // Colorfy a given line based on the line's content. func Colorfy(line string) string { + sb := strings.Builder{} + switch { case strings.HasPrefix(line, "REMOTE"): - return paintRemote(line) - - case strings.HasPrefix(line, "CLIENT") && strings.Contains(line, "|stats|"): - return paintClientStats(line) + paintRemote(&sb, line) case strings.Contains(line, "ERROR"): - return color.PaintWithAttr(line, + color.PaintWithAttr(&sb, line, config.Client.TermColors.ClientErrorFg, config.Client.TermColors.ClientErrorBg, config.Client.TermColors.ClientErrorAttr) case strings.Contains(line, "WARN"): - return color.PaintWithAttr(line, + color.PaintWithAttr(&sb, line, config.Client.TermColors.ClientWarnFg, config.Client.TermColors.ClientWarnBg, config.Client.TermColors.ClientWarnAttr) + + default: + color.PaintWithAttr(&sb, line, + color.FgDefault, + color.BgDefault, + color.AttrNone) } - return line + color.ResetWithAttr(&sb) + return sb.String() } diff --git a/internal/color/paint.go b/internal/color/paint.go index 7862467..2798ff7 100644 --- a/internal/color/paint.go +++ b/internal/color/paint.go @@ -1,31 +1,66 @@ package color -import "fmt" +import ( + "fmt" + "strings" +) -// Paint paints a given text in a given foreground/background color combination. -func Paint(text string, fg FgColor, bg BgColor) string { +// PaintStr paints a given text in a given foreground/background color combination. +func PaintStr(text string, fg FgColor, bg BgColor) string { return fmt.Sprintf("%s%s%s%s%s", fg, bg, text, BgDefault, FgDefault) } -// PaintWithAttr paints a given text in a given foreground/background/attribute combination -func PaintWithAttr(text string, fg FgColor, bg BgColor, attr Attribute) string { +// PaintStrWithAttr paints a given text in a given foreground/background/attribute combination +func PaintStrWithAttr(text string, fg FgColor, bg BgColor, attr Attribute) string { if attr == AttrNone { - return Paint(text, fg, bg) + return PaintStr(text, fg, bg) } return fmt.Sprintf("%s%s%s%s%s%s%s", fg, bg, attr, text, AttrReset, BgDefault, FgDefault) } -// PaintFg paints a given text in a given foreground color. -func PaintFg(text string, fg FgColor) string { +// PaintStrFg paints a given text in a given foreground color. +func PaintStrFg(text string, fg FgColor) string { return fmt.Sprintf("%s%s%s", fg, text, FgDefault) } -// PaintBg paints a given text in a given background color. -func PaintBg(text string, bg BgColor) string { +// PaintStrBg paints a given text in a given background color. +func PaintStrBg(text string, bg BgColor) string { return fmt.Sprintf("%s%s%s", bg, text, BgDefault) } -// PaintAttr adds a given attribute to a given text, such as "bold" or "italic". -func PaintAttr(text string, attr Attribute) string { +// PaintStrAttr adds a given attribute to a given text, such as "bold" or "italic". +func PaintStrAttr(text string, attr Attribute) string { return fmt.Sprintf("%s%s%s", attr, text, AttrReset) } + +// Paint paints a given text in a given foreground/background color combination. +func Paint(sb *strings.Builder, text string, fg FgColor, bg BgColor) { + sb.WriteString(string(fg)) + sb.WriteString(string(bg)) + sb.WriteString(text) +} + +// Reset background and foreground colors. +func Reset(sb *strings.Builder) { + sb.WriteString(string(BgDefault)) + sb.WriteString(string(FgDefault)) +} + +// PaintWithAttr starts painting a given text in a given foreground/background/attribute combination. +func PaintWithAttr(sb *strings.Builder, text string, fg FgColor, bg BgColor, attr Attribute) { + if attr == AttrNone { + Paint(sb, text, fg, bg) + return + } + sb.WriteString(string(fg)) + sb.WriteString(string(bg)) + sb.WriteString(string(attr)) + sb.WriteString(text) +} + +// ResetWithAttr resets background, foreground and attributes. +func ResetWithAttr(sb *strings.Builder) { + sb.WriteString(string(AttrReset)) + sb.WriteString(string(BgDefault)) + sb.WriteString(string(FgDefault)) +} diff --git a/internal/color/table.go b/internal/color/table.go index 8c36047..e2265e3 100644 --- a/internal/color/table.go +++ b/internal/color/table.go @@ -26,7 +26,7 @@ func printColorTable(attr string) { attribute, _ := ToAttribute(attr) text := fmt.Sprintf(" Foreground:%10s | Background:%10s | Attribute:%10s ", fg, bg, attr) - fmt.Print(PaintWithAttr(text, fgColor, bgColor, attribute)) + fmt.Print(PaintStrWithAttr(text, fgColor, bgColor, attribute)) fmt.Print("\n") } } diff --git a/internal/config/client.go b/internal/config/client.go index c1b488c..05e4f93 100644 --- a/internal/config/client.go +++ b/internal/config/client.go @@ -4,49 +4,51 @@ import "github.com/mimecast/dtail/internal/color" // ClientColorConfig allows to override the default terminal color color. type termColors struct { - ClientErrorAttr color.Attribute - ClientErrorBg color.BgColor - ClientErrorFg color.FgColor - - ClientStatsAttr color.Attribute - ClientStatsBg color.BgColor - ClientStatsFg color.FgColor - - ClientWarnAttr color.Attribute - ClientWarnBg color.BgColor - ClientWarnFg color.FgColor - - RemoteDebugAttr color.Attribute - RemoteDebugBg color.BgColor - RemoteDebugFg color.FgColor - - RemoteErrorAttr color.Attribute - RemoteErrorBg color.BgColor - RemoteErrorFg color.FgColor - - RemoteFatalAttr color.Attribute - RemoteFatalBg color.BgColor - RemoteFatalFg color.FgColor - - RemoteStatsOkAttr color.Attribute - RemoteStatsOkBg color.BgColor - RemoteStatsOkFg color.FgColor - + ClientErrorAttr color.Attribute + ClientErrorBg color.BgColor + ClientErrorFg color.FgColor + ClientWarnAttr color.Attribute + ClientWarnBg color.BgColor + ClientWarnFg color.FgColor + DelimiterAttr color.Attribute + DelimiterBg color.BgColor + DelimiterFg color.FgColor + RemoteCountAttr color.Attribute + RemoteCountBg color.BgColor + RemoteCountFg color.FgColor + RemoteDebugAttr color.Attribute + RemoteDebugBg color.BgColor + RemoteDebugFg color.FgColor + RemoteErrorAttr color.Attribute + RemoteErrorBg color.BgColor + RemoteErrorFg color.FgColor + RemoteFatalAttr color.Attribute + RemoteFatalBg color.BgColor + RemoteFatalFg color.FgColor + RemoteIdAttr color.Attribute + RemoteIdBg color.BgColor + RemoteIdFg color.FgColor + RemoteServerAttr color.Attribute + RemoteServerBg color.BgColor + RemoteServerFg color.FgColor + RemoteStatsOkAttr color.Attribute + RemoteStatsOkBg color.BgColor + RemoteStatsOkFg color.FgColor RemoteStatsWarnAttr color.Attribute RemoteStatsWarnBg color.BgColor RemoteStatsWarnFg color.FgColor - - RemoteTextAttr color.Attribute - RemoteTextBg color.BgColor - RemoteTextFg color.FgColor - - RemoteTraceAttr color.Attribute - RemoteTraceBg color.BgColor - RemoteTraceFg color.FgColor - - RemoteWarnAttr color.Attribute - RemoteWarnBg color.BgColor - RemoteWarnFg color.FgColor + RemoteStrAttr color.Attribute + RemoteStrBg color.BgColor + RemoteStrFg color.FgColor + RemoteTextAttr color.Attribute + RemoteTextBg color.BgColor + RemoteTextFg color.FgColor + RemoteTraceAttr color.Attribute + RemoteTraceBg color.BgColor + RemoteTraceFg color.FgColor + RemoteWarnAttr color.Attribute + RemoteWarnBg color.BgColor + RemoteWarnFg color.FgColor } // ClientConfig represents a DTail client configuration (empty as of now as there @@ -61,49 +63,51 @@ func newDefaultClientConfig() *ClientConfig { return &ClientConfig{ TermColorsEnable: true, TermColors: termColors{ - ClientErrorAttr: color.AttrBold, - ClientErrorBg: color.BgBlack, - ClientErrorFg: color.FgRed, - - ClientStatsAttr: color.AttrDim, - ClientStatsBg: color.BgBlue, - ClientStatsFg: color.FgWhite, - - ClientWarnAttr: color.AttrNone, - ClientWarnBg: color.BgBlack, - ClientWarnFg: color.FgMagenta, - - RemoteDebugAttr: color.AttrNone, - RemoteDebugBg: color.BgGreen, - RemoteDebugFg: color.FgBlack, - - RemoteErrorAttr: color.AttrBold, - RemoteErrorBg: color.BgRed, - RemoteErrorFg: color.FgWhite, - - RemoteFatalAttr: color.AttrBlink, - RemoteFatalBg: color.BgRed, - RemoteFatalFg: color.FgWhite, - - RemoteStatsOkAttr: color.AttrNone, - RemoteStatsOkBg: color.BgGreen, - RemoteStatsOkFg: color.FgBlack, - + ClientErrorAttr: color.AttrBold, + ClientErrorBg: color.BgBlack, + ClientErrorFg: color.FgRed, + ClientWarnAttr: color.AttrNone, + ClientWarnBg: color.BgBlack, + ClientWarnFg: color.FgMagenta, + DelimiterAttr: color.AttrDim, + DelimiterBg: color.BgBlue, + DelimiterFg: color.FgCyan, + RemoteCountAttr: color.AttrDim, + RemoteCountBg: color.BgBlue, + RemoteCountFg: color.FgGreen, + RemoteDebugAttr: color.AttrBold, + RemoteDebugBg: color.BgBlack, + RemoteDebugFg: color.FgGreen, + RemoteErrorAttr: color.AttrBold, + RemoteErrorBg: color.BgRed, + RemoteErrorFg: color.FgWhite, + RemoteFatalAttr: color.AttrBlink, + RemoteFatalBg: color.BgRed, + RemoteFatalFg: color.FgWhite, + RemoteIdAttr: color.AttrDim, + RemoteIdBg: color.BgBlue, + RemoteIdFg: color.FgWhite, + RemoteServerAttr: color.AttrBold, + RemoteServerBg: color.BgBlue, + RemoteServerFg: color.FgWhite, + RemoteStatsOkAttr: color.AttrNone, + RemoteStatsOkBg: color.BgGreen, + RemoteStatsOkFg: color.FgBlue, RemoteStatsWarnAttr: color.AttrNone, RemoteStatsWarnBg: color.BgRed, RemoteStatsWarnFg: color.FgWhite, - - RemoteTextAttr: color.AttrNone, - RemoteTextBg: color.BgBlack, - RemoteTextFg: color.FgWhite, - - RemoteTraceAttr: color.AttrBold, - RemoteTraceBg: color.BgGreen, - RemoteTraceFg: color.FgWhite, - - RemoteWarnAttr: color.AttrBold, - RemoteWarnBg: color.BgYellow, - RemoteWarnFg: color.FgWhite, + RemoteStrAttr: color.AttrDim, + RemoteStrBg: color.BgBlue, + RemoteStrFg: color.FgWhite, + RemoteTextAttr: color.AttrNone, + RemoteTextBg: color.BgBlack, + RemoteTextFg: color.FgWhite, + RemoteTraceAttr: color.AttrBold, + RemoteTraceBg: color.BgGreen, + RemoteTraceFg: color.FgWhite, + RemoteWarnAttr: color.AttrBold, + RemoteWarnBg: color.BgYellow, + RemoteWarnFg: color.FgWhite, }, } } diff --git a/internal/protocol/protocol.go b/internal/protocol/protocol.go index d3035e4..e92ec6a 100644 --- a/internal/protocol/protocol.go +++ b/internal/protocol/protocol.go @@ -7,6 +7,8 @@ const ( MessageDelimiter byte = '¬' // FieldDelimiter delimits aggregation fields. FieldDelimiter string = "|" + // Arrow for multiple purposes + Arrow string = "➔" // AggregateDelimiter delimits parts of an aggregation message. - AggregateDelimiter string = "➔" + AggregateDelimiter string = Arrow ) diff --git a/internal/version/version.go b/internal/version/version.go index 7f07c83..693192f 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -29,16 +29,16 @@ func PaintedString() string { return String() } - name := color.PaintWithAttr(fmt.Sprintf(" %s ", Name), + name := color.PaintStrWithAttr(fmt.Sprintf(" %s ", Name), color.FgYellow, color.BgBlue, color.AttrBold) - version := color.PaintWithAttr(fmt.Sprintf(" %s ", Version), + version := color.PaintStrWithAttr(fmt.Sprintf(" %s ", Version), color.FgBlue, color.BgYellow, color.AttrBold) - protocol := color.Paint(fmt.Sprintf(" Protocol %s ", protocol.ProtocolCompat), + protocol := color.PaintStr(fmt.Sprintf(" Protocol %s ", protocol.ProtocolCompat), color.FgBlack, color.BgGreen) - additional := color.PaintWithAttr(fmt.Sprintf(" %s ", Additional), + additional := color.PaintStrWithAttr(fmt.Sprintf(" %s ", Additional), color.FgWhite, color.BgMagenta, color.AttrBlink) return fmt.Sprintf("%s%v%s%s", name, version, protocol, additional) diff --git a/samples/dtail.schema.json b/samples/dtail.schema.json index 7978baf..0fd06f1 100755 --- a/samples/dtail.schema.json +++ b/samples/dtail.schema.json @@ -20,15 +20,6 @@ "ClientErrorFg": { "type": "string" }, - "ClientStatsAttr": { - "type": "string" - }, - "ClientStatsBg": { - "type": "string" - }, - "ClientStatsFg": { - "type": "string" - }, "ClientWarnAttr": { "type": "string" }, |
