Skip to content

Commit

Permalink
feature: add custom message for systemlogmonitor rule
Browse files Browse the repository at this point in the history
  • Loading branch information
googs1025 committed Dec 23, 2024
1 parent 93e64ac commit f5433f4
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 5 deletions.
3 changes: 2 additions & 1 deletion pkg/systemlogmonitor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ with new rule definition:
"type": "temporary/permanent",
"condition": "NodeConditionOfPermanentIssue",
"reason": "CamelCaseShortReason",
"pattern": "regexp matching the issue in the log"
"pattern": "regexp matching the issue in the log",
"patternGeneratedMessageSuffix": "Please check the network connectivity and ensure that all required services are running. For more details, see our documentation at https://example.com/docs/troubleshooting."
}
```

Expand Down
2 changes: 1 addition & 1 deletion pkg/systemlogmonitor/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ type MonitorConfig struct {
EnableMetricsReporting *bool `json:"metricsReporting,omitempty"`
}

// ApplyConfiguration applies default configurations.
// ApplyDefaultConfiguration applies default configurations.
func (mc *MonitorConfig) ApplyDefaultConfiguration() {
if mc.BufferSize == 0 {
mc.BufferSize = defaultBufferSize
Expand Down
11 changes: 8 additions & 3 deletions pkg/systemlogmonitor/log_monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package systemlogmonitor

import (
"encoding/json"
"fmt"
"os"
"time"

Expand Down Expand Up @@ -165,7 +166,7 @@ func (l *logMonitor) parseLog(log *systemlogtypes.Log) {
func (l *logMonitor) generateStatus(logs []*systemlogtypes.Log, rule systemlogtypes.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)
message := generateMessage(logs, rule.PatternGeneratedMessageSuffix)
var events []types.Event
var changedConditions []*types.Condition
if rule.Type == types.Temp {
Expand Down Expand Up @@ -250,10 +251,14 @@ func initialConditions(defaults []types.Condition) []types.Condition {
return conditions
}

func generateMessage(logs []*systemlogtypes.Log) string {
func generateMessage(logs []*systemlogtypes.Log, patternGeneratedMessageSuffix string) string {
messages := []string{}
for _, log := range logs {
messages = append(messages, log.Message)
}
return concatLogs(messages)
logMessage := concatLogs(messages)
if patternGeneratedMessageSuffix != "" {
return fmt.Sprintf("%s; %s", logMessage, patternGeneratedMessageSuffix)
}
return logMessage
}
38 changes: 38 additions & 0 deletions pkg/systemlogmonitor/log_monitor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
"k8s.io/node-problem-detector/pkg/problemdaemon"
"k8s.io/node-problem-detector/pkg/problemmetrics"
logtypes "k8s.io/node-problem-detector/pkg/systemlogmonitor/types"
systemlogtypes "k8s.io/node-problem-detector/pkg/systemlogmonitor/types"
"k8s.io/node-problem-detector/pkg/types"
"k8s.io/node-problem-detector/pkg/util"
"k8s.io/node-problem-detector/pkg/util/metrics"
Expand Down Expand Up @@ -699,3 +700,40 @@ func TestInitializeProblemMetricsOrDie(t *testing.T) {
})
}
}

func TestGenerateMessage(t *testing.T) {
tests := []struct {
name string
logs []*systemlogtypes.Log
patternGeneratedMessageSuffix string
want string
}{
{
name: "No rule message",
logs: []*systemlogtypes.Log{
{Message: "First log message"},
{Message: "Second log message"},
},
patternGeneratedMessageSuffix: "",
want: "First log message\nSecond log message",
},
{
name: "With rule message",
logs: []*systemlogtypes.Log{
{Message: "First log message"},
{Message: "Second log message"},
},
patternGeneratedMessageSuffix: "refer www.foo.com/docs for playbook on how to fix the issue",
want: "First log message\nSecond log message; refer www.foo.com/docs for playbook on how to fix the issue",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := generateMessage(tt.logs, tt.patternGeneratedMessageSuffix)
if got != tt.want {
t.Errorf("generateMessage() = %v, want %v", got, tt.want)
}
})
}
}
5 changes: 5 additions & 0 deletions pkg/systemlogmonitor/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,9 @@ type Rule struct {
// 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"`
// PatternGeneratedMessageSuffix is an optional suffix appended to the matched pattern.
// This suffix provides additional context or instructions for resolving the issue.
// It can be used to include environment-specific details, links to documentation,
// or any other information that helps users understand and address the problem.
PatternGeneratedMessageSuffix string `json:"patternGeneratedMessageSuffix,omitempty"`
}

0 comments on commit f5433f4

Please sign in to comment.