diff --git a/Dockerfile.in b/Dockerfile.in index a75d79bc..40181d23 100644 --- a/Dockerfile.in +++ b/Dockerfile.in @@ -20,4 +20,4 @@ RUN test -h /etc/localtime && rm -f /etc/localtime && cp /usr/share/zoneinfo/UTC ADD ./bin/node-problem-detector /node-problem-detector ADD config /config -ENTRYPOINT ["/node-problem-detector", "--kernel-monitor=/config/kernel-monitor.json"] +ENTRYPOINT ["/node-problem-detector", "--system-log-monitor=/config/kernel-monitor.json"] diff --git a/README.md b/README.md index 6ed661fe..0bf31095 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ List of supported problem daemons: | Problem Daemon | NodeCondition | Description | |----------------|:---------------:|:------------| -| [KernelMonitor](https://github.com/kubernetes/node-problem-detector/tree/master/pkg/kernelmonitor) | KernelDeadlock | A problem daemon monitors kernel log and reports problem according to predefined rules. | +| [KernelMonitor](https://github.com/kubernetes/node-problem-detector/tree/master/pkg/logmonitor) | KernelDeadlock | A problem daemon monitors kernel log and reports problem according to predefined rules. | # Usage ## Flags diff --git a/cmd/node_problem_detector.go b/cmd/node_problem_detector.go index 796c7447..9234eadd 100644 --- a/cmd/node_problem_detector.go +++ b/cmd/node_problem_detector.go @@ -26,10 +26,10 @@ import ( "github.com/golang/glog" "github.com/spf13/pflag" - "k8s.io/node-problem-detector/pkg/kernelmonitor" "k8s.io/node-problem-detector/pkg/options" "k8s.io/node-problem-detector/pkg/problemclient" "k8s.io/node-problem-detector/pkg/problemdetector" + "k8s.io/node-problem-detector/pkg/systemlogmonitor" "k8s.io/node-problem-detector/pkg/version" ) @@ -67,9 +67,9 @@ func main() { os.Exit(0) } - k := kernelmonitor.NewKernelMonitorOrDie(npdo.KernelMonitorConfigPath) + l := systemlogmonitor.NewLogMonitorOrDie(npdo.SystemLogMonitorConfigPath) c := problemclient.NewClientOrDie(npdo) - p := problemdetector.NewProblemDetector(k, c) + p := problemdetector.NewProblemDetector(l, c) // Start http server. if npdo.ServerPort > 0 { diff --git a/config/docker-monitor-filelog.json b/config/docker-monitor-filelog.json index d4ee0c62..349b7adc 100644 --- a/config/docker-monitor-filelog.json +++ b/config/docker-monitor-filelog.json @@ -1,5 +1,5 @@ { - "plugin": "syslog", + "plugin": "filelog", "pluginConfig": { "timestamp": "^time=\"(\\S*)\"", "message": "msg=\"([^\n]*)\"", diff --git a/config/kernel-monitor-filelog.json b/config/kernel-monitor-filelog.json index e95b5ad1..e24bacd3 100644 --- a/config/kernel-monitor-filelog.json +++ b/config/kernel-monitor-filelog.json @@ -1,5 +1,5 @@ { - "plugin": "syslog", + "plugin": "filelog", "pluginConfig": { "timestamp": "^.{15}", "message": "kernel: \\[.*\\] (.*)", diff --git a/pkg/options/options.go b/pkg/options/options.go index e9d21f07..81c4dac9 100644 --- a/pkg/options/options.go +++ b/pkg/options/options.go @@ -30,8 +30,8 @@ import ( type NodeProblemDetectorOptions struct { // command line options - // KernelMonitorConfigPath specifies the path to kernel monitor configuration file. - KernelMonitorConfigPath string + // SystemLogMonitorConfigPath specifies the path to system log monitor configuration file. + SystemLogMonitorConfigPath string // ApiServerOverride is the custom URI used to connect to Kubernetes ApiServer. ApiServerOverride string // PrintVersion is the flag determining whether version information is printed. @@ -55,8 +55,8 @@ func NewNodeProblemDetectorOptions() *NodeProblemDetectorOptions { // AddFlags adds node problem detector command line options to pflag. func (npdo *NodeProblemDetectorOptions) AddFlags(fs *pflag.FlagSet) { - fs.StringVar(&npdo.KernelMonitorConfigPath, "kernel-monitor", - "/config/kernel-monitor.json", "The path to the kernel monitor config file") + fs.StringVar(&npdo.SystemLogMonitorConfigPath, "system-log-monitor", + "/config/kernel-monitor.json", "The path to the system log monitor config file") fs.StringVar(&npdo.ApiServerOverride, "apiserver-override", "", "Custom URI used to connect to Kubernetes ApiServer") fs.BoolVar(&npdo.PrintVersion, "version", false, "Print version information and quit") diff --git a/pkg/problemdetector/problem_detector.go b/pkg/problemdetector/problem_detector.go index 82388c9f..d489cc8c 100644 --- a/pkg/problemdetector/problem_detector.go +++ b/pkg/problemdetector/problem_detector.go @@ -24,8 +24,8 @@ import ( "k8s.io/kubernetes/pkg/util/clock" "k8s.io/node-problem-detector/pkg/condition" - "k8s.io/node-problem-detector/pkg/kernelmonitor" "k8s.io/node-problem-detector/pkg/problemclient" + "k8s.io/node-problem-detector/pkg/systemlogmonitor" "k8s.io/node-problem-detector/pkg/util" ) @@ -39,12 +39,12 @@ type problemDetector struct { client problemclient.Client conditionManager condition.ConditionManager // TODO(random-liu): Use slices of problem daemons if multiple monitors are needed in the future - monitor kernelmonitor.KernelMonitor + monitor systemlogmonitor.LogMonitor } // NewProblemDetector creates the problem detector. Currently we just directly passed in the problem daemons, but // in the future we may want to let the problem daemons register themselves. -func NewProblemDetector(monitor kernelmonitor.KernelMonitor, client problemclient.Client) ProblemDetector { +func NewProblemDetector(monitor systemlogmonitor.LogMonitor, client problemclient.Client) ProblemDetector { return &problemDetector{ client: client, conditionManager: condition.NewConditionManager(client, clock.RealClock{}), diff --git a/pkg/kernelmonitor/README.md b/pkg/systemlogmonitor/README.md similarity index 90% rename from pkg/kernelmonitor/README.md rename to pkg/systemlogmonitor/README.md index afb838b3..de8fcefb 100644 --- a/pkg/kernelmonitor/README.md +++ b/pkg/systemlogmonitor/README.md @@ -43,8 +43,8 @@ with new rule definition: Kernel monitor supports different log management tools with different log watchers: -* [syslog](https://github.com/kubernetes/node-problem-detector/blob/master/pkg/kernelmonitor/logwatchers/syslog) -* [journald](https://github.com/kubernetes/node-problem-detector/blob/master/pkg/kernelmonitor/logwatchers/journald) +* [syslog](https://github.com/kubernetes/node-problem-detector/blob/master/pkg/logmonitor/logwatchers/syslog) +* [journald](https://github.com/kubernetes/node-problem-detector/blob/master/pkg/logmonitor/logwatchers/journald) ### Change Log Path @@ -57,5 +57,5 @@ You can always configure `logPath` and volume mount to match your OS distro. ### New Log Watcher Kernel monitor uses [Log -Watcher](https://github.com/kubernetes/node-problem-detector/blob/master/pkg/kernelmonitor/logwatchers/types/log_watcher.go) to support different log management tools. +Watcher](https://github.com/kubernetes/node-problem-detector/blob/master/pkg/logmonitor/logwatchers/types/log_watcher.go) to support different log management tools. It is easy to implement a new log watcher. diff --git a/pkg/kernelmonitor/config.go b/pkg/systemlogmonitor/config.go similarity index 71% rename from pkg/kernelmonitor/config.go rename to pkg/systemlogmonitor/config.go index 79fc27a9..1e8813ec 100644 --- a/pkg/kernelmonitor/config.go +++ b/pkg/systemlogmonitor/config.go @@ -14,26 +14,26 @@ See the License for the specific language governing permissions and limitations under the License. */ -package kernelmonitor +package systemlogmonitor import ( - watchertypes "k8s.io/node-problem-detector/pkg/kernelmonitor/logwatchers/types" - kerntypes "k8s.io/node-problem-detector/pkg/kernelmonitor/types" + watchertypes "k8s.io/node-problem-detector/pkg/systemlogmonitor/logwatchers/types" + logtypes "k8s.io/node-problem-detector/pkg/systemlogmonitor/types" "k8s.io/node-problem-detector/pkg/types" ) -// MonitorConfig is the configuration of kernel monitor. +// MonitorConfig is the configuration of log monitor. type MonitorConfig struct { - // WatcherConfig is the configuration of kernel log watcher. + // WatcherConfig is the configuration of log watcher. watchertypes.WatcherConfig // BufferSize is the size (in lines) of the log buffer. BufferSize int `json:"bufferSize"` - // Source is the source name of the kernel monitor + // Source is the source name of the log monitor Source string `json:"source"` - // DefaultConditions are the default states of all the conditions kernel monitor should handle. + // DefaultConditions are the default states of all the conditions log monitor should handle. DefaultConditions []types.Condition `json:"conditions"` - // Rules are the rules kernel monitor will follow to parse the log file. - Rules []kerntypes.Rule `json:"rules"` + // Rules are the rules log monitor will follow to parse the log file. + Rules []logtypes.Rule `json:"rules"` } // applyDefaultConfiguration applies default configurations. diff --git a/pkg/kernelmonitor/log_buffer.go b/pkg/systemlogmonitor/log_buffer.go similarity index 87% rename from pkg/kernelmonitor/log_buffer.go rename to pkg/systemlogmonitor/log_buffer.go index ff12160d..1dc4bc40 100644 --- a/pkg/kernelmonitor/log_buffer.go +++ b/pkg/systemlogmonitor/log_buffer.go @@ -14,28 +14,28 @@ See the License for the specific language governing permissions and limitations under the License. */ -package kernelmonitor +package systemlogmonitor import ( "regexp" "strings" - "k8s.io/node-problem-detector/pkg/kernelmonitor/types" + "k8s.io/node-problem-detector/pkg/systemlogmonitor/types" ) // LogBuffer buffers the logs and supports match in the log buffer with regular expression. type LogBuffer interface { // Push pushes log into the log buffer. - Push(*types.KernelLog) + Push(*types.Log) // Match with regular expression in the log buffer. - Match(string) []*types.KernelLog + Match(string) []*types.Log // String returns a concatenated string of the buffered logs. String() string } type logBuffer struct { // buffer is a simple ring buffer. - buffer []*types.KernelLog + buffer []*types.Log msg []string max int current int @@ -47,20 +47,20 @@ type logBuffer struct { // lines of patterns we support. func NewLogBuffer(maxLines int) *logBuffer { return &logBuffer{ - buffer: make([]*types.KernelLog, maxLines, maxLines), + buffer: make([]*types.Log, maxLines, maxLines), msg: make([]string, maxLines, maxLines), max: maxLines, } } -func (b *logBuffer) Push(log *types.KernelLog) { +func (b *logBuffer) Push(log *types.Log) { b.buffer[b.current%b.max] = log b.msg[b.current%b.max] = log.Message b.current++ } // TODO(random-liu): Cache regexp if garbage collection becomes a problem someday. -func (b *logBuffer) Match(expr string) []*types.KernelLog { +func (b *logBuffer) Match(expr string) []*types.Log { // The expression should be checked outside, and it must match to the end. reg := regexp.MustCompile(expr + `\z`) log := b.String() @@ -72,7 +72,7 @@ func (b *logBuffer) Match(expr string) []*types.KernelLog { // reverse index s := len(log) - loc[0] - 1 total := 0 - matched := []*types.KernelLog{} + matched := []*types.Log{} for i := b.tail(); i >= b.current && b.buffer[i%b.max] != nil; i-- { matched = append(matched, b.buffer[i%b.max]) total += len(b.msg[i%b.max]) + 1 // Add '\n' diff --git a/pkg/kernelmonitor/log_buffer_test.go b/pkg/systemlogmonitor/log_buffer_test.go similarity index 90% rename from pkg/kernelmonitor/log_buffer_test.go rename to pkg/systemlogmonitor/log_buffer_test.go index 20584794..895a655f 100644 --- a/pkg/kernelmonitor/log_buffer_test.go +++ b/pkg/systemlogmonitor/log_buffer_test.go @@ -14,13 +14,13 @@ See the License for the specific language governing permissions and limitations under the License. */ -package kernelmonitor +package systemlogmonitor import ( "reflect" "testing" - "k8s.io/node-problem-detector/pkg/kernelmonitor/types" + "k8s.io/node-problem-detector/pkg/systemlogmonitor/types" ) func TestPush(t *testing.T) { @@ -52,7 +52,7 @@ func TestPush(t *testing.T) { } { b := NewLogBuffer(test.max) for _, log := range test.logs { - b.Push(&types.KernelLog{Message: log}) + b.Push(&types.Log{Message: log}) } got := b.String() if test.expected != got { @@ -94,13 +94,13 @@ func TestMatch(t *testing.T) { } { b := NewLogBuffer(max) for _, log := range test.logs { - b.Push(&types.KernelLog{Message: log}) + b.Push(&types.Log{Message: log}) } for i, expr := range test.exprs { - kLogs := b.Match(expr) + logs := b.Match(expr) got := []string{} - for _, kLog := range kLogs { - got = append(got, kLog.Message) + for _, log := range logs { + got = append(got, log.Message) } if !reflect.DeepEqual(test.expected[i], got) { t.Errorf("case %d.%d: expected %v, got %v", c+1, i+1, test.expected[i], got) diff --git a/pkg/kernelmonitor/kernel_monitor.go b/pkg/systemlogmonitor/log_monitor.go similarity index 56% rename from pkg/kernelmonitor/kernel_monitor.go rename to pkg/systemlogmonitor/log_monitor.go index 97513242..188c95d2 100644 --- a/pkg/kernelmonitor/kernel_monitor.go +++ b/pkg/systemlogmonitor/log_monitor.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package kernelmonitor +package systemlogmonitor import ( "encoding/json" @@ -22,116 +22,116 @@ import ( "regexp" "time" - "k8s.io/node-problem-detector/pkg/kernelmonitor/logwatchers" - watchertypes "k8s.io/node-problem-detector/pkg/kernelmonitor/logwatchers/types" - kerntypes "k8s.io/node-problem-detector/pkg/kernelmonitor/types" - "k8s.io/node-problem-detector/pkg/kernelmonitor/util" + "k8s.io/node-problem-detector/pkg/systemlogmonitor/logwatchers" + watchertypes "k8s.io/node-problem-detector/pkg/systemlogmonitor/logwatchers/types" + logtypes "k8s.io/node-problem-detector/pkg/systemlogmonitor/types" + "k8s.io/node-problem-detector/pkg/systemlogmonitor/util" "k8s.io/node-problem-detector/pkg/types" "github.com/golang/glog" ) -// KernelMonitor monitors the kernel log and reports node problem condition and event according to +// LogMonitor monitors the log and reports node problem condition and event according to // the rules. -type KernelMonitor interface { - // Start starts the kernel monitor. +type LogMonitor interface { + // Start starts the log monitor. Start() (<-chan *types.Status, error) - // Stop stops the kernel monitor. + // Stop stops the log monitor. Stop() } -type kernelMonitor struct { +type logMonitor struct { watcher watchertypes.LogWatcher buffer LogBuffer config MonitorConfig conditions []types.Condition - logCh <-chan *kerntypes.KernelLog + logCh <-chan *logtypes.Log output chan *types.Status tomb *util.Tomb } -// NewKernelMonitorOrDie create a new KernelMonitor, panic if error occurs. -func NewKernelMonitorOrDie(configPath string) KernelMonitor { - k := &kernelMonitor{ +// NewLogMonitorOrDie create a new LogMonitor, panic if error occurs. +func NewLogMonitorOrDie(configPath string) LogMonitor { + l := &logMonitor{ tomb: util.NewTomb(), } f, err := ioutil.ReadFile(configPath) if err != nil { glog.Fatalf("Failed to read configuration file %q: %v", configPath, err) } - err = json.Unmarshal(f, &k.config) + err = json.Unmarshal(f, &l.config) if err != nil { glog.Fatalf("Failed to unmarshal configuration file %q: %v", configPath, err) } // Apply default configurations - applyDefaultConfiguration(&k.config) - err = validateRules(k.config.Rules) + applyDefaultConfiguration(&l.config) + err = validateRules(l.config.Rules) if err != nil { - glog.Fatalf("Failed to validate matching rules %#v: %v", k.config.Rules, err) + glog.Fatalf("Failed to validate matching rules %#v: %v", l.config.Rules, err) } - glog.Infof("Finish parsing log file: %+v", k.config) - k.watcher = logwatchers.GetLogWatcherOrDie(k.config.WatcherConfig) - k.buffer = NewLogBuffer(k.config.BufferSize) + glog.Infof("Finish parsing log monitor config file: %+v", l.config) + l.watcher = logwatchers.GetLogWatcherOrDie(l.config.WatcherConfig) + l.buffer = NewLogBuffer(l.config.BufferSize) // A 1000 size channel should be big enough. - k.output = make(chan *types.Status, 1000) - return k + l.output = make(chan *types.Status, 1000) + return l } -func (k *kernelMonitor) Start() (<-chan *types.Status, error) { - glog.Info("Start kernel monitor") +func (l *logMonitor) Start() (<-chan *types.Status, error) { + glog.Info("Start log monitor") var err error - k.logCh, err = k.watcher.Watch() + l.logCh, err = l.watcher.Watch() if err != nil { return nil, err } - go k.monitorLoop() - return k.output, nil + go l.monitorLoop() + return l.output, nil } -func (k *kernelMonitor) Stop() { - glog.Info("Stop kernel monitor") - k.tomb.Stop() +func (l *logMonitor) Stop() { + glog.Info("Stop log monitor") + l.tomb.Stop() } -// monitorLoop is the main loop of kernel monitor. -func (k *kernelMonitor) monitorLoop() { - defer k.tomb.Done() - k.initializeStatus() +// monitorLoop is the main loop of log monitor. +func (l *logMonitor) monitorLoop() { + defer l.tomb.Done() + l.initializeStatus() for { select { - case log := <-k.logCh: - k.parseLog(log) - case <-k.tomb.Stopping(): - k.watcher.Stop() - glog.Infof("Kernel monitor stopped") + case log := <-l.logCh: + l.parseLog(log) + case <-l.tomb.Stopping(): + l.watcher.Stop() + glog.Infof("Log monitor stopped") return } } } // parseLog parses one log line. -func (k *kernelMonitor) parseLog(log *kerntypes.KernelLog) { - // Once there is new log, kernel monitor will push it into the log buffer and try - // to match each rule. If any rule is matched, kernel monitor will report a status. - k.buffer.Push(log) - for _, rule := range k.config.Rules { - matched := k.buffer.Match(rule.Pattern) +func (l *logMonitor) parseLog(log *logtypes.Log) { + // Once there is new log, log monitor will push it into the log buffer and try + // to match each rule. If any rule is matched, log monitor will report a status. + l.buffer.Push(log) + for _, rule := range l.config.Rules { + matched := l.buffer.Match(rule.Pattern) if len(matched) == 0 { continue } - status := k.generateStatus(matched, rule) + status := l.generateStatus(matched, rule) glog.Infof("New status generated: %+v", status) - k.output <- status + l.output <- status } } // generateStatus generates status from the logs. -func (k *kernelMonitor) generateStatus(logs []*kerntypes.KernelLog, rule kerntypes.Rule) *types.Status { +func (l *logMonitor) generateStatus(logs []*logtypes.Log, rule logtypes.Rule) *types.Status { // We use the timestamp of the first log line as the timestamp of the status. timestamp := logs[0].Timestamp message := generateMessage(logs) var events []types.Event - if rule.Type == kerntypes.Temp { + if rule.Type == logtypes.Temp { // For temporary error only generate event events = append(events, types.Event{ Severity: types.Warn, @@ -141,8 +141,8 @@ func (k *kernelMonitor) generateStatus(logs []*kerntypes.KernelLog, rule kerntyp }) } else { // For permanent error changes the condition - for i := range k.conditions { - condition := &k.conditions[i] + for i := range l.conditions { + condition := &l.conditions[i] if condition.Type == rule.Condition { condition.Type = rule.Condition // Update transition timestamp and message when the condition @@ -159,22 +159,22 @@ func (k *kernelMonitor) generateStatus(logs []*kerntypes.KernelLog, rule kerntyp } } return &types.Status{ - Source: k.config.Source, + Source: l.config.Source, // TODO(random-liu): Aggregate events and conditions and then do periodically report. Events: events, - Conditions: k.conditions, + Conditions: l.conditions, } } // initializeStatus initializes the internal condition and also reports it to the node problem detector. -func (k *kernelMonitor) initializeStatus() { +func (l *logMonitor) initializeStatus() { // Initialize the default node conditions - k.conditions = initialConditions(k.config.DefaultConditions) - glog.Infof("Initialize condition generated: %+v", k.conditions) + l.conditions = initialConditions(l.config.DefaultConditions) + glog.Infof("Initialize condition generated: %+v", l.conditions) // Update the initial status - k.output <- &types.Status{ - Source: k.config.Source, - Conditions: k.conditions, + l.output <- &types.Status{ + Source: l.config.Source, + Conditions: l.conditions, } } @@ -190,7 +190,7 @@ func initialConditions(defaults []types.Condition) []types.Condition { } // validateRules verifies whether the regular expressions in the rules are valid. -func validateRules(rules []kerntypes.Rule) error { +func validateRules(rules []logtypes.Rule) error { for _, rule := range rules { _, err := regexp.Compile(rule.Pattern) if err != nil { @@ -200,7 +200,7 @@ func validateRules(rules []kerntypes.Rule) error { return nil } -func generateMessage(logs []*kerntypes.KernelLog) string { +func generateMessage(logs []*logtypes.Log) string { messages := []string{} for _, log := range logs { messages = append(messages, log.Message) diff --git a/pkg/kernelmonitor/kernel_monitor_test.go b/pkg/systemlogmonitor/log_monitor_test.go similarity index 88% rename from pkg/kernelmonitor/kernel_monitor_test.go rename to pkg/systemlogmonitor/log_monitor_test.go index 8d84f297..ec8d3634 100644 --- a/pkg/kernelmonitor/kernel_monitor_test.go +++ b/pkg/systemlogmonitor/log_monitor_test.go @@ -14,14 +14,14 @@ See the License for the specific language governing permissions and limitations under the License. */ -package kernelmonitor +package systemlogmonitor import ( "reflect" "testing" "time" - kerntypes "k8s.io/node-problem-detector/pkg/kernelmonitor/types" + logtypes "k8s.io/node-problem-detector/pkg/systemlogmonitor/types" "k8s.io/node-problem-detector/pkg/types" ) @@ -45,7 +45,7 @@ func TestGenerateStatus(t *testing.T) { Transition: time.Unix(500, 500), }, } - logs := []*kerntypes.KernelLog{ + logs := []*logtypes.Log{ { Timestamp: time.Unix(1000, 1000), Message: "test message 1", @@ -56,13 +56,13 @@ func TestGenerateStatus(t *testing.T) { }, } for c, test := range []struct { - rule kerntypes.Rule + rule logtypes.Rule expected types.Status }{ // Do not need Pattern because we don't do pattern match in this test { - rule: kerntypes.Rule{ - Type: kerntypes.Perm, + rule: logtypes.Rule{ + Type: logtypes.Perm, Condition: testConditionA, Reason: "test reason", }, @@ -82,8 +82,8 @@ func TestGenerateStatus(t *testing.T) { }, // Should not update transition time when status and reason are not changed. { - rule: kerntypes.Rule{ - Type: kerntypes.Perm, + rule: logtypes.Rule{ + Type: logtypes.Perm, Condition: testConditionA, Reason: "initial reason", }, @@ -101,8 +101,8 @@ func TestGenerateStatus(t *testing.T) { }, }, { - rule: kerntypes.Rule{ - Type: kerntypes.Temp, + rule: logtypes.Rule{ + Type: logtypes.Temp, Reason: "test reason", }, expected: types.Status{ @@ -117,7 +117,7 @@ func TestGenerateStatus(t *testing.T) { }, }, } { - k := &kernelMonitor{ + l := &logMonitor{ config: MonitorConfig{ Source: testSource, }, @@ -125,7 +125,7 @@ func TestGenerateStatus(t *testing.T) { // during the test. conditions: append([]types.Condition{}, initConditions...), } - got := k.generateStatus(logs, test.rule) + got := l.generateStatus(logs, test.rule) if !reflect.DeepEqual(&test.expected, got) { t.Errorf("case %d: expected status %+v, got %+v", c+1, test.expected, got) } diff --git a/pkg/kernelmonitor/logwatchers/syslog/log_watcher.go b/pkg/systemlogmonitor/logwatchers/filelog/log_watcher.go similarity index 78% rename from pkg/kernelmonitor/logwatchers/syslog/log_watcher.go rename to pkg/systemlogmonitor/logwatchers/filelog/log_watcher.go index 6b6df7c8..922312a2 100644 --- a/pkg/kernelmonitor/logwatchers/syslog/log_watcher.go +++ b/pkg/systemlogmonitor/logwatchers/filelog/log_watcher.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package syslog +package filelog import ( "bufio" @@ -30,36 +30,36 @@ import ( "github.com/golang/glog" "github.com/google/cadvisor/utils/tail" - "k8s.io/node-problem-detector/pkg/kernelmonitor/logwatchers/types" - kerntypes "k8s.io/node-problem-detector/pkg/kernelmonitor/types" - "k8s.io/node-problem-detector/pkg/kernelmonitor/util" + "k8s.io/node-problem-detector/pkg/systemlogmonitor/logwatchers/types" + logtypes "k8s.io/node-problem-detector/pkg/systemlogmonitor/types" + "k8s.io/node-problem-detector/pkg/systemlogmonitor/util" ) -type syslogWatcher struct { +type filelogWatcher struct { cfg types.WatcherConfig reader *bufio.Reader closer io.Closer translator *translator - logCh chan *kerntypes.KernelLog + logCh chan *logtypes.Log uptime time.Time tomb *util.Tomb clock utilclock.Clock } -// NewSyslogWatcherOrDie creates a new kernel log watcher. The function panics +// NewSyslogWatcherOrDie creates a new log watcher. The function panics // when encounters an error. func NewSyslogWatcherOrDie(cfg types.WatcherConfig) types.LogWatcher { var info syscall.Sysinfo_t if err := syscall.Sysinfo(&info); err != nil { glog.Fatalf("Failed to get system info: %v", err) } - return &syslogWatcher{ + return &filelogWatcher{ cfg: cfg, translator: newTranslatorOrDie(cfg.PluginConfig), uptime: time.Now().Add(time.Duration(-info.Uptime * int64(time.Second))), tomb: util.NewTomb(), // A capacity 1000 buffer should be enough - logCh: make(chan *kerntypes.KernelLog, 1000), + logCh: make(chan *logtypes.Log, 1000), clock: utilclock.NewClock(), } } @@ -67,30 +67,30 @@ func NewSyslogWatcherOrDie(cfg types.WatcherConfig) types.LogWatcher { // Make sure NewSyslogWathcer is types.WatcherCreateFunc. var _ types.WatcherCreateFunc = NewSyslogWatcherOrDie -// Watch starts the syslog watcher. -func (s *syslogWatcher) Watch() (<-chan *kerntypes.KernelLog, error) { +// Watch starts the filelog watcher. +func (s *filelogWatcher) Watch() (<-chan *logtypes.Log, error) { r, err := getLogReader(s.cfg.LogPath) if err != nil { return nil, err } s.reader = bufio.NewReader(r) s.closer = r - glog.Info("Start watching syslog") + glog.Info("Start watching filelog") go s.watchLoop() return s.logCh, nil } -// Stop stops the syslog watcher. -func (s *syslogWatcher) Stop() { +// Stop stops the filelog watcher. +func (s *filelogWatcher) Stop() { s.tomb.Stop() } -// watchPollInterval is the interval syslog log watcher will +// watchPollInterval is the interval filelog log watcher will // poll for pod change after reading to the end. const watchPollInterval = 500 * time.Millisecond -// watchLoop is the main watch loop of syslog watcher. -func (s *syslogWatcher) watchLoop() { +// watchLoop is the main watch loop of filelog watcher. +func (s *filelogWatcher) watchLoop() { defer func() { s.closer.Close() close(s.logCh) @@ -105,14 +105,14 @@ func (s *syslogWatcher) watchLoop() { for { select { case <-s.tomb.Stopping(): - glog.Infof("Stop watching syslog") + glog.Infof("Stop watching filelog") return default: } line, err := s.reader.ReadString('\n') if err != nil && err != io.EOF { - glog.Errorf("Exiting syslog watch with error: %v", err) + glog.Errorf("Exiting filelog watch with error: %v", err) return } buffer.WriteString(line) @@ -135,7 +135,7 @@ func (s *syslogWatcher) watchLoop() { } } -// getLogReader returns log reader for syslog log. Note that getLogReader doesn't look back +// getLogReader returns log reader for filelog log. Note that getLogReader doesn't look back // to the rolled out logs. func getLogReader(path string) (io.ReadCloser, error) { if path == "" { diff --git a/pkg/kernelmonitor/logwatchers/syslog/log_watcher_test.go b/pkg/systemlogmonitor/logwatchers/filelog/log_watcher_test.go similarity index 89% rename from pkg/kernelmonitor/logwatchers/syslog/log_watcher_test.go rename to pkg/systemlogmonitor/logwatchers/filelog/log_watcher_test.go index 5f1f376a..730de818 100644 --- a/pkg/kernelmonitor/logwatchers/syslog/log_watcher_test.go +++ b/pkg/systemlogmonitor/logwatchers/filelog/log_watcher_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package syslog +package filelog import ( "io/ioutil" @@ -22,8 +22,8 @@ import ( "testing" "time" - "k8s.io/node-problem-detector/pkg/kernelmonitor/logwatchers/types" - kerntypes "k8s.io/node-problem-detector/pkg/kernelmonitor/types" + "k8s.io/node-problem-detector/pkg/systemlogmonitor/logwatchers/types" + logtypes "k8s.io/node-problem-detector/pkg/systemlogmonitor/types" "code.cloudfoundry.org/clock/fakeclock" "github.com/stretchr/testify/assert" @@ -45,7 +45,7 @@ func TestWatch(t *testing.T) { fakeClock := fakeclock.NewFakeClock(now) testCases := []struct { log string - logs []kerntypes.KernelLog + logs []logtypes.Log uptime time.Time lookback string }{ @@ -56,7 +56,7 @@ Jan 2 03:04:06 kernel: [1.000000] 2 Jan 2 03:04:07 kernel: [2.000000] 3 `, lookback: "0", - logs: []kerntypes.KernelLog{ + logs: []logtypes.Log{ { Timestamp: now, Message: "1", @@ -78,7 +78,7 @@ Jan 2 03:04:05 kernel: [1.000000] 2 Jan 2 03:04:06 kernel: [2.000000] 3 `, lookback: "0", - logs: []kerntypes.KernelLog{ + logs: []logtypes.Log{ { Timestamp: now, Message: "2", @@ -96,7 +96,7 @@ Jan 2 03:04:04 kernel: [1.000000] 2 Jan 2 03:04:05 kernel: [2.000000] 3 `, lookback: "1s", - logs: []kerntypes.KernelLog{ + logs: []logtypes.Log{ { Timestamp: now.Add(-time.Second), Message: "2", @@ -116,7 +116,7 @@ Jan 2 03:04:05 kernel: [2.000000] 3 `, uptime: time.Date(time.Now().Year(), time.January, 2, 3, 4, 4, 0, time.Local), lookback: "2s", - logs: []kerntypes.KernelLog{ + logs: []logtypes.Log{ { Timestamp: now.Add(-time.Second), Message: "2", @@ -130,7 +130,7 @@ Jan 2 03:04:05 kernel: [2.000000] 3 } for c, test := range testCases { t.Logf("TestCase #%d: %#v", c+1, test) - f, err := ioutil.TempFile("", "kernel_log_watcher_test") + f, err := ioutil.TempFile("", "log_watcher_test") assert.NoError(t, err) defer func() { f.Close() @@ -140,15 +140,15 @@ Jan 2 03:04:05 kernel: [2.000000] 3 assert.NoError(t, err) w := NewSyslogWatcherOrDie(types.WatcherConfig{ - Plugin: "syslog", + Plugin: "filelog", PluginConfig: getTestPluginConfig(), LogPath: f.Name(), Lookback: test.lookback, }) // Set the uptime. - w.(*syslogWatcher).uptime = test.uptime + w.(*filelogWatcher).uptime = test.uptime // Set the fake clock. - w.(*syslogWatcher).clock = fakeClock + w.(*filelogWatcher).clock = fakeClock logCh, err := w.Watch() assert.NoError(t, err) defer w.Stop() diff --git a/pkg/kernelmonitor/logwatchers/syslog/translator.go b/pkg/systemlogmonitor/logwatchers/filelog/translator.go similarity index 94% rename from pkg/kernelmonitor/logwatchers/syslog/translator.go rename to pkg/systemlogmonitor/logwatchers/filelog/translator.go index 3f2ed9c3..a2ced1d7 100644 --- a/pkg/kernelmonitor/logwatchers/syslog/translator.go +++ b/pkg/systemlogmonitor/logwatchers/filelog/translator.go @@ -13,14 +13,14 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -package syslog +package filelog import ( "fmt" "regexp" "time" - kerntypes "k8s.io/node-problem-detector/pkg/kernelmonitor/types" + logtypes "k8s.io/node-problem-detector/pkg/systemlogmonitor/types" "github.com/golang/glog" ) @@ -56,7 +56,7 @@ func newTranslatorOrDie(pluginConfig map[string]string) *translator { } // translate translates the log line into internal type. -func (t *translator) translate(line string) (*kerntypes.KernelLog, error) { +func (t *translator) translate(line string) (*logtypes.Log, error) { // Parse timestamp. matches := t.timestampRegexp.FindStringSubmatch(line) if len(matches) == 0 { @@ -74,7 +74,7 @@ func (t *translator) translate(line string) (*kerntypes.KernelLog, error) { return nil, fmt.Errorf("no message found in line %q with regular expression %v", line, t.messageRegexp) } message := matches[len(matches)-1] - return &kerntypes.KernelLog{ + return &logtypes.Log{ Timestamp: timestamp, Message: message, }, nil @@ -95,7 +95,7 @@ func validatePluginConfig(cfg map[string]string) error { } // formalizeTimestamp formalizes the timestamp. We need this because some log doesn't contain full -// timestamp, e.g. syslog. +// timestamp, e.g. filelog. func formalizeTimestamp(t time.Time) time.Time { if t.Year() == 0 { t = t.AddDate(time.Now().Year(), 0, 0) diff --git a/pkg/kernelmonitor/logwatchers/syslog/translator_test.go b/pkg/systemlogmonitor/logwatchers/filelog/translator_test.go similarity index 92% rename from pkg/kernelmonitor/logwatchers/syslog/translator_test.go rename to pkg/systemlogmonitor/logwatchers/filelog/translator_test.go index 8e128c19..c14d5e13 100644 --- a/pkg/kernelmonitor/logwatchers/syslog/translator_test.go +++ b/pkg/systemlogmonitor/logwatchers/filelog/translator_test.go @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package syslog +package filelog import ( "testing" @@ -23,7 +23,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - kerntypes "k8s.io/node-problem-detector/pkg/kernelmonitor/types" + logtypes "k8s.io/node-problem-detector/pkg/systemlogmonitor/types" ) func TestTranslate(t *testing.T) { @@ -32,7 +32,7 @@ func TestTranslate(t *testing.T) { config map[string]string input string err bool - log *kerntypes.KernelLog + log *logtypes.Log }{ { // missing year and timezone @@ -41,7 +41,7 @@ func TestTranslate(t *testing.T) { // "timestampFormat": "Jan _2 15:04:05", config: getTestPluginConfig(), input: "May 1 12:23:45 hostname kernel: [0.000000] component: log message", - log: &kerntypes.KernelLog{ + log: &logtypes.Log{ Timestamp: time.Date(year, time.May, 1, 12, 23, 45, 0, time.Local), Message: "component: log message", }, @@ -50,7 +50,7 @@ func TestTranslate(t *testing.T) { // no log message config: getTestPluginConfig(), input: "May 21 12:23:45 hostname kernel: [9.999999] ", - log: &kerntypes.KernelLog{ + log: &logtypes.Log{ Timestamp: time.Date(year, time.May, 21, 12, 23, 45, 0, time.Local), Message: "", }, @@ -69,7 +69,7 @@ func TestTranslate(t *testing.T) { "timestampFormat": "2006-01-02T15:04:05.999999999-07:00", }, input: `time="2017-02-01T17:58:34.999999999-08:00" level=error msg="test log line1\n test log line2"`, - log: &kerntypes.KernelLog{ + log: &logtypes.Log{ Timestamp: time.Date(2017, 2, 1, 17, 58, 34, 999999999, time.FixedZone("PST", -8*3600)), Message: `test log line1\n test log line2`, }, diff --git a/pkg/kernelmonitor/logwatchers/journald/log_watcher.go b/pkg/systemlogmonitor/logwatchers/journald/log_watcher.go similarity index 91% rename from pkg/kernelmonitor/logwatchers/journald/log_watcher.go rename to pkg/systemlogmonitor/logwatchers/journald/log_watcher.go index aae33a71..1291c4c0 100644 --- a/pkg/kernelmonitor/logwatchers/journald/log_watcher.go +++ b/pkg/systemlogmonitor/logwatchers/journald/log_watcher.go @@ -26,9 +26,9 @@ import ( "github.com/coreos/go-systemd/sdjournal" "github.com/golang/glog" - "k8s.io/node-problem-detector/pkg/kernelmonitor/logwatchers/types" - kerntypes "k8s.io/node-problem-detector/pkg/kernelmonitor/types" - "k8s.io/node-problem-detector/pkg/kernelmonitor/util" + "k8s.io/node-problem-detector/pkg/systemlogmonitor/logwatchers/types" + logtypes "k8s.io/node-problem-detector/pkg/systemlogmonitor/types" + "k8s.io/node-problem-detector/pkg/systemlogmonitor/util" ) // Compiling go-systemd/sdjournald needs libsystemd-dev or libsystemd-journal-dev, @@ -40,7 +40,7 @@ import ( type journaldWatcher struct { journal *sdjournal.Journal cfg types.WatcherConfig - logCh chan *kerntypes.KernelLog + logCh chan *logtypes.Log tomb *util.Tomb } @@ -50,7 +50,7 @@ func NewJournaldWatcher(cfg types.WatcherConfig) types.LogWatcher { cfg: cfg, tomb: util.NewTomb(), // A capacity 1000 buffer should be enough - logCh: make(chan *kerntypes.KernelLog, 1000), + logCh: make(chan *logtypes.Log, 1000), } } @@ -58,7 +58,7 @@ func NewJournaldWatcher(cfg types.WatcherConfig) types.LogWatcher { var _ types.WatcherCreateFunc = NewJournaldWatcher // Watch starts the journal watcher. -func (j *journaldWatcher) Watch() (<-chan *kerntypes.KernelLog, error) { +func (j *journaldWatcher) Watch() (<-chan *logtypes.Log, error) { journal, err := getJournal(j.cfg) if err != nil { return nil, err @@ -162,10 +162,10 @@ func getJournal(cfg types.WatcherConfig) (*sdjournal.Journal, error) { } // translate translates journal entry into internal type. -func translate(entry *sdjournal.JournalEntry) *kerntypes.KernelLog { +func translate(entry *sdjournal.JournalEntry) *logtypes.Log { timestamp := time.Unix(0, int64(time.Duration(entry.RealtimeTimestamp)*time.Microsecond)) message := strings.TrimSpace(entry.Fields["MESSAGE"]) - return &kerntypes.KernelLog{ + return &logtypes.Log{ Timestamp: timestamp, Message: message, } diff --git a/pkg/kernelmonitor/logwatchers/journald/log_watcher_test.go b/pkg/systemlogmonitor/logwatchers/journald/log_watcher_test.go similarity index 90% rename from pkg/kernelmonitor/logwatchers/journald/log_watcher_test.go rename to pkg/systemlogmonitor/logwatchers/journald/log_watcher_test.go index bb7957cf..356a4262 100644 --- a/pkg/kernelmonitor/logwatchers/journald/log_watcher_test.go +++ b/pkg/systemlogmonitor/logwatchers/journald/log_watcher_test.go @@ -25,13 +25,13 @@ import ( "github.com/coreos/go-systemd/sdjournal" "github.com/stretchr/testify/assert" - kerntypes "k8s.io/node-problem-detector/pkg/kernelmonitor/types" + logtypes "k8s.io/node-problem-detector/pkg/systemlogmonitor/types" ) func TestTranslate(t *testing.T) { testCases := []struct { entry *sdjournal.JournalEntry - log *kerntypes.KernelLog + log *logtypes.Log }{ { // has log message @@ -39,7 +39,7 @@ func TestTranslate(t *testing.T) { Fields: map[string]string{"MESSAGE": "log message"}, RealtimeTimestamp: 123456789, }, - log: &kerntypes.KernelLog{ + log: &logtypes.Log{ Timestamp: time.Unix(0, 123456789*1000), Message: "log message", }, @@ -50,7 +50,7 @@ func TestTranslate(t *testing.T) { Fields: map[string]string{}, RealtimeTimestamp: 987654321, }, - log: &kerntypes.KernelLog{ + log: &logtypes.Log{ Timestamp: time.Unix(0, 987654321*1000), Message: "", }, diff --git a/pkg/kernelmonitor/logwatchers/log_watchers.go b/pkg/systemlogmonitor/logwatchers/log_watchers.go similarity index 95% rename from pkg/kernelmonitor/logwatchers/log_watchers.go rename to pkg/systemlogmonitor/logwatchers/log_watchers.go index fd47baf3..a4b7562d 100644 --- a/pkg/kernelmonitor/logwatchers/log_watchers.go +++ b/pkg/systemlogmonitor/logwatchers/log_watchers.go @@ -17,7 +17,7 @@ limitations under the License. package logwatchers import ( - "k8s.io/node-problem-detector/pkg/kernelmonitor/logwatchers/types" + "k8s.io/node-problem-detector/pkg/systemlogmonitor/logwatchers/types" "github.com/golang/glog" ) diff --git a/pkg/kernelmonitor/logwatchers/register_syslog.go b/pkg/systemlogmonitor/logwatchers/register_filelog.go similarity index 75% rename from pkg/kernelmonitor/logwatchers/register_syslog.go rename to pkg/systemlogmonitor/logwatchers/register_filelog.go index 398b6398..43a23d0c 100644 --- a/pkg/kernelmonitor/logwatchers/register_syslog.go +++ b/pkg/systemlogmonitor/logwatchers/register_filelog.go @@ -17,12 +17,12 @@ limitations under the License. package logwatchers import ( - "k8s.io/node-problem-detector/pkg/kernelmonitor/logwatchers/syslog" + "k8s.io/node-problem-detector/pkg/systemlogmonitor/logwatchers/filelog" ) -const syslogPluginName = "syslog" +const filelogPluginName = "filelog" func init() { - // Register the syslog plugin. - registerLogWatcher(syslogPluginName, syslog.NewSyslogWatcherOrDie) + // Register the filelog plugin. + registerLogWatcher(filelogPluginName, filelog.NewSyslogWatcherOrDie) } diff --git a/pkg/kernelmonitor/logwatchers/register_journald.go b/pkg/systemlogmonitor/logwatchers/register_journald.go similarity index 87% rename from pkg/kernelmonitor/logwatchers/register_journald.go rename to pkg/systemlogmonitor/logwatchers/register_journald.go index 9d37f1c7..0d0862ae 100644 --- a/pkg/kernelmonitor/logwatchers/register_journald.go +++ b/pkg/systemlogmonitor/logwatchers/register_journald.go @@ -19,12 +19,12 @@ limitations under the License. package logwatchers import ( - "k8s.io/node-problem-detector/pkg/kernelmonitor/logwatchers/journald" + "k8s.io/node-problem-detector/pkg/systemlogmonitor/logwatchers/journald" ) const journaldPluginName = "journald" func init() { - // Register the syslog plugin. + // Register the journald plugin. registerLogWatcher(journaldPluginName, journald.NewJournaldWatcher) } diff --git a/pkg/kernelmonitor/logwatchers/types/log_watcher.go b/pkg/systemlogmonitor/logwatchers/types/log_watcher.go similarity index 88% rename from pkg/kernelmonitor/logwatchers/types/log_watcher.go rename to pkg/systemlogmonitor/logwatchers/types/log_watcher.go index c079c018..4dc1d72a 100644 --- a/pkg/kernelmonitor/logwatchers/types/log_watcher.go +++ b/pkg/systemlogmonitor/logwatchers/types/log_watcher.go @@ -17,13 +17,13 @@ limitations under the License. package types import ( - "k8s.io/node-problem-detector/pkg/kernelmonitor/types" + "k8s.io/node-problem-detector/pkg/systemlogmonitor/types" ) // LogWatcher is the interface of a log watcher. type LogWatcher interface { // Watch starts watching logs and returns logs via a channel. - Watch() (<-chan *types.KernelLog, error) + Watch() (<-chan *types.Log, error) // Stop stops the log watcher. Resources open should be closed properly. Stop() } @@ -31,14 +31,14 @@ type LogWatcher interface { // WatcherConfig is the configuration of the log watcher. type WatcherConfig struct { // Plugin is the name of plugin which is currently used. - // Currently supported: syslog, journald. + // Currently supported: filelog, journald. Plugin string `json:"plugin, omitempty"` // PluginConfig is a key/value configuration of a plugin. Valid configurations // are defined in different log watcher plugin. PluginConfig map[string]string `json:"pluginConfig, omitempty"` // LogPath is the path to the log LogPath string `json:"logPath, omitempty"` - // Lookback is the time kernel watcher looks up + // Lookback is the time log watcher looks up Lookback string `json:"lookback, omitempty"` } diff --git a/pkg/kernelmonitor/types/types.go b/pkg/systemlogmonitor/types/types.go similarity index 60% rename from pkg/kernelmonitor/types/types.go rename to pkg/systemlogmonitor/types/types.go index 0793463c..b20a8df2 100644 --- a/pkg/kernelmonitor/types/types.go +++ b/pkg/systemlogmonitor/types/types.go @@ -20,34 +20,34 @@ import ( "time" ) -// KernelLog is the log item returned by translator. It's very easy to extend this +// Log is the log item returned by translator. It's very easy to extend this // to support other log monitoring, such as docker log monitoring. -type KernelLog struct { +type Log struct { Timestamp time.Time Message string } -// Type is the type of the kernel problem. +// Type is the type of the problem. type Type string const ( - // Temp means the kernel problem is temporary, only need to report an event. + // Temp means the problem is temporary, only need to report an event. Temp Type = "temporary" - // Perm means the kernel problem is permanent, need to change the node condition. + // Perm means the problem is permanent, need to change the node condition. Perm Type = "permanent" ) -// Rule describes how kernel monitor should analyze the kernel log. +// Rule describes how log monitor should analyze the log. type Rule struct { - // Type is the type of matched kernel problem. + // Type is the type of matched problem. Type Type `json:"type"` - // Condition is the type of the condition the kernel problem triggered. Notice that - // the Condition field should be set only when the problem is permanent, or else the - // field will be ignored. + // Condition is the type of the condition the problem triggered. Notice that + // the Condition field should be set only when the problem is permanent, or + // else the field will be ignored. Condition string `json:"condition"` - // Reason is the short reason of the kernel problem. + // Reason is the short reason of the problem. Reason string `json:"reason"` - // Pattern is the regular expression to match the kernel problem in kernel log. + // Pattern is the regular expression to match the problem in log. // Notice that the pattern must match to the end of the line. Pattern string `json:"pattern"` } diff --git a/pkg/kernelmonitor/util/tomb.go b/pkg/systemlogmonitor/util/tomb.go similarity index 100% rename from pkg/kernelmonitor/util/tomb.go rename to pkg/systemlogmonitor/util/tomb.go diff --git a/pkg/kernelmonitor/util/tomb_test.go b/pkg/systemlogmonitor/util/tomb_test.go similarity index 100% rename from pkg/kernelmonitor/util/tomb_test.go rename to pkg/systemlogmonitor/util/tomb_test.go