Documentation
¶
Index ¶
- Constants
- Variables
- func CleanupOldFiles(basePath string, maxAge time.Duration) error
- func CompressFile(filePath string) error
- func ConvertValue(v any) any
- func DetectHomographAttack(s string) bool
- func DetectLog4Shell(input string) bool
- func DetectNullByteInjection(data []byte) bool
- func FindNextBackupIndex(basePath string, compress bool) int
- func FormatFields(fields []Field) string
- func FormatInt(n int) string
- func FormatJSON(entry map[string]any, opts *JSONOptions) string
- func FormatJSONData(data ...any) string
- func FormatSimpleValue(v any) string
- func GetBackupPath(basePath string, index int, compress bool) string
- func GetCaller(callerDepth int, fullPath bool) string
- func HasNestedQuantifiers(pattern string, maxQuantifierRange int) bool
- func InitPatterns()
- func IsComplexValue(v any) bool
- func IsSensitiveKey(key string) bool
- func IsSimpleType(v any) bool
- func NeedsQuoting(s string) bool
- func NeedsRotation(currentSize, writeSize, maxSize int64) bool
- func OpenFile(path string) (*os.File, int64, error)
- func OutputJSON(w io.Writer, caller string, data ...any)
- func OutputText(w io.Writer, caller string, data ...any)
- func OutputTextData(w io.Writer, data ...any)
- func ParseInt(s string) (int, error)
- func RotateBackups(basePath string, maxBackups int, compress bool)
- func SanitizeControlChars(message string) string
- func SanitizeUnicodeControlChars(s string) string
- func ValidateAndSecurePath(path string, maxPathLength int, ...) (string, error)
- func ValidateFieldKeyBasic(key string) error
- func ValidateFieldKeyStrict(key string) error
- func ValidateQuantifierRange(rangeStr string, maxQuantifierRange int) error
- func ValidateTimeFormat(format string) error
- func WipeBytes(data []byte)
- type DebugBuffer
- type Field
- type FormatterConfig
- type JSONFieldNames
- type JSONOptions
- type LogFormat
- type LogLevel
- type MessageFormatter
- type PatternDefinition
- type RateLimitConfig
- type RateLimitStats
- type RateLimitStrategy
- type RateLimiter
- type SecureBuffer
- func (sb *SecureBuffer) Bytes() []byte
- func (sb *SecureBuffer) Cap() int
- func (sb *SecureBuffer) Grow(n int)
- func (sb *SecureBuffer) Len() int
- func (sb *SecureBuffer) Release()
- func (sb *SecureBuffer) Reset()
- func (sb *SecureBuffer) String() string
- func (sb *SecureBuffer) Write(p []byte) (int, error)
- func (sb *SecureBuffer) WriteString(s string) (int, error)
- type SecureBytes
- type SecureString
Constants ¶
const ( // FieldBuilderCapacity is the initial capacity for field builder FieldBuilderCapacity = 256 // EstimatedFieldSize is the estimated size per field in bytes EstimatedFieldSize = 32 )
Constants for field formatting
const ( // FilePermissions is the permission mode for creating files (rw-------). // Only the owner has read and write permissions. This is more restrictive // than DirPermissions (0700) because files don't need execute permission. FilePermissions = 0600 // RetryAttempts is the number of times to retry file operations before giving up. RetryAttempts = 3 // RetryDelay is the duration to wait between retry attempts. RetryDelay = 10 * time.Millisecond )
File system and retry configuration constants.
const DefaultJSONIndent = " "
DefaultJSONIndent is the default indentation string for JSON output.
const HexChars = "0123456789abcdef"
HexChars is a package-level constant for hex digit conversion. Avoids allocation in SanitizeControlChars hot path.
const MaxConvertDepth = 100
MaxConvertDepth is the maximum recursion depth for ConvertValue. This prevents stack overflow when converting deeply nested structures.
const MaxDebugBufferSize = 64 * 1024
MaxDebugBufferSize is the maximum buffer size to return to pool (64KB)
const MaxDecompressSize = 100 * 1024 * 1024 // 100MB
MaxDecompressSize limits the maximum bytes to read during gzip verification. This protects against decompression bombs (zip bombs) that could exhaust memory.
Variables ¶
var ( CompiledFullPatterns []*regexp.Regexp CompiledBasicPatterns []*regexp.Regexp PatternsOnce sync.Once )
Pre-compiled regex cache to avoid repeated compilation.
var AllPatterns = []PatternDefinition{ {`\b[0-9]{4}[- ]?[0-9]{4}[- ]?[0-9]{4}[- ]?[0-9]{3,7}\b`, true}, {`\b[0-9]{3}-[0-9]{2}-[0-9]{4}\b`, true}, {`(?i)((?:credit[_-]?card|card)[\s:=]+)[0-9]{13,19}\b`, true}, {`(?i)((?:password|passwd|pwd|secret)[\s:=]+)[^\s]{1,128}\b`, true}, {`(?i)((?:token|api[_-]?key|bearer)[\s:=]+)[^\s]{1,256}\b`, true}, {`\beyJ[A-Za-z0-9_-]{10,100}\.eyJ[A-Za-z0-9_-]{10,100}\.[A-Za-z0-9_-]{10,100}\b`, false}, {`-----BEGIN[^-]{1,20}PRIVATE\s+KEY-----[A-Za-z0-9+/=\s]{1,4000}-----END[^-]{1,20}PRIVATE\s+KEY-----`, true}, {`\b(?:AKIA|ASIA)[0-9A-Z]{16}\b`, true}, {`\bAIza[A-Za-z0-9_-]{35}\b`, false}, {`\bsk-[A-Za-z0-9]{16,48}\b`, true}, {`\b[A-Za-z0-9._%+-]{1,64}@[A-Za-z0-9.-]{1,253}\.[A-Za-z]{2,6}\b`, false}, {`\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b`, false}, {`\b(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\b`, false}, {`\b(?:[0-9a-fA-F]{1,4}:){1,7}:\b`, false}, {`\b::(?:[0-9a-fA-F]{1,4}:){0,5}[0-9a-fA-F]{1,4}\b`, false}, {`\b(?:[0-9a-fA-F]{1,4}:){1,4}::(?:[0-9a-fA-F]{1,4}:){0,3}[0-9a-fA-F]{1,4}\b`, false}, {`\b(?:[0-9a-fA-F]{1,4}:){1,5}::[0-9a-fA-F]{1,4}\b`, false}, {`\b(?:[0-9a-fA-F]{1,4}:){1,6}::\b`, false}, {`\b::(?:[0-9a-fA-F]{1,4}:){1,6}[0-9a-fA-F]{1,4}\b`, false}, {`\b(?:[0-9a-fA-F]{1,4}:){6}(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b`, false}, {`(?i)((?:mysql|postgresql|mongodb|redis|sqlite|cassandra|influx|cockroach|timescale|postgres)://)[^\s]{1,200}\b`, true}, {`(?i)((?:jdbc:)(?:mysql|postgresql|sqlserver|oracle|mongodb|redis|cassandra)://)[^\s]{1,200}\b`, false}, {`(?i)((?:server|data source|host)[\s=:]+)[^\s;]{1,200}(?:;|\s|$)`, false}, {`(?i)((?:oracle|tns|sid)[\s=:]+)[^\s]{1,100}\b`, false}, {`(?i)(?:[\w.-]+:[\w.-]+@)(?:[\w.-]+|\([^\)]+\))(?::\d+)?(?:/[\w.-]+)?`, false}, {`(?i)((?:phone|mobile|tel|telephone|cell|cellular|fax|contact|number)[\s:=]+)[\+]?[(]?\d{1,4}[)]?[-\s.]?\(?\d{1,4}\)?[-\s.]?\d{1,9}[-\s.]?\d{0,9}\b`, true}, {`\+\d{1,3}[- ]?\d{6,14}\b`, true}, {`\+[\d\s\-\(\)]{7,20}\b`, true}, {`\b00[1-9]\d{6,14}\b`, true}, {`\b(?:\(\d{3}\)\s?|\d{3}[-.\s])\d{3}[-.\s]?\d{4}\b`, true}, {`\b\d{3,5}[- ]\d{4,8}\b`, false}, {`\b0\d{3,5}[- ]?\d{4,8}\b`, true}, {`\b(?!REDACTED|REDACT|REMOVED|FILTERED)[A-Z]{4}[A-Z]{2}[A-Z0-9]{2}(?:[A-Z0-9]{3})?\b`, false}, {`\b[A-Z]{2}[0-9]{2}[A-Z0-9]{4}[0-9]{7,30}\b`, false}, {`(?i)(?:cvv|cvc|cv2|security[_-]?code|card[_-]?verification)[\s:=]+[0-9]{3,4}\b`, true}, {`\b[A-Z][0-9]{2}(?:\.[0-9A-Z]{1,4})?\b`, false}, {`(?i)(?:npi|national[_-]?provider[_-]?identifier|provider[_-]?id)[\s:=]+[12][0-9]{9}\b`, true}, {`(?i)(?:mrn|medical[_-]?record[_-]?number|patient[_-]?id|health[_-]?record)[\s:=]+[A-Za-z0-9]{6,20}\b`, true}, {`\b[0-9]{9}[A-Z]{1,2}\b`, false}, {`(?i)(?:passport[_-]?number|passport[_-]?no|passport[_-]?id)[\s:=]+[0-9]{8,9}\b`, true}, {`(?i)(?:driver[_-]?license|dl[_-]?number|license[_-]?number|drivers[_-]?license)[\s:=]+[A-Za-z0-9]{5,20}\b`, true}, {`\b[0-9]{2}-[0-9]{7}\b`, false}, {`\b[A-CEGHJ-PR-TW-Z][A-CEGHJ-NPR-TW-Z][0-9]{6}[A-D]\b`, false}, {`(?i)(?:sin|social[_-]?insurance[_-]?number|canadian[_-]?sin)[\s:=]+[0-9]{3}[- ]?[0-9]{3}[- ]?[0-9]{3}\b`, true}, {`\b(?:ghp_|gho_|ghu_|ghs_|ghr_)[A-Za-z0-9]{36}\b`, true}, {`\bxox[baprs]-[0-9]{10,13}-[0-9]{10,13}-[a-zA-Z0-9]{24}\b`, true}, {`\b(?:sk|rk|stk)_live_[0-9a-zA-Z]{24,64}\b`, true}, {`"private_key"\s*:\s*"[^"]{100,4000}"`, true}, {`(?i)(?:connection[_-]?string|connstr|azure[_-]?connection)[\s:=]+[^\s]{50,500}`, true}, {`(?i)(?:refresh[_-]?token|access[_-]?token|auth[_-]?token|bearer)[\s:=]+[A-Za-z0-9_\-\.]{20,256}\b`, true}, {`\$\{jndi:[^}]{0,200}\}`, true}, {`\$\{(?:lower|upper) *: *j[a-z]{0,10}\}`, false}, {`\$\{[^}]{0,100}jndi[^}]{0,100}\}`, true}, {`(?i)(?:ldap|ldaps|rmi|dns|iiop|corba)://[^\s]{1,200}`, false}, {`\bsk-(?:ant|proj)-[A-Za-z0-9_-]{32,128}\b`, true}, {`\bglpat-[A-Za-z0-9_-]{20,128}\b`, true}, {`\b(?:ya29\.|1//)[A-Za-z0-9_\-\.]{20,256}\b`, true}, {`\bFwoGZXIvYXdz[ A-Za-z0-9/+=]{40,256}\b`, false}, {`(?i)(?:amqp|amqps)://[^\s]{1,200}\b`, true}, {`(?i)nats://[^\s]{1,200}\b`, false}, {`(?i)(?:kafka|bootstrap[_-]?server)[\s:=]+[a-z0-9._-]+:\d{1,5}`, false}, {`\b\d{2}[- ]\d{3}[- ]?\d{3}[- ]?\d{3}\b`, false}, {`\b\d{8,9}\b`, false}, {`\b\d{1,2}\.\d{3}\.\d{3}-[\dKk]\b`, false}, {`\b\d{3}\.\d{3}\.\d{3}-\d{2}\b`, false}, {`\b[A-ZÑ&]{3,4}\d{6}[A-Z0-9]{3}\b`, false}, {`(?i)(?:fingerprint[_-]?template|fp[_-]?id)[\s:=]+[A-Za-z0-9_-]{10,128}\b`, true}, {`(?i)(?:face[_-]?template|face[_-]?id)[\s:=]+[A-Za-z0-9_-]{10,128}\b`, true}, {`(?i)(?:biometric[_-]?data|bio[_-]?hash)[\s:=]+[A-Za-z0-9+/=]{20,256}\b`, true}, }
AllPatterns is the centralized registry of all security patterns.
var ErrAlternateDataStream = fmt.Errorf("alternate data stream not allowed")
ErrAlternateDataStream is returned when a path contains a Windows Alternate Data Stream.
var ErrOverlongEncoding = fmt.Errorf("UTF-8 overlong encoding detected")
ErrOverlongEncoding is returned when a path contains UTF-8 overlong encoded bytes. Overlong encodings can be used to bypass security checks by encoding characters like '.' or '/' in non-canonical ways.
var ErrReservedName = fmt.Errorf("reserved device name")
ErrReservedName is returned when a path uses a Windows reserved device name.
var ExactMatchOnlyKeywords = map[string]struct{}{
"conn": {},
"dsn": {},
"db": {},
"host": {},
"uri": {},
"url": {},
}
ExactMatchOnlyKeywords contains keywords that should only match exactly. These are typically short words that could cause false positives with substring matching. For example, "db" should not match "mongodb", and "url" should not match "curl".
var SensitiveKeywords = map[string]struct{}{
"password": {},
"passwd": {},
"pwd": {},
"secret": {},
"token": {},
"bearer": {},
"auth": {},
"authorization": {},
"credential": {},
"credentials": {},
"api_key": {},
"apikey": {},
"api-key": {},
"access_key": {},
"accesskey": {},
"access-key": {},
"client_id": {},
"clientid": {},
"client_secret": {},
"secret_key": {},
"secretkey": {},
"secret-key": {},
"private_key": {},
"privatekey": {},
"private-key": {},
"private_key_id": {},
"session_id": {},
"sessionid": {},
"session_token": {},
"refresh_token": {},
"refreshtoken": {},
"access_token": {},
"accesstoken": {},
"oauth_token": {},
"auth_token": {},
"authtoken": {},
"consumer_key": {},
"consumer_secret": {},
"credit_card": {},
"creditcard": {},
"ssn": {},
"social_security": {},
"phone": {},
"telephone": {},
"mobile": {},
"cell": {},
"cellular": {},
"tel": {},
"fax": {},
"contact": {},
"phonenumber": {},
"phone_number": {},
"connection": {},
"database": {},
"hostname": {},
"endpoint": {},
}
SensitiveKeywords contains field names that indicate sensitive data. These keywords support both exact match and substring matching. For short keywords that may cause false positives (e.g., "db", "url"), use ExactMatchOnlyKeywords instead.
Categories:
- Credentials: password, passwd, pwd, secret, token, bearer, auth, authorization, credential
- API Keys: api_key, apikey, api-key, access_key, accesskey, access-key, client_id, client_secret
- Secrets: secret_key, secretkey, secret-key, private_key, privatekey, private-key, private_key_id
- Tokens: session_id, session_token, refresh_token, access_token, oauth_token
- OAuth: consumer_key, consumer_secret
- PII: credit_card, creditcard, ssn, social_security
- Contact: phone, telephone, mobile, cell, cellular, tel, fax, contact
Functions ¶
func CompressFile ¶
func ConvertValue ¶ added in v1.2.0
ConvertValue converts any value to a JSON-serializable format. This is used for debug visualization and complex value formatting. The function has a maximum recursion depth to prevent stack overflow.
func DetectHomographAttack ¶ added in v1.2.0
DetectHomographAttack checks for potential homograph attacks. Homograph attacks use visually similar characters from different Unicode scripts to impersonate legitimate domains or strings.
This is a basic detection that checks for:
- Mixed Cyrillic/Latin characters (common spoofing)
- Mixed Greek/Latin characters
- Confusable characters in suspicious contexts
func DetectLog4Shell ¶ added in v1.2.0
DetectLog4Shell checks for Log4Shell (CVE-2021-44228) and related JNDI injection attack patterns. These patterns can trigger remote code execution in vulnerable Log4j versions.
Patterns detected:
- ${jndi:...} - JNDI lookup
- ${${lower:j}ndi:...} - Obfuscated JNDI
- ${${::-j}${::-n}${::-d}${::-i}:...} - Character bypass
- ${env:...}, ${sys:...} - Environment/system variable lookups
- Unicode escape sequences like \u006a for 'j'
func DetectNullByteInjection ¶ added in v1.2.0
DetectNullByteInjection checks for null byte injection attacks. Null bytes can be used to truncate strings in C-based systems or bypass validation checks that only examine data before the null byte.
func FindNextBackupIndex ¶
func FormatFields ¶ added in v1.2.0
FormatFields formats structured fields into a string representation. Uses a sync.Pool for strings.Builder to reduce allocations.
func FormatInt ¶ added in v1.2.1
FormatInt formats an integer to string using cached values for small integers.
func FormatJSON ¶
func FormatJSON(entry map[string]any, opts *JSONOptions) string
FormatJSON formats a map as JSON using a fast path for simple types and falling back to encoding/json for complex types.
func FormatJSONData ¶ added in v1.2.0
FormatJSONData formats data as JSON using intelligent type conversion.
func FormatSimpleValue ¶ added in v1.2.0
FormatSimpleValue formats a simple value as a string.
func HasNestedQuantifiers ¶ added in v1.2.0
HasNestedQuantifiers checks for regex patterns with nested quantifiers that can cause exponential backtracking (ReDoS vulnerability). Returns true if dangerous patterns like (a+)+, a++, or a{1,10000} are found.
func InitPatterns ¶ added in v1.2.0
func InitPatterns()
InitPatterns initializes the pre-compiled regex patterns. This is called once on first use to avoid startup overhead.
func IsComplexValue ¶ added in v1.2.0
IsComplexValue checks if a field value is a complex type that should be JSON-formatted. This is used to determine if a value needs JSON marshaling in structured logging. Uses type switch fast paths to avoid reflection for common types.
func IsSensitiveKey ¶ added in v1.2.0
IsSensitiveKey checks if a key indicates sensitive data. It uses both exact match and substring matching for comprehensive detection. Performance optimized with pre-sorted slices and binary search for exact matching, and efficient substring matching for compound keys.
func IsSimpleType ¶ added in v1.2.0
IsSimpleType checks if a value is a simple type that doesn't need JSON formatting.
func NeedsQuoting ¶ added in v1.2.0
NeedsQuoting checks if a string needs to be quoted in log output. Strings containing spaces, special characters, or control characters need quoting.
func NeedsRotation ¶
func OutputJSON ¶ added in v1.2.0
OutputJSON writes JSON-formatted data to the specified writer with caller info.
func OutputText ¶ added in v1.2.0
OutputText writes text-formatted data to the specified writer with caller info.
func OutputTextData ¶ added in v1.2.0
OutputTextData writes formatted data to the specified writer. It outputs complex types as pretty-printed JSON and simple types as-is.
func RotateBackups ¶
func SanitizeControlChars ¶ added in v1.2.0
SanitizeControlChars replaces dangerous control characters with visible escape sequences. This preserves debugging information while preventing log injection attacks.
Allowed control characters: \t (tab) - passed through as-is Newlines and carriage returns: replaced with visible escape sequences (\n → \\n, \r → \\r) to prevent CRLF injection attacks while preserving debug information. Null bytes (\x00) and DEL (127) are removed entirely for security. Other control characters (0x01-0x1F except \t) are replaced with \xNN format. ANSI escape sequences (starting with ESC \x1b) are removed entirely for security. Unicode control characters (ZWSP, directional markers, BOM) are removed for security.
func SanitizeUnicodeControlChars ¶ added in v1.2.0
SanitizeUnicodeControlChars removes dangerous Unicode control characters from a string. This is a convenience function for cases where only Unicode control characters need to be removed without other sanitization.
func ValidateAndSecurePath ¶ added in v1.2.0
func ValidateAndSecurePath(path string, maxPathLength int, emptyFilePathErr, nullByteErr, pathTooLongErr, pathTraversalErr, invalidPathErr error) (string, error)
ValidateAndSecurePath validates a file path and returns a cleaned absolute path. It performs security checks to prevent path traversal attacks and other vulnerabilities. Parameters:
- path: the file path to validate
- maxPathLength: maximum allowed path length
- emptyFilePathErr, nullByteErr, pathTooLongErr, pathTraversalErr, invalidPathErr: errors to return
func ValidateFieldKeyBasic ¶ added in v1.2.0
ValidateFieldKeyBasic validates a field key against basic naming rules. This is less strict than ValidateFieldKeyStrict and allows more characters.
func ValidateFieldKeyStrict ¶ added in v1.2.0
ValidateFieldKeyStrict validates a field key against strict naming rules. Field keys should:
- Not be empty
- Not exceed 256 characters
- Contain only alphanumeric characters, underscores, hyphens, and dots
- Not start with a digit
- Not contain path traversal sequences
- Not contain null bytes
- Not look like Log4Shell patterns
- Not contain overlong UTF-8 encodings
- Not contain mixed script characters (homograph attacks)
func ValidateQuantifierRange ¶ added in v1.2.0
ValidateQuantifierRange checks if a quantifier range is within safe limits.
func ValidateTimeFormat ¶ added in v1.2.0
ValidateTimeFormat validates a time format string. Returns nil if the format is valid or empty (empty uses default). Returns an error if the format cannot be used to parse/format time.
Types ¶
type DebugBuffer ¶ added in v1.2.0
DebugBuffer is a helper type that manages getting and returning a buffer from the pool.
func NewDebugBuffer ¶ added in v1.2.0
func NewDebugBuffer() *DebugBuffer
NewDebugBuffer creates a new DebugBuffer from the pool.
func (*DebugBuffer) Release ¶ added in v1.2.0
func (b *DebugBuffer) Release()
Release returns the buffer to the pool if it's not too large.
type Field ¶ added in v1.2.0
Field represents a structured log field. This is the internal representation used by the formatter.
type FormatterConfig ¶ added in v1.2.0
type FormatterConfig struct {
Format LogFormat
TimeFormat string
IncludeTime bool
IncludeLevel bool
FullPath bool
DynamicCaller bool
JSON *JSONOptions
}
FormatterConfig holds the configuration for creating a MessageFormatter. This is used to pass configuration from the root package without importing it.
type JSONFieldNames ¶
type JSONFieldNames struct {
Timestamp string
Level string
Caller string
Message string
Fields string
}
func DefaultJSONFieldNames ¶
func DefaultJSONFieldNames() *JSONFieldNames
func MergeWithDefaults ¶ added in v1.0.8
func MergeWithDefaults(f *JSONFieldNames) *JSONFieldNames
func (*JSONFieldNames) IsComplete ¶
func (j *JSONFieldNames) IsComplete() bool
type JSONOptions ¶
type JSONOptions struct {
PrettyPrint bool
Indent string
FieldNames *JSONFieldNames
}
type LogFormat ¶ added in v1.2.0
type LogFormat int8
LogFormat defines the output format for log messages.
type MessageFormatter ¶ added in v1.2.0
type MessageFormatter struct {
// contains filtered or unexported fields
}
MessageFormatter handles formatting of log messages. It supports both text and JSON formats and caches resources for performance.
func NewMessageFormatter ¶ added in v1.2.0
func NewMessageFormatter(config *FormatterConfig) *MessageFormatter
NewMessageFormatter creates a new MessageFormatter with the given configuration.
func (*MessageFormatter) FormatArgsToString ¶ added in v1.2.0
func (f *MessageFormatter) FormatArgsToString(args ...any) string
FormatArgsToString converts arguments to a single string for filtering. Complex types (slices, maps, structs) are formatted as JSON for better readability. Uses pooled strings.Builder to reduce allocations.
func (*MessageFormatter) FormatWithMessage ¶ added in v1.2.0
func (f *MessageFormatter) FormatWithMessage(level LogLevel, callerDepth int, message string, fields []Field) string
FormatWithMessage formats a complete log message with level, caller, and fields.
type PatternDefinition ¶ added in v1.2.0
PatternDefinition represents a regex pattern for sensitive data detection.
type RateLimitConfig ¶ added in v1.2.0
type RateLimitConfig struct {
// MaxMessagesPerSecond is the maximum number of messages allowed per second.
// Set to 0 to disable message rate limiting.
// Default: 10000 messages/second
MaxMessagesPerSecond int
// MaxBytesPerSecond is the maximum bytes allowed per second.
// Set to 0 to disable byte rate limiting.
// Default: 10MB/second
MaxBytesPerSecond int64
// BurstSize allows temporary bursts above the rate limit.
// This is useful for handling sudden spikes in log volume.
// Default: 1000 messages
BurstSize int
// Strategy determines how to handle rate-limited messages.
// Default: RateLimitStrategyDrop
Strategy RateLimitStrategy
// SamplingRate is used when Strategy is RateLimitStrategySample.
// It determines 1 in N messages to keep when rate limited.
// Default: 100 (keep 1 in 100 messages)
SamplingRate int
}
RateLimitConfig configures the rate limiter for preventing log flooding. Rate limiting protects against DoS attacks via excessive logging and helps maintain system stability under load.
func DefaultRateLimitConfig ¶ added in v1.2.0
func DefaultRateLimitConfig() *RateLimitConfig
DefaultRateLimitConfig returns a RateLimitConfig with sensible defaults. Defaults: 10000 messages/sec, 10MB/sec, burst of 1000, drop strategy.
func (*RateLimitConfig) Clone ¶ added in v1.2.0
func (c *RateLimitConfig) Clone() *RateLimitConfig
Clone creates a copy of the RateLimitConfig.
type RateLimitStats ¶ added in v1.2.0
type RateLimitStats struct {
Tokens int64 // Current message tokens
ByteTokens int64 // Current byte tokens
MessageCount int64 // Messages in current second
ByteCount int64 // Bytes in current second
RateLimitedCount int64 // Total rate-limited messages
CurrentSecond int64 // Current second (Unix timestamp)
MaxMessagesPerSec int // Configured max messages/sec
MaxBytesPerSec int64 // Configured max bytes/sec
}
GetStats returns current rate limiter statistics.
type RateLimitStrategy ¶ added in v1.2.0
type RateLimitStrategy int
RateLimitStrategy defines the strategy for rate limiting log messages.
const ( // RateLimitStrategyDrop drops messages when rate limit is exceeded. RateLimitStrategyDrop RateLimitStrategy = iota // RateLimitStrategySample samples messages when rate limit is exceeded (1 in N). RateLimitStrategySample // RateLimitStrategyThrottle throttles messages to the configured rate. RateLimitStrategyThrottle )
type RateLimiter ¶ added in v1.2.0
type RateLimiter struct {
// contains filtered or unexported fields
}
RateLimiter implements a token bucket rate limiter for log messages. It uses a combination of atomic operations and mutex for thread-safe access. The mutex is only used for second boundary transitions to avoid TOCTOU races.
func NewRateLimiter ¶ added in v1.2.0
func NewRateLimiter(config *RateLimitConfig) *RateLimiter
NewRateLimiter creates a new RateLimiter with the given configuration. If config is nil, defaults are used.
func (*RateLimiter) Reset ¶ added in v1.2.0
func (rl *RateLimiter) Reset()
Reset resets the rate limiter state.
func (*RateLimiter) ShouldRateLimit ¶ added in v1.2.0
func (rl *RateLimiter) ShouldRateLimit(msgSize int) bool
ShouldRateLimit checks if a message of the given size should be rate limited. Returns true if the message should be dropped/throttled, false if it should be processed. This method uses a mutex for second boundary transitions to prevent TOCTOU races, but uses atomic operations for the hot path within each second.
func (*RateLimiter) Stats ¶ added in v1.2.0
func (rl *RateLimiter) Stats() RateLimitStats
Stats returns current rate limiter statistics for monitoring.
type SecureBuffer ¶ added in v1.2.0
type SecureBuffer struct {
// contains filtered or unexported fields
}
SecureBuffer is a byte buffer that zeros its contents when released. This prevents sensitive data from remaining in memory after use. Use for intermediate results during sensitive data processing.
func NewSecureBuffer ¶ added in v1.2.0
func NewSecureBuffer() *SecureBuffer
NewSecureBuffer creates a new SecureBuffer from the pool. Remember to call Release when done to zero and return the buffer.
func (*SecureBuffer) Bytes ¶ added in v1.2.0
func (sb *SecureBuffer) Bytes() []byte
Bytes returns the buffer contents. IMPORTANT: The returned slice is valid only until Release is called.
func (*SecureBuffer) Cap ¶ added in v1.2.0
func (sb *SecureBuffer) Cap() int
Cap returns the capacity of the buffer.
func (*SecureBuffer) Grow ¶ added in v1.2.0
func (sb *SecureBuffer) Grow(n int)
Grow grows the buffer capacity to guarantee space for n more bytes.
IMPORTANT: After calling Grow, any slices previously obtained from Bytes() may point to old memory that has been zeroed. Do not retain references to the internal buffer across Grow calls.
func (*SecureBuffer) Len ¶ added in v1.2.0
func (sb *SecureBuffer) Len() int
Len returns the current length of the buffer.
func (*SecureBuffer) Release ¶ added in v1.2.0
func (sb *SecureBuffer) Release()
Release zeros the buffer and returns it to the pool. After calling Release, the buffer must not be used.
IMPORTANT: Any slices obtained from Bytes() become invalid after Release. Do not store or use references to the internal buffer after calling Release.
func (*SecureBuffer) Reset ¶ added in v1.2.0
func (sb *SecureBuffer) Reset()
Reset clears the buffer (zeros data) and prepares for reuse.
func (*SecureBuffer) String ¶ added in v1.2.0
func (sb *SecureBuffer) String() string
String returns the buffer contents as a string.
func (*SecureBuffer) Write ¶ added in v1.2.0
func (sb *SecureBuffer) Write(p []byte) (int, error)
Write appends data to the buffer.
func (*SecureBuffer) WriteString ¶ added in v1.2.0
func (sb *SecureBuffer) WriteString(s string) (int, error)
WriteString appends a string to the buffer.
type SecureBytes ¶ added in v1.2.0
type SecureBytes struct {
// contains filtered or unexported fields
}
SecureBytes is a byte slice wrapper that zeros its contents when cleared.
func NewSecureBytes ¶ added in v1.2.0
func NewSecureBytes(data []byte) *SecureBytes
NewSecureBytes creates a new SecureBytes from a byte slice. The data is copied to a new allocation.
func (*SecureBytes) Bytes ¶ added in v1.2.0
func (sb *SecureBytes) Bytes() []byte
Bytes returns the underlying bytes.
func (*SecureBytes) Clear ¶ added in v1.2.0
func (sb *SecureBytes) Clear()
Clear zeros the data and releases it.
func (*SecureBytes) Equals ¶ added in v1.2.0
func (sb *SecureBytes) Equals(other []byte) bool
Equals compares the SecureBytes with another byte slice in constant time.
func (*SecureBytes) Len ¶ added in v1.2.0
func (sb *SecureBytes) Len() int
Len returns the length of the data.
type SecureString ¶ added in v1.2.0
type SecureString struct {
// contains filtered or unexported fields
}
SecureString is a string wrapper that can be explicitly cleared. Unlike regular strings which are immutable and may remain in memory until garbage collection, SecureString can be cleared immediately.
func NewSecureString ¶ added in v1.2.0
func NewSecureString(s string) *SecureString
NewSecureString creates a new SecureString from a regular string.
func (*SecureString) Bytes ¶ added in v1.2.0
func (ss *SecureString) Bytes() []byte
Bytes returns the underlying bytes.
func (*SecureString) Clear ¶ added in v1.2.0
func (ss *SecureString) Clear()
Clear zeros the string data and releases it. After calling Clear, the SecureString must not be used.
func (*SecureString) Equals ¶ added in v1.2.0
func (ss *SecureString) Equals(s string) bool
Equals compares the SecureString with another string in constant time. This prevents timing attacks when comparing sensitive values.
func (*SecureString) Len ¶ added in v1.2.0
func (ss *SecureString) Len() int
Len returns the length of the string.
func (*SecureString) String ¶ added in v1.2.0
func (ss *SecureString) String() string
String returns the string value.