feat: implement new generic parser and improve production readyness
This commit is contained in:
parent
8364218234
commit
0830b403e0
34 changed files with 1715 additions and 2114 deletions
179
patterns/repository.go
Normal file
179
patterns/repository.go
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
// 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]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue