Skip to content

Commit 803dfd9

Browse files
committed
feat(alertsender,eventlog): Allow events in JSON format
This change allows to configure the eventlog alertsender to emit the alerts in JSON format.
1 parent e9d8099 commit 803dfd9

8 files changed

Lines changed: 73 additions & 16 deletions

File tree

cmd/systray/main_windows.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ import (
2222
"encoding/json"
2323
"errors"
2424
"fmt"
25+
"io"
26+
"net"
27+
"os"
28+
"path/filepath"
29+
"unsafe"
30+
2531
"github.com/Microsoft/go-winio"
2632
"github.com/mitchellh/mapstructure"
2733
"github.com/rabbitstack/fibratus/pkg/alertsender"
@@ -31,11 +37,6 @@ import (
3137
"github.com/rabbitstack/fibratus/pkg/util/signals"
3238
"github.com/sirupsen/logrus"
3339
"golang.org/x/sys/windows"
34-
"io"
35-
"net"
36-
"os"
37-
"path/filepath"
38-
"unsafe"
3940
)
4041

4142
const systrayPipe = `\\.\pipe\fibratus-systray`
@@ -65,6 +66,7 @@ func (m Msg) decode(output any) error {
6566
DecodeHook: mapstructure.ComposeDecodeHookFunc(
6667
mapstructure.StringToTimeDurationHookFunc(),
6768
mapstructure.StringToSliceHookFunc(","),
69+
alertsender.StringToSeverityDecodeHook(),
6870
),
6971
}
7072
decoder, err := mapstructure.NewDecoder(decoderConfig)

configs/fibratus.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ alertsenders:
8686
# in the log message.
8787
verbose: true
8888

89+
# Specifies the eventlog record format for the alert. Can be pretty|json
90+
format: pretty
91+
8992
# =============================== API ==================================================
9093

9194
# Settings that influence the behaviour of the HTTP server that exposes a number of endpoints such as

pkg/alertsender/alert.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,14 @@ package alertsender
2121
import (
2222
"bytes"
2323
"fmt"
24+
"reflect"
25+
"strings"
26+
27+
"github.com/mitchellh/mapstructure"
2428
"github.com/rabbitstack/fibratus/pkg/event"
2529
"github.com/yuin/goldmark"
2630
"github.com/yuin/goldmark/extension"
2731
"github.com/yuin/goldmark/renderer/html"
28-
"strings"
2932
)
3033

3134
// Severity is the type alias for alert's severity level.
@@ -58,6 +61,26 @@ func (s Severity) String() string {
5861
}
5962
}
6063

64+
// StringToSeverityDecodeHook converts severity string to integer.
65+
func StringToSeverityDecodeHook() mapstructure.DecodeHookFuncType {
66+
return func(
67+
from reflect.Type,
68+
to reflect.Type,
69+
data any,
70+
) (any, error) {
71+
72+
if from.Kind() != reflect.String {
73+
return data, nil
74+
}
75+
76+
if to != reflect.TypeOf(Severity(0)) {
77+
return data, nil
78+
}
79+
80+
return ParseSeverityFromString(data.(string)), nil
81+
}
82+
}
83+
6184
// ParseSeverityFromString parses the severity from the string representation.
6285
func ParseSeverityFromString(sever string) Severity {
6386
switch sever {

pkg/alertsender/eventlog/config.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ import (
2525
const (
2626
enabled = "alertsenders.eventlog.enabled"
2727
verbose = "alertsenders.eventlog.verbose"
28+
format = "alertsenders.eventlog.format"
29+
30+
prettyFormat = "pretty"
31+
jsonFormat = "json"
2832
)
2933

3034
// Config defines the configuration for the eventlog sender.
@@ -35,10 +39,14 @@ type Config struct {
3539
// event context, including parameters and the process
3640
// state are included in the log message.
3741
Verbose bool `mapstructure:"verbose"`
42+
// Format specifies the eventlog record format for the alert.
43+
// Can be pretty or json.
44+
Format string `mapstructure:"format"`
3845
}
3946

4047
// AddFlags registers persistent flags.
4148
func AddFlags(flags *pflag.FlagSet) {
4249
flags.Bool(enabled, true, "Indicates if eventlog alert sender is enabled")
4350
flags.Bool(verbose, true, "Enables/disables the verbose mode. In verbose mode, the full event context, including all parameters and the process information are included in the log message")
51+
flags.String(format, "pretty", "Specifies the eventlog record format for the alert. Can be pretty|json")
4452
}

pkg/alertsender/eventlog/eventlog.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@
1919
package eventlog
2020

2121
import (
22+
"encoding/json"
2223
"errors"
2324
"fmt"
25+
"hash/crc32"
26+
"strings"
27+
2428
"github.com/rabbitstack/fibratus/pkg/alertsender"
2529
evlog "github.com/rabbitstack/fibratus/pkg/util/eventlog"
2630
"golang.org/x/sys/windows"
27-
"hash/crc32"
28-
"strings"
2931
)
3032

3133
const minIDChars = 12
@@ -83,7 +85,19 @@ func (s *eventlog) Send(alert alertsender.Alert) error {
8385
code = uint16(h & 0xFFFF)
8486
}
8587

86-
msg := alert.String(s.config.Verbose)
88+
// build the eventlog event
89+
var msg string
90+
switch s.config.Format {
91+
case prettyFormat:
92+
msg = alert.String(s.config.Verbose)
93+
case jsonFormat:
94+
b, err := json.MarshalIndent(alert, "", " ")
95+
if err != nil {
96+
return err
97+
}
98+
msg = string(b)
99+
}
100+
87101
// trim null characters to avoid
88102
// UTF16PtrFromString complaints
89103
msg = strings.ReplaceAll(msg, "\x00", "")

pkg/alertsender/eventlog/eventlog_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
package eventlog
2020

2121
import (
22+
"testing"
23+
"time"
24+
2225
"github.com/rabbitstack/fibratus/pkg/alertsender"
2326
"github.com/rabbitstack/fibratus/pkg/event"
2427
"github.com/rabbitstack/fibratus/pkg/event/params"
@@ -28,12 +31,10 @@ import (
2831
"github.com/rabbitstack/fibratus/pkg/util/va"
2932
"github.com/stretchr/testify/require"
3033
"golang.org/x/sys/windows"
31-
"testing"
32-
"time"
3334
)
3435

3536
func TestEventlogSender(t *testing.T) {
36-
s, err := alertsender.Load(alertsender.Config{Type: alertsender.Eventlog, Sender: Config{Verbose: true, Enabled: true}})
37+
s, err := alertsender.Load(alertsender.Config{Type: alertsender.Eventlog, Sender: Config{Verbose: true, Enabled: true, Format: prettyFormat}})
3738
require.NoError(t, err)
3839
require.NotNil(t, s)
3940

pkg/alertsender/systray/systray_test.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,16 @@ package systray
2020

2121
import (
2222
"encoding/json"
23+
"io"
24+
"net"
25+
"sync"
26+
"testing"
27+
2328
"github.com/Microsoft/go-winio"
2429
"github.com/mitchellh/mapstructure"
2530
"github.com/rabbitstack/fibratus/pkg/alertsender"
2631
"github.com/stretchr/testify/assert"
2732
"github.com/stretchr/testify/require"
28-
"io"
29-
"net"
30-
"sync"
31-
"testing"
3233
)
3334

3435
func handleMessage(t *testing.T, conn net.Conn, wg *sync.WaitGroup, msgs chan Msg) {
@@ -107,6 +108,7 @@ func decodeMsg(output any, data any) error {
107108
DecodeHook: mapstructure.ComposeDecodeHookFunc(
108109
mapstructure.StringToTimeDurationHookFunc(),
109110
mapstructure.StringToSliceHookFunc(","),
111+
alertsender.StringToSeverityDecodeHook(),
110112
),
111113
}
112114
decoder, err := mapstructure.NewDecoder(decoderConfig)

pkg/config/config.schema.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@
155155
},
156156
"verbose": {
157157
"type": "boolean"
158+
},
159+
"format": {
160+
"type": "string",
161+
"enum": ["pretty", "json"]
158162
}
159163
},
160164
"additionalProperties": false

0 commit comments

Comments
 (0)