watch-tool/patterns/repository.go

179 lines
3.8 KiB
Go

// 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 (
"fmt"
"os"
"regexp"
"sync"
"gopkg.in/yaml.v3"
)
// Struktur der YAML Datei
type Config struct {
Patterns map[string]ServiceConfig `yaml:"patterns"`
}
type ServiceConfig struct {
Extractors []ExtractorConfig `yaml:"extractors"`
}
type ExtractorConfig struct {
Name string `yaml:"name"`
Regex string `yaml:"regex"`
Fields map[string]string `yaml:"fields"` // Name -> Typ (int, float, string)
}
// Interne kompilierte Struktur
type CompiledExtractor struct {
Name string
Pattern *regexp.Regexp
Fields map[string]string
}
type Repository struct {
services map[string][]CompiledExtractor
mu sync.RWMutex
}
var (
instance *Repository
once sync.Once
)
func GetInstance() *Repository {
once.Do(func() {
instance = &Repository{
services: make(map[string][]CompiledExtractor),
}
})
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 patterns file: %w", err)
}
var cfg Config
if err := yaml.Unmarshal(data, &cfg); err != nil {
return fmt.Errorf("failed to parse yaml: %w", err)
}
for service, svcCfg := range cfg.Patterns {
var compiledList []CompiledExtractor
for _, ext := range svcCfg.Extractors {
re, err := regexp.Compile(ext.Regex)
if err != nil {
return fmt.Errorf("invalid regex in service %s extractor %s: %w", service, ext.Name, err)
}
compiledList = append(compiledList, CompiledExtractor{
Name: ext.Name,
Pattern: re,
Fields: ext.Fields,
})
}
r.services[service] = compiledList
}
return nil
}
func (r *Repository) GetExtractors(service string) []CompiledExtractor {
r.mu.RLock()
defer r.mu.RUnlock()
return r.services[service]
}