From b26212975b8db9a19181cb544ea712060c319607 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Thu, 19 Jun 2025 22:12:26 +0300 Subject: Fix doubled colored output in dcat/dgrep by removing server-side coloring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Server should never send colored output - all colorization should happen on the client side. This fix removes the colorization logic from the server-side processors (catprocessor.go and grepprocessor.go). Changes: - Remove brush.Colorfy() calls from server-side processors - Remove color-related imports and fields - Update dlog.Raw() documentation to reflect server sends plain output - Client-side coloring remains intact via dlog.Raw() This ensures proper separation of concerns and prevents doubled ANSI escape sequences in the output. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- internal/io/dlog/dlog.go | 2 ++ internal/io/fs/catprocessor.go | 43 ++++++----------------------------------- internal/io/fs/grepprocessor.go | 14 +------------- 3 files changed, 9 insertions(+), 50 deletions(-) diff --git a/internal/io/dlog/dlog.go b/internal/io/dlog/dlog.go index 5bb6445..044624e 100644 --- a/internal/io/dlog/dlog.go +++ b/internal/io/dlog/dlog.go @@ -238,6 +238,8 @@ func (d *DLog) Devel(args ...interface{}) string { } // Raw message logging. +// Raw logs messages from the server without the standard log formatting. +// Since server never sends colored output, client handles all colorization. func (d *DLog) Raw(message string) string { if d == nil { return "" diff --git a/internal/io/fs/catprocessor.go b/internal/io/fs/catprocessor.go index b062c7f..0af8751 100644 --- a/internal/io/fs/catprocessor.go +++ b/internal/io/fs/catprocessor.go @@ -4,25 +4,20 @@ import ( "context" "fmt" - "github.com/mimecast/dtail/internal/color/brush" "github.com/mimecast/dtail/internal/protocol" ) // CatProcessor handles cat-style output type CatProcessor struct { - plain bool - noColor bool - hostname string - isFirstLine bool + plain bool + hostname string } // NewCatProcessor creates a new cat processor func NewCatProcessor(plain, noColor bool, hostname string) *CatProcessor { return &CatProcessor{ - plain: plain, - noColor: noColor, - hostname: hostname, - isFirstLine: true, + plain: plain, + hostname: hostname, } } @@ -69,29 +64,7 @@ func (cp *CatProcessor) ProcessLine(line []byte, lineNum int, filePath string, s transmittedPerc, protocol.FieldDelimiter, count, protocol.FieldDelimiter, sourceID, protocol.FieldDelimiter, string(line)) - // Apply ANSI color formatting if not in plain mode and not noColor mode - if !cp.plain && !cp.noColor { - colorized := brush.Colorfy(protocolLine) - - // Add color reset prefix for all lines except the first - var result []byte - if cp.isFirstLine { - cp.isFirstLine = false - result = make([]byte, len(colorized)+1) - copy(result, colorized) - result[len(colorized)] = '\n' - } else { - // Add color reset prefix: [39m[49m[49m[39m - colorResetPrefix := "\x1b[39m\x1b[49m\x1b[49m\x1b[39m" - result = make([]byte, len(colorResetPrefix)+len(colorized)+1) - copy(result, colorResetPrefix) - copy(result[len(colorResetPrefix):], colorized) - result[len(colorResetPrefix)+len(colorized)] = '\n' - } - return result, true - } - - // No color formatting + // Server should never send colored output - client handles all colorization result := make([]byte, len(protocolLine)+1) copy(result, protocolLine) result[len(protocolLine)] = '\n' @@ -100,10 +73,6 @@ func (cp *CatProcessor) ProcessLine(line []byte, lineNum int, filePath string, s } func (cp *CatProcessor) Flush() []byte { - // Add final color reset line to match original behavior (no trailing newline) - // Only in non-plain mode with colors enabled - if !cp.plain && !cp.noColor { - return []byte("\x1b[39m\x1b[49m\x1b[49m\x1b[39m") - } + // Server should not send color codes - client handles colorization return nil } diff --git a/internal/io/fs/grepprocessor.go b/internal/io/fs/grepprocessor.go index 57c4c2f..c9d1d79 100644 --- a/internal/io/fs/grepprocessor.go +++ b/internal/io/fs/grepprocessor.go @@ -4,7 +4,6 @@ import ( "context" "fmt" - "github.com/mimecast/dtail/internal/color/brush" "github.com/mimecast/dtail/internal/protocol" "github.com/mimecast/dtail/internal/regex" ) @@ -13,7 +12,6 @@ import ( type GrepProcessor struct { regex regex.Regex plain bool - noColor bool hostname string // Context handling @@ -33,7 +31,6 @@ func NewGrepProcessor(re regex.Regex, plain, noColor bool, hostname string, befo gp := &GrepProcessor{ regex: re, plain: plain, - noColor: noColor, hostname: hostname, beforeContext: beforeContext, afterContext: afterContext, @@ -165,16 +162,7 @@ func (gp *GrepProcessor) formatLine(line []byte, lineNum int, filePath string, s transmittedPerc, protocol.FieldDelimiter, count, protocol.FieldDelimiter, sourceID, protocol.FieldDelimiter, string(line)) - // Apply ANSI color formatting if not in plain mode and not noColor mode. - if !gp.plain && !gp.noColor { - colorized := brush.Colorfy(protocolLine) - result := make([]byte, len(colorized)+1) - copy(result, colorized) - result[len(colorized)] = '\n' - return result - } - - // No color formatting + // Server should never send colored output - client handles all colorization result := make([]byte, len(protocolLine)+1) copy(result, protocolLine) result[len(protocolLine)] = '\n' -- cgit v1.2.3