97 lines
2.1 KiB
Go
97 lines
2.1 KiB
Go
package cleaner
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/cyrilix/pod-cleaner/pkg/metrics"
|
|
"github.com/cyrilix/pod-cleaner/pkg/monitor"
|
|
"go.uber.org/zap"
|
|
"regexp"
|
|
"strconv"
|
|
"sync"
|
|
)
|
|
|
|
var (
|
|
defaultRegex = regexp.MustCompile("There were many similar errors. Turn up verbosity to see them.\" err=\\\"orphaned pod \\\\\"(?P<podId>[0-9a-f\\-]+)\\\\\" found, but error not a directory occurred when trying to remove the volumes dir\" numErrs=(?P<numErrs>[0-9]+)")
|
|
)
|
|
|
|
func NewPodWatcher(logfile string) *PodWatcher {
|
|
return &PodWatcher{
|
|
m: monitor.New(),
|
|
rex: defaultRegex,
|
|
logfile: logfile,
|
|
cancel: make(chan interface{}),
|
|
}
|
|
}
|
|
|
|
type PodWatcher struct {
|
|
m monitor.Monitor
|
|
rex *regexp.Regexp
|
|
logfile string
|
|
|
|
cancel chan interface{}
|
|
|
|
muPodError sync.RWMutex
|
|
numErrors int
|
|
podIdErrors string
|
|
}
|
|
|
|
func (w *PodWatcher) Close() error {
|
|
close(w.cancel)
|
|
if w.m != nil {
|
|
err := w.m.Close()
|
|
if err != nil {
|
|
zap.S().Errorf("unable to close monitor resource: %v", err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (w *PodWatcher) GetNumErrors() int {
|
|
w.muPodError.RLock()
|
|
defer w.muPodError.RUnlock()
|
|
return w.numErrors
|
|
}
|
|
|
|
func (w *PodWatcher) GetPodDirInError() string {
|
|
w.muPodError.RLock()
|
|
defer w.muPodError.RUnlock()
|
|
if w.podIdErrors == "" {
|
|
return ""
|
|
}
|
|
return fmt.Sprintf("/var/lib/kubelet/pods/%s", w.podIdErrors)
|
|
}
|
|
|
|
func (w *PodWatcher) Watch() {
|
|
lineChan := make(chan string)
|
|
go func() {
|
|
err := w.m.Watch(w.logfile, w.rex, lineChan)
|
|
if err != nil {
|
|
zap.S().Panicf("unable to init watching on file '%s', %v", w.logfile, err)
|
|
}
|
|
close(w.cancel)
|
|
}()
|
|
|
|
for {
|
|
select {
|
|
case line := <-lineChan:
|
|
w.processLogRecord(line)
|
|
case <-w.cancel:
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func (w *PodWatcher) processLogRecord(line string) {
|
|
numErrors, err := strconv.Atoi(w.rex.FindStringSubmatch(line)[w.rex.SubexpIndex("numErrs")])
|
|
if err != nil {
|
|
zap.S().Errorf("unable to extract numErrors value from line '%v': %v", line, err)
|
|
return
|
|
}
|
|
w.muPodError.Lock()
|
|
defer w.muPodError.Unlock()
|
|
w.numErrors = numErrors
|
|
w.podIdErrors = w.rex.FindStringSubmatch(line)[w.rex.SubexpIndex("podId")]
|
|
|
|
metrics.NumErrors.Set(float64(numErrors))
|
|
}
|