Documentation
¶
Overview ¶
Package drain3 implements the Drain log template mining algorithm in Go. It is a faithful port of the Python Drain3 library (github.com/logpai/Drain3).
Drain3 processes streaming log messages and automatically extracts log templates by replacing variable parts with wildcards (<*>).
Index ¶
- Constants
- type AddLogMessageResult
- type ChangeType
- type ClusterStore
- type Config
- type Drain
- func (d *Drain) AddLogMessage(content string) (*LogCluster, ChangeType)
- func (d *Drain) ClusterCount() int
- func (d *Drain) Clusters() []*LogCluster
- func (d *Drain) GetContentAsTokens(content string) []string
- func (d *Drain) GetTotalClusterSize() int
- func (d *Drain) MarshalJSON() ([]byte, error)
- func (d *Drain) Match(content string, fullSearchStrategy SearchStrategy) *LogCluster
- func (d *Drain) StateConfigMismatch() bool
- func (d *Drain) UnmarshalState(data []byte) error
- type DrainConfig
- type DrainSection
- type ExtractedParameter
- type FilePersistence
- type LimitsSection
- type LogCluster
- type LogClusterCache
- type LogMasker
- type MaskErrorPolicy
- type MaskingInstruction
- type MaskingInstructionConfig
- type MaskingSection
- type MemoryPersistence
- type Node
- type NullProfiler
- type Option
- func WithCompressState(enabled bool) Option
- func WithConfig(cfg *Config) Option
- func WithDepth(depth int) Option
- func WithExtraDelimiters(delimiters ...string) Option
- func WithFilePersistence(filePath string) Option
- func WithMaskErrorPolicy(policy MaskErrorPolicy) Option
- func WithMaskPrefix(prefix string) Option
- func WithMaskSuffix(suffix string) Option
- func WithMasking(regexPattern, maskWith string) Option
- func WithMaxChildren(maxChildren int) Option
- func WithMaxClusters(maxClusters int) Option
- func WithMaxDecompressedStateBytes(maxBytes int) Option
- func WithMaxMessageBytes(maxBytes int) Option
- func WithMaxStateBytes(maxBytes int) Option
- func WithParamStr(paramStr string) Option
- func WithParameterExtractionCacheCapacity(capacity int) Option
- func WithParametrizeNumericTokens(enabled bool) Option
- func WithPersistence(handler PersistenceHandler) Option
- func WithProfiling(enabled bool) Option
- func WithRegexTimeout(timeout time.Duration) Option
- func WithSimTh(simTh float64) Option
- func WithSnapshotInterval(minutes int) Option
- type ParameterExtractor
- type PersistenceHandler
- type Profiler
- type ProfilingSection
- type SearchStrategy
- type SimpleProfiler
- type SnapshotSection
- type StateClearer
- type StateSizeProvider
- type TemplateMiner
- func (tm *TemplateMiner) AddLogMessage(message string) *AddLogMessageResult
- func (tm *TemplateMiner) ClusterCount() int
- func (tm *TemplateMiner) Clusters() []*LogCluster
- func (tm *TemplateMiner) GetProfilerReport(reset bool) string
- func (tm *TemplateMiner) LoadState() error
- func (tm *TemplateMiner) Match(message string, strategy SearchStrategy) *LogCluster
- func (tm *TemplateMiner) MatchWithError(message string, strategy SearchStrategy) (*LogCluster, error)
- func (tm *TemplateMiner) NewParameterExtractor() *ParameterExtractor
- func (tm *TemplateMiner) SaveState() error
Examples ¶
Constants ¶
const DefaultParamStr = "<*>"
DefaultParamStr is the wildcard placeholder used for variable tokens in templates.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AddLogMessageResult ¶
type AddLogMessageResult struct {
Cluster *LogCluster
ChangeType ChangeType
// InputError reports that the message was rejected before mining, for
// example because it exceeded the configured size limit.
InputError error
// MaskError reports masking failures such as regex timeouts. The message is
// mined only when MaskErrorPolicyContinue is configured.
MaskError error
// SaveError is non-nil if auto-saving state to persistence failed.
SaveError error
}
AddLogMessageResult is the result of processing a log message.
type ChangeType ¶
type ChangeType int
ChangeType indicates what happened when a log message was processed.
const ( // ChangeNone means the message matched an existing cluster with no template change. ChangeNone ChangeType = iota // ChangeClusterCreated means a new cluster was created for the message. ChangeClusterCreated // ChangeClusterTemplateChanged means an existing cluster's template was updated. ChangeClusterTemplateChanged )
func (ChangeType) String ¶
func (c ChangeType) String() string
type ClusterStore ¶
type ClusterStore interface {
Get(clusterID int) *LogCluster
// Put inserts or updates a cluster. Returns the evicted cluster if any (LRU mode).
Put(cluster *LogCluster) *LogCluster
Remove(clusterID int)
Len() int
Values() []*LogCluster
}
ClusterStore is an interface for storing and retrieving log clusters.
type Config ¶
type Config struct {
Drain DrainSection `yaml:"drain"`
Snapshot SnapshotSection `yaml:"snapshot"`
Masking MaskingSection `yaml:"masking"`
Limits LimitsSection `yaml:"limits"`
Profiling ProfilingSection `yaml:"profiling"`
}
Config holds all configuration for the TemplateMiner.
func DefaultConfig ¶
func DefaultConfig() *Config
DefaultConfig returns a Config with safe production defaults.
func LoadConfig ¶
LoadConfig loads a Config from a YAML file. Missing fields are filled with default values.
type Drain ¶
type Drain struct {
// Configuration
SimTh float64 `json:"-"`
Depth int `json:"-"`
MaxChildren int `json:"-"`
MaxClusters int `json:"-"`
ExtraDelimiters []string `json:"-"`
ParamStr string `json:"-"`
ParametrizeNumericTokens bool `json:"-"`
// State
RootNode *Node `json:"root_node"`
IDToCluster ClusterStore `json:"-"`
ClustersCounter int `json:"clusters_counter"`
// contains filtered or unexported fields
}
Drain is the core log template mining engine. It maintains a prefix tree for fast matching and a collection of log clusters.
func NewDrain ¶
func NewDrain(cfg DrainConfig) *Drain
NewDrain creates a new Drain engine with the given configuration. It panics for invalid configuration. Use NewDrainChecked when configuration is supplied dynamically and the error must be handled.
func NewDrainChecked ¶
func NewDrainChecked(cfg DrainConfig) (*Drain, error)
NewDrainChecked creates a new Drain engine and returns configuration errors.
func (*Drain) AddLogMessage ¶
func (d *Drain) AddLogMessage(content string) (*LogCluster, ChangeType)
AddLogMessage processes a log message and returns the matching cluster and change type.
func (*Drain) ClusterCount ¶
ClusterCount returns the number of active clusters.
func (*Drain) Clusters ¶
func (d *Drain) Clusters() []*LogCluster
Clusters returns all current log clusters.
func (*Drain) GetContentAsTokens ¶
GetContentAsTokens splits content into tokens, applying extra delimiters. Extra delimiters are treated as literal strings, matching Drain3 tokenization.
func (*Drain) GetTotalClusterSize ¶
GetTotalClusterSize returns the sum of all cluster sizes (total messages processed).
func (*Drain) MarshalJSON ¶
MarshalJSON serializes the Drain state to JSON.
func (*Drain) Match ¶
func (d *Drain) Match(content string, fullSearchStrategy SearchStrategy) *LogCluster
Match finds the best matching cluster for a log message without modifying any state.
func (*Drain) StateConfigMismatch ¶
StateConfigMismatch reports whether the most recently loaded state was created with a different or legacy configuration. The prefix tree is rebuilt automatically in either case.
func (*Drain) UnmarshalState ¶
UnmarshalState restores the Drain state from JSON.
type DrainConfig ¶
type DrainConfig struct {
SimTh float64
Depth int
MaxChildren int
MaxClusters int
ExtraDelimiters []string
ParamStr string
ParametrizeNumericTokens bool
}
DrainConfig holds configuration for creating a new Drain instance.
func DefaultDrainConfig ¶
func DefaultDrainConfig() DrainConfig
DefaultDrainConfig returns a DrainConfig with safe production defaults.
type DrainSection ¶
type DrainSection struct {
SimTh float64 `yaml:"sim_th"`
Depth int `yaml:"depth"`
MaxChildren int `yaml:"max_children"`
MaxClusters int `yaml:"max_clusters"`
ExtraDelimiters []string `yaml:"extra_delimiters"`
ParamStr string `yaml:"param_str"`
ParametrizeNumericTokens *bool `yaml:"parametrize_numeric_tokens"`
}
DrainSection holds Drain algorithm parameters.
func (*DrainSection) GetParametrizeNumericTokens ¶
func (d *DrainSection) GetParametrizeNumericTokens() bool
GetParametrizeNumericTokens returns the effective value, defaulting to true if nil.
func (*DrainSection) GetSimTh ¶
func (d *DrainSection) GetSimTh() float64
GetSimTh returns the configured similarity threshold.
type ExtractedParameter ¶
ExtractedParameter represents a single extracted parameter value and its mask name.
type FilePersistence ¶
type FilePersistence struct {
FilePath string
}
FilePersistence saves/loads Drain state to/from a file.
func NewFilePersistence ¶
func NewFilePersistence(filePath string) *FilePersistence
NewFilePersistence creates a new file-based persistence handler.
func (*FilePersistence) ClearState ¶
func (f *FilePersistence) ClearState() error
ClearState removes the persisted state file. Missing files are ignored.
func (*FilePersistence) LoadState ¶
func (f *FilePersistence) LoadState() ([]byte, error)
LoadState reads the state from the file. Returns nil, nil if the file does not exist.
func (*FilePersistence) SaveState ¶
func (f *FilePersistence) SaveState(state []byte) error
SaveState writes the state to the file, atomically.
func (*FilePersistence) StateSize ¶
func (f *FilePersistence) StateSize() (int64, error)
StateSize returns the persisted file size without reading its contents.
type LimitsSection ¶
type LimitsSection struct {
MaxMessageBytes int `yaml:"max_message_bytes"`
MaxStateBytes int `yaml:"max_state_bytes"`
MaxDecompressedStateBytes int `yaml:"max_decompressed_state_bytes"`
ParameterExtractionCacheCapacity int `yaml:"parameter_extraction_cache_capacity"`
}
LimitsSection bounds input, persistence, and cache memory usage. A zero value disables the corresponding limit.
type LogCluster ¶
type LogCluster struct {
ClusterID int `json:"cluster_id"`
LogTemplateTokens []string `json:"log_template_tokens"`
Size int `json:"size"`
}
LogCluster represents a discovered log template and the count of messages that match it.
func NewLogCluster ¶
func NewLogCluster(logTemplateTokens []string, clusterID int) *LogCluster
NewLogCluster creates a new log cluster with the given template tokens and ID.
func (*LogCluster) GetTemplate ¶
func (lc *LogCluster) GetTemplate() string
GetTemplate returns the template as a single string with tokens joined by spaces.
func (*LogCluster) String ¶
func (lc *LogCluster) String() string
String returns a human-readable representation of the cluster.
type LogClusterCache ¶
type LogClusterCache struct {
// contains filtered or unexported fields
}
LogClusterCache is an LRU cache for log clusters. IMPORTANT: Get() does NOT promote the entry (non-destructive). Only Put() and Touch() move entries to the front (most recently used). This matches the Python Drain3 behavior where reading a cluster for matching should not affect eviction order.
func NewLogClusterCache ¶
func NewLogClusterCache(maxSize int) *LogClusterCache
NewLogClusterCache creates a new LRU cache with the given maximum size.
func (*LogClusterCache) Get ¶
func (c *LogClusterCache) Get(clusterID int) *LogCluster
Get retrieves a cluster by ID without affecting eviction order.
func (*LogClusterCache) Len ¶
func (c *LogClusterCache) Len() int
Len returns the number of clusters in the cache.
func (*LogClusterCache) Put ¶
func (c *LogClusterCache) Put(cluster *LogCluster) *LogCluster
Put inserts or updates a cluster, promoting it to most-recently-used. If the cache is at capacity, the least-recently-used entry is evicted. Returns the evicted cluster, if any.
func (*LogClusterCache) Remove ¶
func (c *LogClusterCache) Remove(clusterID int)
Remove removes a cluster from the cache.
func (*LogClusterCache) Touch ¶
func (c *LogClusterCache) Touch(clusterID int)
Touch promotes a cluster to most-recently-used without modifying it.
func (*LogClusterCache) Values ¶
func (c *LogClusterCache) Values() []*LogCluster
Values returns all clusters in the cache (most recently used first).
type LogMasker ¶
type LogMasker struct {
Instructions []*MaskingInstruction
MaskPrefix string
MaskSuffix string
// contains filtered or unexported fields
}
LogMasker applies a sequence of masking instructions to log messages.
func NewLogMasker ¶
func NewLogMasker(instructions []*MaskingInstruction, maskPrefix, maskSuffix string) *LogMasker
NewLogMasker creates a new LogMasker with the given prefix and suffix for mask tokens.
func (*LogMasker) InstructionsByMaskName ¶
func (m *LogMasker) InstructionsByMaskName(maskName string) []*MaskingInstruction
InstructionsByMaskName returns all instructions that use the given mask name.
func (*LogMasker) MaskWithError ¶
MaskWithError applies all masking instructions and reports regex execution errors, including timeouts. Instructions that fail are skipped so callers can decide whether to accept the partially masked result.
func (*LogMasker) SetTimeout ¶
SetTimeout sets a regex match timeout for all masking instructions.
type MaskErrorPolicy ¶
type MaskErrorPolicy string
MaskErrorPolicy controls whether a message is mined when masking fails.
const ( // MaskErrorPolicyReject prevents partially masked messages from changing the model. MaskErrorPolicyReject MaskErrorPolicy = "reject" // MaskErrorPolicyContinue mines the message using masks that completed successfully. MaskErrorPolicyContinue MaskErrorPolicy = "continue" )
type MaskingInstruction ¶
type MaskingInstruction struct {
Pattern string `yaml:"pattern" json:"pattern"`
MaskWith string `yaml:"mask_with" json:"mask_with"`
MaskPrefix string `yaml:"-" json:"-"`
MaskSuffix string `yaml:"-" json:"-"`
// contains filtered or unexported fields
}
MaskingInstruction defines a regex pattern and its replacement mask.
func NewMaskingInstruction ¶
func NewMaskingInstruction(pattern, maskWith string) (*MaskingInstruction, error)
NewMaskingInstruction creates a new MaskingInstruction with a compiled regex.
type MaskingInstructionConfig ¶
type MaskingInstructionConfig struct {
Pattern string `yaml:"pattern"`
MaskWith string `yaml:"mask_with"`
}
MaskingInstructionConfig is the YAML representation of a masking instruction.
type MaskingSection ¶
type MaskingSection struct {
MaskPrefix string `yaml:"mask_prefix"`
MaskSuffix string `yaml:"mask_suffix"`
RegexTimeoutMillis int `yaml:"regex_timeout_millis"`
ErrorPolicy MaskErrorPolicy `yaml:"error_policy"`
Instructions []MaskingInstructionConfig `yaml:"instructions"`
}
MaskingSection holds masking configuration.
type MemoryPersistence ¶
type MemoryPersistence struct {
// contains filtered or unexported fields
}
MemoryPersistence is an in-memory PersistenceHandler, useful for testing.
func NewMemoryPersistence ¶
func NewMemoryPersistence() *MemoryPersistence
NewMemoryPersistence creates a new in-memory persistence handler.
func (*MemoryPersistence) ClearState ¶
func (m *MemoryPersistence) ClearState() error
ClearState clears any previously saved in-memory state.
func (*MemoryPersistence) LoadState ¶
func (m *MemoryPersistence) LoadState() ([]byte, error)
LoadState returns the previously saved state, or nil if none.
func (*MemoryPersistence) SaveState ¶
func (m *MemoryPersistence) SaveState(state []byte) error
SaveState stores state in memory.
type Node ¶
type Node struct {
KeyToChildNode map[string]*Node `json:"key_to_child_node"`
ClusterIDs []int `json:"cluster_ids"`
}
Node represents a node in the Drain prefix tree. Internal nodes hold child pointers keyed by token string. Leaf nodes hold a list of cluster IDs for fast matching.
type NullProfiler ¶
type NullProfiler struct{}
NullProfiler is a no-op profiler that does nothing.
func (NullProfiler) EndSection ¶
func (NullProfiler) EndSection(string)
func (NullProfiler) Report ¶
func (NullProfiler) Report(bool) string
func (NullProfiler) StartSection ¶
func (NullProfiler) StartSection(string)
type Option ¶
type Option func(*Config, *options)
Option configures a TemplateMiner. Use with New().
func WithCompressState ¶
WithCompressState enables or disables zlib compression for persisted state. Default: true.
func WithConfig ¶
WithConfig uses a pre-built Config directly. This overrides all other drain/masking/snapshot/profiling options set before it.
func WithExtraDelimiters ¶
WithExtraDelimiters sets additional characters to split tokens on.
func WithFilePersistence ¶
WithFilePersistence sets file-based persistence at the given path.
func WithMaskErrorPolicy ¶
func WithMaskErrorPolicy(policy MaskErrorPolicy) Option
WithMaskErrorPolicy controls whether masking errors reject a message or allow mining to continue with partial masking. Default: MaskErrorPolicyReject.
func WithMaskPrefix ¶
WithMaskPrefix sets the prefix for mask tokens. Default: "<".
func WithMaskSuffix ¶
WithMaskSuffix sets the suffix for mask tokens. Default: ">".
func WithMasking ¶
WithMasking adds a regex masking instruction. The pattern is applied to log messages before template mining, and matches are replaced with <maskWith>. Can be called multiple times to add multiple masks.
Example:
drain3.WithMasking(`\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}`, "IP")
func WithMaxChildren ¶
WithMaxChildren sets the maximum children per tree node. Default: 100.
func WithMaxClusters ¶
WithMaxClusters sets the maximum number of clusters (0 = unlimited). Default: 0.
func WithMaxDecompressedStateBytes ¶
WithMaxDecompressedStateBytes limits JSON state size after decompression. Zero disables the limit.
func WithMaxMessageBytes ¶
WithMaxMessageBytes limits input message size. Zero disables the limit.
func WithMaxStateBytes ¶
WithMaxStateBytes limits persisted state size before loading and after saving. Zero disables the limit.
func WithParamStr ¶
WithParamStr sets the wildcard placeholder string. Default: "<*>".
func WithParameterExtractionCacheCapacity ¶
WithParameterExtractionCacheCapacity bounds compiled parameter extraction regexes. Zero disables caching.
func WithParametrizeNumericTokens ¶
WithParametrizeNumericTokens controls whether numeric tokens are routed to the wildcard node in the prefix tree. Default: true.
func WithPersistence ¶
func WithPersistence(handler PersistenceHandler) Option
WithPersistence sets a persistence handler for saving/loading state.
func WithProfiling ¶
WithProfiling enables the built-in simple profiler.
func WithRegexTimeout ¶
WithRegexTimeout limits the execution time of each masking regular expression. A zero timeout disables timeout checks. Default: 100ms.
func WithSnapshotInterval ¶
WithSnapshotInterval sets how often state is auto-saved (in minutes). Default: 5.
type ParameterExtractor ¶
type ParameterExtractor struct {
// contains filtered or unexported fields
}
ParameterExtractor extracts variable values from log messages given a template.
func NewParameterExtractor ¶
func NewParameterExtractor(masker *LogMasker, extraDelimiters []string) *ParameterExtractor
NewParameterExtractor creates a new ParameterExtractor. Extra delimiters are treated as literal strings, consistent with Drain's tokenization.
func NewParameterExtractorWithCapacity ¶
func NewParameterExtractorWithCapacity( masker *LogMasker, extraDelimiters []string, cacheCapacity int, ) (*ParameterExtractor, error)
NewParameterExtractorWithCapacity creates an extractor with a bounded LRU cache. A capacity of zero disables caching.
func (*ParameterExtractor) ExtractParameters ¶
func (pe *ParameterExtractor) ExtractParameters(logTemplate, logMessage string, exactMatching bool) []ExtractedParameter
ExtractParameters extracts parameter values from a log message according to a template. If exactMatching is true and a masker is provided, mask-specific regex patterns are used to capture parameter values more accurately. Returns nil if the message does not match the template.
type PersistenceHandler ¶
PersistenceHandler defines the interface for saving/loading Drain state.
type Profiler ¶
type Profiler interface {
StartSection(sectionName string)
EndSection(sectionName string)
Report(reset bool) string
}
Profiler is an interface for tracking timing of sections in the mining pipeline.
type ProfilingSection ¶
ProfilingSection holds profiling configuration.
type SearchStrategy ¶
type SearchStrategy int
SearchStrategy controls how Drain searches for matching clusters.
const ( // SearchStrategyNever disables searching — only new clusters are created. SearchStrategyNever SearchStrategy = iota // SearchStrategyFallback searches existing clusters only when tree search fails. SearchStrategyFallback // SearchStrategyAlways always searches all clusters for the best match. SearchStrategyAlways )
func (SearchStrategy) String ¶
func (s SearchStrategy) String() string
type SimpleProfiler ¶
type SimpleProfiler struct {
// contains filtered or unexported fields
}
SimpleProfiler tracks cumulative time spent in named sections.
func NewSimpleProfiler ¶
func NewSimpleProfiler() *SimpleProfiler
NewSimpleProfiler creates a new SimpleProfiler.
func (*SimpleProfiler) EndSection ¶
func (p *SimpleProfiler) EndSection(sectionName string)
EndSection ends timing a named section and records the elapsed time.
func (*SimpleProfiler) Report ¶
func (p *SimpleProfiler) Report(reset bool) string
Report returns a formatted string with profiling results. If reset is true, all accumulated stats are cleared.
func (*SimpleProfiler) StartSection ¶
func (p *SimpleProfiler) StartSection(sectionName string)
StartSection begins timing a named section.
type SnapshotSection ¶
type SnapshotSection struct {
SnapshotIntervalMinutes int `yaml:"snapshot_interval_minutes"`
CompressState bool `yaml:"compress_state"`
}
SnapshotSection holds persistence/snapshot configuration.
type StateClearer ¶
type StateClearer interface {
ClearState() error
}
StateClearer is an optional interface for persistence backends that can clear corrupted state and continue with a fresh miner state.
type StateSizeProvider ¶
StateSizeProvider optionally reports persisted size before loading, allowing callers to reject oversized state without first allocating it.
type TemplateMiner ¶
type TemplateMiner struct {
Drain *Drain
Config *Config
Persistence PersistenceHandler
Profiler Profiler
Masker *LogMasker
// contains filtered or unexported fields
}
TemplateMiner is the high-level API that integrates Drain, masking, persistence, and profiling. Its public mining, matching, profiling, and persistence methods are safe for concurrent use.
func New ¶
func New(opts ...Option) (*TemplateMiner, error)
New creates a new TemplateMiner with functional options.
Example:
tm, err := drain3.New(
drain3.WithSimTh(0.5),
drain3.WithDepth(5),
drain3.WithMaxClusters(1000),
drain3.WithMasking(`\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}`, "IP"),
drain3.WithMasking(`\b\d+\b`, "NUM"),
drain3.WithFilePersistence("/tmp/drain3_state.json"),
)
Example ¶
package main
import (
"errors"
"fmt"
"sort"
"github.com/FEINIAO233/drain3/v2"
)
func requireCluster(result *drain3.AddLogMessageResult) *drain3.LogCluster {
if result.InputError != nil {
panic(result.InputError)
}
if result.MaskError != nil {
panic(result.MaskError)
}
if result.Cluster == nil {
panic(errors.New("drain3 returned no cluster"))
}
if result.SaveError != nil {
panic(result.SaveError)
}
return result.Cluster
}
func main() {
// Create with defaults
tm, err := drain3.New()
if err != nil {
panic(err)
}
messages := []string{
"Failed password for invalid user admin from 192.168.1.1 port 22 ssh2",
"Failed password for invalid user root from 10.0.0.1 port 22 ssh2",
"Failed password for invalid user test from 172.16.0.1 port 22 ssh2",
"Accepted password for admin from 192.168.1.1 port 22 ssh2",
"Accepted password for admin from 10.0.0.1 port 22 ssh2",
}
for _, msg := range messages {
result := tm.AddLogMessage(msg)
cluster := requireCluster(result)
fmt.Printf("change=%s cluster=%s\n", result.ChangeType, cluster.GetTemplate())
}
fmt.Printf("\nDiscovered %d templates:\n", tm.ClusterCount())
clusters := tm.Clusters()
sort.Slice(clusters, func(i, j int) bool {
return clusters[i].ClusterID < clusters[j].ClusterID
})
for _, c := range clusters {
fmt.Printf(" [size=%d] %s\n", c.Size, c.GetTemplate())
}
}
Output: change=cluster_created cluster=Failed password for invalid user admin from 192.168.1.1 port 22 ssh2 change=cluster_template_changed cluster=Failed password for invalid user <*> from <*> port 22 ssh2 change=none cluster=Failed password for invalid user <*> from <*> port 22 ssh2 change=cluster_created cluster=Accepted password for admin from 192.168.1.1 port 22 ssh2 change=cluster_template_changed cluster=Accepted password for admin from <*> port 22 ssh2 Discovered 2 templates: [size=3] Failed password for invalid user <*> from <*> port 22 ssh2 [size=2] Accepted password for admin from <*> port 22 ssh2
Example (WithOptions) ¶
package main
import (
"errors"
"fmt"
"github.com/FEINIAO233/drain3/v2"
)
func requireCluster(result *drain3.AddLogMessageResult) *drain3.LogCluster {
if result.InputError != nil {
panic(result.InputError)
}
if result.MaskError != nil {
panic(result.MaskError)
}
if result.Cluster == nil {
panic(errors.New("drain3 returned no cluster"))
}
if result.SaveError != nil {
panic(result.SaveError)
}
return result.Cluster
}
func main() {
// Create with custom options
tm, err := drain3.New(
drain3.WithSimTh(0.5),
drain3.WithMasking(`\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}`, "IP"),
drain3.WithMasking(`\b\d+\b`, "NUM"),
)
if err != nil {
panic(err)
}
messages := []string{
"connection from 192.168.1.1 port 22",
"connection from 10.0.0.1 port 8080",
"disconnect from 192.168.1.1 port 443",
}
for _, msg := range messages {
result := tm.AddLogMessage(msg)
fmt.Printf("template: %s\n", requireCluster(result).GetTemplate())
}
}
Output: template: connection from <IP> port <NUM> template: connection from <IP> port <NUM> template: disconnect from <IP> port <NUM>
func NewTemplateMiner ¶
func NewTemplateMiner(persistence PersistenceHandler, config *Config) (*TemplateMiner, error)
NewTemplateMiner creates a new TemplateMiner with the given persistence handler and config. If config is nil, DefaultConfig() is used. If persistence is nil, no persistence is performed.
func (*TemplateMiner) AddLogMessage ¶
func (tm *TemplateMiner) AddLogMessage(message string) *AddLogMessageResult
AddLogMessage processes a log message through the masking and Drain pipeline.
func (*TemplateMiner) ClusterCount ¶
func (tm *TemplateMiner) ClusterCount() int
ClusterCount returns the number of active clusters.
func (*TemplateMiner) Clusters ¶
func (tm *TemplateMiner) Clusters() []*LogCluster
Clusters returns all current log clusters.
func (*TemplateMiner) GetProfilerReport ¶
func (tm *TemplateMiner) GetProfilerReport(reset bool) string
GetProfilerReport returns the profiler report string.
func (*TemplateMiner) LoadState ¶
func (tm *TemplateMiner) LoadState() error
LoadState restores Drain state from persistence.
func (*TemplateMiner) Match ¶
func (tm *TemplateMiner) Match(message string, strategy SearchStrategy) *LogCluster
Match finds the best matching cluster for a log message without modifying state.
func (*TemplateMiner) MatchWithError ¶
func (tm *TemplateMiner) MatchWithError(message string, strategy SearchStrategy) (*LogCluster, error)
MatchWithError finds the best matching cluster and reports masking failures, including regular expression timeouts.
func (*TemplateMiner) NewParameterExtractor ¶
func (tm *TemplateMiner) NewParameterExtractor() *ParameterExtractor
NewParameterExtractor creates an extractor using this miner's delimiter, masking, and cache-limit configuration.
func (*TemplateMiner) SaveState ¶
func (tm *TemplateMiner) SaveState() error
SaveState persists the current Drain state.