feat: implement drain3 based generic log-parser
This commit is contained in:
parent
1d1568e3ee
commit
5af49f926a
17 changed files with 612 additions and 220 deletions
|
|
@ -1,93 +1,3 @@
|
|||
// package patterns
|
||||
|
||||
// import (
|
||||
// "fmt"
|
||||
// "regexp"
|
||||
// "sync"
|
||||
|
||||
// "gopkg.in/yaml.v3"
|
||||
// "os"
|
||||
// )
|
||||
|
||||
// type PatternConfig struct {
|
||||
// Patterns map[string]map[string]PatternDefinition `yaml:"patterns"`
|
||||
// }
|
||||
|
||||
// type PatternDefinition struct {
|
||||
// Regex string `yaml:"regex"`
|
||||
// Description string `yaml:"description,omitempty"`
|
||||
// }
|
||||
|
||||
// type Repository struct {
|
||||
// compiledPatterns map[string]map[string]*regexp.Regexp
|
||||
// mu sync.RWMutex
|
||||
// }
|
||||
|
||||
// var (
|
||||
// instance *Repository
|
||||
// once sync.Once
|
||||
// )
|
||||
|
||||
// func GetInstance() *Repository {
|
||||
// once.Do(func() {
|
||||
// instance = &Repository{
|
||||
// compiledPatterns: make(map[string]map[string]*regexp.Regexp),
|
||||
// }
|
||||
// })
|
||||
// return instance
|
||||
// }
|
||||
|
||||
// func (r *Repository) Load(path string) error {
|
||||
// r.mu.Lock()
|
||||
// defer r.mu.Unlock()
|
||||
|
||||
// data, err := os.ReadFile(path)
|
||||
// if err != nil {
|
||||
// return fmt.Errorf("failed to read pattern config: %w", err)
|
||||
// }
|
||||
|
||||
// var config PatternConfig
|
||||
// if err := yaml.Unmarshal(data, &config); err != nil {
|
||||
// return fmt.Errorf("failed to parse pattern config: %w", err)
|
||||
// }
|
||||
|
||||
// for service, patterns := range config.Patterns {
|
||||
// if _, exists := r.compiledPatterns[service]; !exists {
|
||||
// r.compiledPatterns[service] = make(map[string]*regexp.Regexp)
|
||||
// }
|
||||
|
||||
// for name, def := range patterns {
|
||||
// compiled, err := regexp.Compile(def.Regex)
|
||||
// if err != nil {
|
||||
// return fmt.Errorf("invalid regex for %s/%s: %w", service, name, err)
|
||||
// }
|
||||
// r.compiledPatterns[service][name] = compiled
|
||||
// }
|
||||
// }
|
||||
|
||||
// return nil
|
||||
// }
|
||||
|
||||
// func (r *Repository) Get(service string, name string) (*regexp.Regexp, error) {
|
||||
// r.mu.RLock()
|
||||
// defer r.mu.RUnlock()
|
||||
|
||||
// if svcPatterns, ok := r.compiledPatterns[service]; ok {
|
||||
// if pattern, ok := svcPatterns[name]; ok {
|
||||
// return pattern, nil
|
||||
// }
|
||||
// }
|
||||
|
||||
// return nil, fmt.Errorf("pattern not found: %s/%s", service, name)
|
||||
// }
|
||||
|
||||
// func (r *Repository) MustGet(service string, name string) *regexp.Regexp {
|
||||
// p, err := r.Get(service, name)
|
||||
// if err != nil {
|
||||
// panic(err)
|
||||
// }
|
||||
// return p
|
||||
// }
|
||||
package patterns
|
||||
|
||||
import (
|
||||
|
|
@ -99,7 +9,6 @@ import (
|
|||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// Struktur der YAML Datei
|
||||
type Config struct {
|
||||
Patterns map[string]ServiceConfig `yaml:"patterns"`
|
||||
}
|
||||
|
|
@ -111,10 +20,9 @@ type ServiceConfig struct {
|
|||
type ExtractorConfig struct {
|
||||
Name string `yaml:"name"`
|
||||
Regex string `yaml:"regex"`
|
||||
Fields map[string]string `yaml:"fields"` // Name -> Typ (int, float, string)
|
||||
Fields map[string]string `yaml:"fields"`
|
||||
}
|
||||
|
||||
// Interne kompilierte Struktur
|
||||
type CompiledExtractor struct {
|
||||
Name string
|
||||
Pattern *regexp.Regexp
|
||||
|
|
|
|||
51
patterns/repository_test.go
Normal file
51
patterns/repository_test.go
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
package patterns
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRepository_Load(t *testing.T) {
|
||||
content := `
|
||||
patterns:
|
||||
test_service:
|
||||
extractors:
|
||||
- name: "test_pattern"
|
||||
regex: '^Test (?P<id>\d+) (?P<value>\d+\.\d+)$'
|
||||
fields:
|
||||
id: "int"
|
||||
value: "float"
|
||||
`
|
||||
tmpfile, err := os.CreateTemp("", "patterns_test_*.yaml")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.Remove(tmpfile.Name())
|
||||
|
||||
if _, err := tmpfile.Write([]byte(content)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := tmpfile.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
repo := GetInstance()
|
||||
err = repo.Load(tmpfile.Name())
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to load repository: %v", err)
|
||||
}
|
||||
|
||||
extractors := repo.GetExtractors("test_service")
|
||||
if len(extractors) != 1 {
|
||||
t.Errorf("Expected 1 extractor, got %d", len(extractors))
|
||||
}
|
||||
|
||||
ext := extractors[0]
|
||||
if ext.Name != "test_pattern" {
|
||||
t.Errorf("Expected name 'test_pattern', got '%s'", ext.Name)
|
||||
}
|
||||
|
||||
if !ext.Pattern.MatchString("Test 123 45.67") {
|
||||
t.Error("Regex did not match valid string")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue