// 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] }