Permit regex ignores. Fixes #18
This commit is contained in:
parent
075b9252b7
commit
b3791319d8
@ -42,18 +42,29 @@ func cmdStdout(commandline []string) chan *string {
|
|||||||
return lines
|
return lines
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Pattern) notAnIgnore(match *string) bool {
|
||||||
|
for _, ignore := range p.Ignore {
|
||||||
|
if ignore == *match {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// Whether one of the filter's regexes is matched on a line
|
// Whether one of the filter's regexes is matched on a line
|
||||||
func (f *Filter) match(line *string) string {
|
func (f *Filter) match(line *string) string {
|
||||||
for _, regex := range f.compiledRegex {
|
for _, regex := range f.compiledRegex {
|
||||||
|
|
||||||
if matches := regex.FindStringSubmatch(*line); matches != nil {
|
if matches := regex.FindStringSubmatch(*line); matches != nil {
|
||||||
|
|
||||||
match := matches[regex.SubexpIndex(f.patternName)]
|
match := matches[regex.SubexpIndex(f.pattern.name)]
|
||||||
|
|
||||||
|
if f.pattern.notAnIgnore(&match) {
|
||||||
log.Printf("INFO %s.%s: match [%v]\n", f.stream.name, f.name, match)
|
log.Printf("INFO %s.%s: match [%v]\n", f.stream.name, f.name, match)
|
||||||
return match
|
return match
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +105,7 @@ func (a *Action) exec(match string, advance time.Duration) {
|
|||||||
if doExec {
|
if doExec {
|
||||||
computedCommand := make([]string, 0, len(a.Cmd))
|
computedCommand := make([]string, 0, len(a.Cmd))
|
||||||
for _, item := range a.Cmd {
|
for _, item := range a.Cmd {
|
||||||
computedCommand = append(computedCommand, strings.ReplaceAll(item, a.filter.patternWithBraces, match))
|
computedCommand = append(computedCommand, strings.ReplaceAll(item, a.filter.pattern.nameWithBraces, match))
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("INFO %s.%s.%s: run %s\n", a.filter.stream.name, a.filter.name, a.name, computedCommand)
|
log.Printf("INFO %s.%s.%s: run %s\n", a.filter.stream.name, a.filter.name, a.name, computedCommand)
|
||||||
|
@ -15,10 +15,18 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Conf struct {
|
type Conf struct {
|
||||||
Patterns map[string]string `yaml:"patterns"`
|
Patterns map[string]*Pattern `yaml:"patterns"`
|
||||||
Streams map[string]*Stream `yaml:"streams"`
|
Streams map[string]*Stream `yaml:"streams"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Pattern struct {
|
||||||
|
Regex string `yaml:"regex"`
|
||||||
|
Ignore []string `yaml:"ignore"`
|
||||||
|
|
||||||
|
name string `yaml:"-"`
|
||||||
|
nameWithBraces string `yaml:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
// Stream, Filter & Action structures must never be copied.
|
// Stream, Filter & Action structures must never be copied.
|
||||||
// They're always referenced through pointers
|
// They're always referenced through pointers
|
||||||
|
|
||||||
@ -35,8 +43,7 @@ type Filter struct {
|
|||||||
|
|
||||||
Regex []string `yaml:"regex"`
|
Regex []string `yaml:"regex"`
|
||||||
compiledRegex []regexp.Regexp `yaml:"-"`
|
compiledRegex []regexp.Regexp `yaml:"-"`
|
||||||
patternName string `yaml:"-"`
|
pattern *Pattern `yaml:"-"`
|
||||||
patternWithBraces string `yaml:"-"`
|
|
||||||
|
|
||||||
Retry int `yaml:"retry"`
|
Retry int `yaml:"retry"`
|
||||||
RetryPeriod string `yaml:"retry-period"`
|
RetryPeriod string `yaml:"retry-period"`
|
||||||
@ -68,9 +75,28 @@ type LogEntry struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *Conf) setup() {
|
func (c *Conf) setup() {
|
||||||
for patternName, pattern := range c.Patterns {
|
|
||||||
c.Patterns[patternName] = fmt.Sprintf("(?P<%s>%s)", patternName, pattern)
|
for patternName := range c.Patterns {
|
||||||
|
pattern := c.Patterns[patternName]
|
||||||
|
pattern.name = patternName
|
||||||
|
pattern.nameWithBraces = fmt.Sprintf("<%s>", pattern.name)
|
||||||
|
|
||||||
|
if pattern.Regex == "" {
|
||||||
|
log.Fatalf("FATAL Bad configuration: pattern's regex %v is empty!", patternName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compiled, err := regexp.Compile(fmt.Sprintf("^%v$", pattern.Regex))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("FATAL Bad configuration: pattern %v doesn't compile!", patternName)
|
||||||
|
}
|
||||||
|
c.Patterns[patternName].Regex = fmt.Sprintf("(?P<%s>%s)", patternName, pattern.Regex)
|
||||||
|
for _, ignore := range pattern.Ignore {
|
||||||
|
if !compiled.MatchString(ignore) {
|
||||||
|
log.Fatalf("FATAL Bad configuration: pattern ignore '%v' doesn't match pattern %v! It should be fixed or removed.", ignore, pattern.nameWithBraces)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(c.Streams) == 0 {
|
if len(c.Streams) == 0 {
|
||||||
log.Fatalln("FATAL Bad configuration: no streams configured!")
|
log.Fatalln("FATAL Bad configuration: no streams configured!")
|
||||||
}
|
}
|
||||||
@ -109,24 +135,24 @@ func (c *Conf) setup() {
|
|||||||
// Look for Patterns inside Regexes
|
// Look for Patterns inside Regexes
|
||||||
for _, regex := range filter.Regex {
|
for _, regex := range filter.Regex {
|
||||||
for patternName, pattern := range c.Patterns {
|
for patternName, pattern := range c.Patterns {
|
||||||
if strings.Contains(regex, patternName) {
|
if strings.Contains(regex, pattern.nameWithBraces) {
|
||||||
|
|
||||||
switch filter.patternName {
|
if filter.pattern == nil {
|
||||||
case "":
|
filter.pattern = pattern
|
||||||
filter.patternName = patternName
|
} else if filter.pattern == pattern {
|
||||||
filter.patternWithBraces = fmt.Sprintf("<%s>", patternName)
|
|
||||||
case patternName:
|
|
||||||
// no op
|
// no op
|
||||||
default:
|
} else {
|
||||||
log.Fatalf(
|
log.Fatalf(
|
||||||
"Bad configuration: Can't mix different patterns (%s, %s) in same filter (%s.%s)\n",
|
"Bad configuration: Can't mix different patterns (%s, %s) in same filter (%s.%s)\n",
|
||||||
filter.patternName, patternName, streamName, filterName,
|
filter.pattern.name, patternName, streamName, filterName,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
regex = strings.Replace(regex, fmt.Sprintf("<%s>", patternName), pattern, 1)
|
// FIXME should go in the `if filter.pattern == nil`?
|
||||||
|
regex = strings.Replace(regex, pattern.nameWithBraces, pattern.Regex, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// TODO regexp.Compile and show proper message if it doesn't instead of panicing
|
||||||
filter.compiledRegex = append(filter.compiledRegex, *regexp.MustCompile(regex))
|
filter.compiledRegex = append(filter.compiledRegex, *regexp.MustCompile(regex))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,20 +1,19 @@
|
|||||||
---
|
---
|
||||||
patterns:
|
patterns:
|
||||||
ip: '(([0-9]{1,3}\.){3}[0-9]{1,3})|([0-9a-fA-F:]{2,90})'
|
ip:
|
||||||
|
regex: '(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3})|(?:[0-9a-fA-F:]{2,90})'
|
||||||
|
ignore:
|
||||||
|
- 1.0.0.1
|
||||||
|
|
||||||
streams:
|
streams:
|
||||||
tailDown:
|
tailDown:
|
||||||
cmd: [ "sh", "-c", "echo 'found 1.1.1.1' && sleep 2s && echo 'found 1.1.1.2' && sleep 2s && echo 'found 1.1.1.1' && sleep 10m" ]
|
cmd: [ "sh", "-c", "echo 'found 1.1.1.1' && sleep 2 && echo 'found 1.0.0.1' && sleep 10m" ]
|
||||||
filters:
|
filters:
|
||||||
findIP:
|
findIP:
|
||||||
regex:
|
regex:
|
||||||
- found <ip>
|
- '^found <ip>'
|
||||||
retry: 2
|
retry: 2
|
||||||
retry-period: 1m
|
retry-period: 1m
|
||||||
actions:
|
actions:
|
||||||
damn:
|
damn:
|
||||||
cmd: [ "echo", "<ip>" ]
|
cmd: [ "echo", "<ip>" ]
|
||||||
sleepdamn:
|
|
||||||
cmd: [ "echo", "sleep", "<ip>" ]
|
|
||||||
after: 8m
|
|
||||||
onexit: true
|
|
||||||
|
@ -8,7 +8,11 @@ definitions:
|
|||||||
# patterns are substitued in regexes.
|
# patterns are substitued in regexes.
|
||||||
# when a filter performs an action, it replaces the found pattern
|
# when a filter performs an action, it replaces the found pattern
|
||||||
patterns:
|
patterns:
|
||||||
ip: '(([0-9]{1,3}\.){3}[0-9]{1,3})|([0-9a-fA-F:]{2,90})'
|
ip:
|
||||||
|
regex: '(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3})|(?:[0-9a-fA-F:]{2,90})'
|
||||||
|
ignore:
|
||||||
|
- 127.0.0.1
|
||||||
|
- ::1
|
||||||
|
|
||||||
# streams are command that are run
|
# streams are command that are run
|
||||||
# their output will be used by one or more filters
|
# their output will be used by one or more filters
|
||||||
|
Loading…
Reference in New Issue
Block a user