87 lines
1.7 KiB
Go
87 lines
1.7 KiB
Go
package patterns
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"regexp"
|
|
"sync"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
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"`
|
|
}
|
|
|
|
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]
|
|
}
|