text

package
v1.21.21 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 14, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func LineFilter

func LineFilter(writer io.Writer, pipeline ...LineProcessor) io.Writer

LineFilter wraps an io.Writer to apply a pipeline of line processors. Each line (delimited by \n) is processed through the pipeline in left-to-right order. If any processor returns skip=true, the line is discarded.

The returned writer is thread-safe for concurrent writes.

Example:

redactor := clicky.RedactSecrets()
writer := clicky.LineFilter(os.Stdout, redactor)
writer.Write([]byte("password=secret\n")) // Writes redacted output

func LoggingFilter

func LoggingFilter(log logger.Logger, pipeline ...LineProcessor) logger.Logger

LoggingFilter wraps a logger.Logger to apply a pipeline of line processors to all log messages. Each log message is processed through the pipeline in left-to-right order. If any processor returns skip=true, the message is not logged.

The returned logger is thread-safe for concurrent use.

Example:

redactor := clicky.RedactSecrets()
log := clicky.LoggingFilter(baseLogger, redactor)
log.Infof("password=secret") // Logs redacted output

func RebuildLine

func RebuildLine(original string, redactedTokens []Token) string

RebuildLine reconstructs a line by replacing token values with redacted versions. It tokenizes the original line, matches against provided tokens, and rebuilds.

func StripANSI

func StripANSI(s string) string

StripANSI removes ANSI escape codes from a string. It handles CSI sequences (\x1b[...) terminated by any byte in 0x40-0x7E, OSC sequences (\x1b]...) terminated by BEL or ST (\x1b\\), and standalone two-byte escapes (\x1b X for X in 0x40-0x5F).

Types

type LineProcessor

type LineProcessor func(line string) (out string, skip bool)

LineProcessor processes a single line and returns:

  • out: the processed line (may be modified or original)
  • skip: whether to skip writing this line

If a processor returns skip=true, the pipeline stops immediately and the line is not written. Processors should not panic, but the framework will recover if they do and skip the line.

func AddPrefix

func AddPrefix(prefix string) LineProcessor

AddPrefix returns a LineProcessor that prepends a prefix to each line. The processor never skips lines.

Example:

processor := clicky.AddPrefix("[INFO] ")
result, _ := processor("message")
// result: "[INFO] message"

func AddSuffix

func AddSuffix(suffix string) LineProcessor

AddSuffix returns a LineProcessor that appends a suffix to each line. The processor never skips lines.

Example:

processor := clicky.AddSuffix(" [END]")
result, _ := processor("message")
// result: "message [END]"

func FilterLines

func FilterLines(matches ...string) LineProcessor

FilterLines returns a LineProcessor that skips lines containing any of the specified strings.

Example:

// Skip health check and metrics logs
processor := clicky.FilterLines("healthcheck", "metrics")

func RedactSecrets

func RedactSecrets(patterns ...string) LineProcessor

RedactSecrets returns a LineProcessor that redacts sensitive data from lines. Uses a tokenizer to properly handle quoted values, ANSI sequences, and complex formats. If patterns are provided, they are used as regex patterns (legacy behavior).

The processor replaces only the value portion with "***", keeping the key. It never skips lines (always returns skip=false).

Example:

processor := text.RedactSecrets()
result, _ := processor("password=secret123")
// result: "password=***"

result, _ = processor("ALTER USER postgres PASSWORD 'secret'")
// result: "ALTER USER postgres PASSWORD '***'"

func RedactValues

func RedactValues(values ...string) LineProcessor

RedactValues returns a LineProcessor that redacts specific known secret values. This is useful when you know the actual secret value and want to redact it wherever it appears, regardless of the key name.

The processor replaces all occurrences of the specified values with "***". It never skips lines (always returns skip=false).

Example:

processor := text.RedactValues("secret123", "token456")
result, _ := processor("password=secret123 token=token456")
// result: "password=*** token=***"

func RegexFilter

func RegexFilter(pattern string, invert bool) LineProcessor

RegexFilter returns a LineProcessor that filters lines based on a regex pattern. If invert=false, lines matching the pattern are skipped. If invert=true, lines NOT matching the pattern are skipped.

The processor never modifies the line content.

Example:

// Skip health check logs
processor := clicky.RegexFilter("healthcheck", false)

// Only keep ERROR logs
processor := clicky.RegexFilter("ERROR", true)

func StripSecrets

func StripSecrets(patterns ...string) LineProcessor

StripSecrets is an alias for RedactSecrets for backward compatibility.

type SensitiveString

type SensitiveString string

SensitiveString is a string type that hides sensitive information in logs and JSON output

func NewSensitiveString

func NewSensitiveString(value string) SensitiveString

NewSensitiveString creates a new SensitiveString from a regular string

func SensitiveStringFromEnv

func SensitiveStringFromEnv(key string) SensitiveString

SensitiveStringFromEnv creates a SensitiveString from an environment variable Returns empty SensitiveString if the environment variable doesn't exist

func (SensitiveString) Equals

func (s SensitiveString) Equals(other SensitiveString) bool

Equals compares two sensitive strings for equality (constant-time comparison)

func (SensitiveString) Format

func (s SensitiveString) Format(f fmt.State, verb rune)

Format implements fmt.Formatter to ensure sensitive values are redacted in all format verbs

func (SensitiveString) GoString

func (s SensitiveString) GoString() string

GoString implements fmt.GoStringer to prevent accidental logging in %#v format

func (SensitiveString) IsEmpty

func (s SensitiveString) IsEmpty() bool

IsEmpty returns true if the sensitive string is empty

func (SensitiveString) MarshalJSON

func (s SensitiveString) MarshalJSON() ([]byte, error)

MarshalJSON redacts the value in JSON output

func (SensitiveString) MarshalText

func (s SensitiveString) MarshalText() ([]byte, error)

MarshalText redacts the value in text marshaling (used by many serializers)

func (SensitiveString) String

func (s SensitiveString) String() string

String implements fmt.Stringer to prevent accidental logging of sensitive values

func (SensitiveString) Value

func (s SensitiveString) Value() string

Value returns the actual string value - use with caution and only when necessary

type Token

type Token struct {
	Key            string // The keyword (password, token, etc.)
	Separator      string // The separator (=, :, or space)
	Value          string // The actual value (unescaped)
	QuoteChar      string // Quote type: ', ", ansi, or empty
	ANSICode       string // The ANSI escape code if QuoteChar is "ansi"
	InnerQuoteChar string // Quote char inside ANSI (for \x1b[37m'value'\x1b[0m)
	StartPos       int    // Starting position in original line
	EndPos         int    // Ending position in original line
}

Token represents a parsed key-value pair with quote information

func TokenizeLine

func TokenizeLine(line string) []Token

TokenizeLine parses a line and extracts secret key-value tokens. If the line contains ANSI escape sequences, they are stripped before parsing.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL