mirror of
https://github.com/kubernetes/node-problem-detector.git
synced 2026-02-14 18:09:57 +00:00
Change kernel specific name in code base and change syslog to filelog.
This commit is contained 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"]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"plugin": "syslog",
|
||||
"plugin": "filelog",
|
||||
"pluginConfig": {
|
||||
"timestamp": "^time=\"(\\S*)\"",
|
||||
"message": "msg=\"([^\n]*)\"",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"plugin": "syslog",
|
||||
"plugin": "filelog",
|
||||
"pluginConfig": {
|
||||
"timestamp": "^.{15}",
|
||||
"message": "kernel: \\[.*\\] (.*)",
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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{}),
|
||||
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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'
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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 == "" {
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
@@ -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`,
|
||||
},
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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: "",
|
||||
},
|
||||
@@ -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"
|
||||
)
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
Reference in New Issue
Block a user