Documentation
¶
Index ¶
- func LineFilter(writer io.Writer, pipeline ...LineProcessor) io.Writer
- func LoggingFilter(log logger.Logger, pipeline ...LineProcessor) logger.Logger
- func RebuildLine(original string, redactedTokens []Token) string
- func StripANSI(s string) string
- type LineProcessor
- func AddPrefix(prefix string) LineProcessor
- func AddSuffix(suffix string) LineProcessor
- func FilterLines(matches ...string) LineProcessor
- func RedactSecrets(patterns ...string) LineProcessor
- func RedactValues(values ...string) LineProcessor
- func RegexFilter(pattern string, invert bool) LineProcessor
- func StripSecrets(patterns ...string) LineProcessor
- type SensitiveString
- func (s SensitiveString) Equals(other SensitiveString) bool
- func (s SensitiveString) Format(f fmt.State, verb rune)
- func (s SensitiveString) GoString() string
- func (s SensitiveString) IsEmpty() bool
- func (s SensitiveString) MarshalJSON() ([]byte, error)
- func (s SensitiveString) MarshalText() ([]byte, error)
- func (s SensitiveString) String() string
- func (s SensitiveString) Value() string
- type Token
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 ¶
RebuildLine reconstructs a line by replacing token values with redacted versions. It tokenizes the original line, matches against provided tokens, and rebuilds.
Types ¶
type LineProcessor ¶
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 ¶
TokenizeLine parses a line and extracts secret key-value tokens. If the line contains ANSI escape sequences, they are stripped before parsing.