Skip to content

Commit 14ed9a2

Browse files
committed
chore(alertsenders): Expose StringShort methods for process/event and create a common eventlog package
1 parent e7f02ca commit 14ed9a2

File tree

7 files changed

+267
-103
lines changed

7 files changed

+267
-103
lines changed

pkg/alertsender/eventlog/eventlog.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,26 @@
1919
package eventlog
2020

2121
import (
22+
"errors"
2223
"fmt"
2324
"github.com/rabbitstack/fibratus/pkg/alertsender"
25+
"github.com/rabbitstack/fibratus/pkg/kevent/ktypes"
26+
evlog "github.com/rabbitstack/fibratus/pkg/util/eventlog"
2427
"golang.org/x/sys/windows"
2528
"hash/crc32"
2629
"strings"
2730
)
2831

29-
// source represents the event source that generates the alerts
30-
const source = "Fibratus"
32+
const (
33+
// source represents the event source that generates the alerts
34+
source = "Fibratus"
35+
// levels designates the supported eventlog levels
36+
levels = uint32(evlog.Info | evlog.Warn | evlog.Erro)
37+
// msgFile specifies the location of the eventlog message DLL
38+
msgFile = "%ProgramFiles%\\Fibratus\\fibratus.dll"
39+
// keyName represents the registry key under which the eventlog source is registered
40+
keyName = `SYSTEM\CurrentControlSet\Services\EventLog`
41+
)
3142

3243
const minIDChars = 12
3344

@@ -50,6 +61,13 @@ func makeSender(config alertsender.Config) (alertsender.Sender, error) {
5061
return nil, fmt.Errorf("could not convert source name: %v", err)
5162
}
5263

64+
err = evlog.Install(source, msgFile, keyName, false, levels, uint32(len(ktypes.Categories())))
65+
if err != nil {
66+
if !errors.Is(err, evlog.ErrKeyExists{}) {
67+
return nil, err
68+
}
69+
}
70+
5371
h, err := windows.RegisterEventSource(nil, sourceName)
5472
if err != nil {
5573
return nil, fmt.Errorf("could not register event source: %v", err)

pkg/kevent/kevent.go

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,10 @@ func (e *Kevent) String() string {
120120
Name: %s
121121
Category: %s
122122
Description: %s
123-
Host: %s,
124-
Timestamp: %s,
125-
Kparams: %s,
126-
Metadata: %s,
123+
Host: %s
124+
Timestamp: %s
125+
Kparams: %s
126+
Metadata: %s
127127
%s
128128
`,
129129
e.Seq,
@@ -150,9 +150,9 @@ func (e *Kevent) String() string {
150150
Name: %s
151151
Category: %s
152152
Description: %s
153-
Host: %s,
154-
Timestamp: %s,
155-
Kparams: %s,
153+
Host: %s
154+
Timestamp: %s
155+
Kparams: %s
156156
Metadata: %s
157157
`,
158158
e.Seq,
@@ -170,6 +170,55 @@ func (e *Kevent) String() string {
170170
)
171171
}
172172

173+
// StringShort returns event's string representation
174+
// by removing some irrelevant event/process fields.
175+
func (e *Kevent) StringShort() string {
176+
e.mmux.RLock()
177+
defer e.mmux.RUnlock()
178+
if e.PS != nil {
179+
return fmt.Sprintf(`
180+
Seq: %d
181+
Pid: %d
182+
Tid: %d
183+
Name: %s
184+
Category: %s
185+
Host: %s
186+
Timestamp: %s
187+
Parameters: %s
188+
%s
189+
`,
190+
e.Seq,
191+
e.PID,
192+
e.Tid,
193+
e.Name,
194+
e.Category,
195+
e.Host,
196+
e.Timestamp,
197+
e.Kparams,
198+
e.PS.StringShort(),
199+
)
200+
}
201+
return fmt.Sprintf(`
202+
Seq: %d
203+
Pid: %d
204+
Tid: %d
205+
Name: %s
206+
Category: %s
207+
Host: %s
208+
Timestamp: %s
209+
Parameters: %s
210+
`,
211+
e.Seq,
212+
e.PID,
213+
e.Tid,
214+
e.Name,
215+
e.Category,
216+
e.Host,
217+
e.Timestamp,
218+
e.Kparams,
219+
)
220+
}
221+
173222
// Empty return a pristine event instance.
174223
func Empty() *Kevent {
175224
return &Kevent{

pkg/outputs/eventlog/api.go

Lines changed: 4 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,17 @@ package eventlog
2525
import (
2626
"bytes"
2727
"errors"
28-
"fmt"
2928
"github.com/rabbitstack/fibratus/pkg/kevent/ktypes"
29+
"github.com/rabbitstack/fibratus/pkg/util/eventlog"
3030
"syscall"
3131

3232
"golang.org/x/sys/windows"
33-
"golang.org/x/sys/windows/registry"
3433
)
3534

3635
const addKeyName = `SYSTEM\CurrentControlSet\Services\EventLog\Application`
3736

3837
var categoryCount = len(ktypes.Categories())
3938

40-
// ErrKeyExists signals that the registry key already exists
41-
var ErrKeyExists = fmt.Errorf("%s\\%s already exists", addKeyName, source)
42-
4339
// Eventlog provides access to the system log.
4440
type Eventlog struct {
4541
Handle windows.Handle
@@ -74,59 +70,6 @@ func OpenRemote(host, source string) (*Eventlog, error) {
7470
return &Eventlog{Handle: h}, nil
7571
}
7672

77-
// Install modifies PC registry to allow logging with an event source src.
78-
// It adds all required keys and values to the event log registry key.
79-
// Install uses msgFile as the event message file. If useExpandKey is true,
80-
// the event message file is installed as REG_EXPAND_SZ value,
81-
// otherwise as REG_SZ. Use bitwise of log.Error, log.Warning and
82-
// log.Info to specify events supported by the new event source.
83-
func Install(src, msgFile string, useExpandKey bool, eventsSupported uint32) error {
84-
appkey, err := registry.OpenKey(registry.LOCAL_MACHINE, addKeyName, registry.CREATE_SUB_KEY)
85-
if err != nil {
86-
return err
87-
}
88-
defer appkey.Close()
89-
90-
sk, alreadyExist, err := registry.CreateKey(appkey, src, registry.SET_VALUE)
91-
if err != nil {
92-
return err
93-
}
94-
defer sk.Close()
95-
if alreadyExist {
96-
return ErrKeyExists
97-
}
98-
99-
err = sk.SetDWordValue("CustomSource", 1)
100-
if err != nil {
101-
return err
102-
}
103-
if useExpandKey {
104-
err = sk.SetExpandStringValue("EventMessageFile", msgFile)
105-
} else {
106-
err = sk.SetStringValue("EventMessageFile", msgFile)
107-
}
108-
if err != nil {
109-
return err
110-
}
111-
if useExpandKey {
112-
err = sk.SetExpandStringValue("CategoryMessageFile", msgFile)
113-
} else {
114-
err = sk.SetStringValue("CategoryMessageFile", msgFile)
115-
}
116-
if err != nil {
117-
return err
118-
}
119-
err = sk.SetDWordValue("TypesSupported", eventsSupported)
120-
if err != nil {
121-
return err
122-
}
123-
err = sk.SetDWordValue("CategoryCount", uint32(categoryCount))
124-
if err != nil {
125-
return err
126-
}
127-
return nil
128-
}
129-
13073
// Close closes event log.
13174
func (l *Eventlog) Close() error {
13275
return windows.DeregisterEventSource(l.Handle)
@@ -151,15 +94,15 @@ func (l *Eventlog) report(etype uint16, eid uint32, category uint16, msg []byte)
15194

15295
// Info writes an information event msg with event id eid to the end of event log.
15396
func (l *Eventlog) Info(eid uint32, category uint16, msg []byte) error {
154-
return l.report(uint16(Info), eid, category, msg)
97+
return l.report(uint16(eventlog.Info), eid, category, msg)
15598
}
15699

157100
// Warning writes a warning event msg with event id eid to the end of event log.
158101
func (l *Eventlog) Warning(eid uint32, category uint16, msg []byte) error {
159-
return l.report(uint16(Warn), eid, category, msg)
102+
return l.report(uint16(eventlog.Warn), eid, category, msg)
160103
}
161104

162105
// Error writes an error event msg with event id eid to the end of event log.
163106
func (l *Eventlog) Error(eid uint32, category uint16, msg []byte) error {
164-
return l.report(uint16(Erro), eid, category, msg)
107+
return l.report(uint16(eventlog.Erro), eid, category, msg)
165108
}

pkg/outputs/eventlog/config.go

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
package eventlog
2020

2121
import (
22-
"fmt"
2322
"github.com/rabbitstack/fibratus/pkg/kevent"
2423
"text/template"
2524

@@ -33,31 +32,6 @@ const (
3332
tmpl = "output.eventlog.template"
3433
)
3534

36-
// Level is the type definition for the eventlog log level
37-
type Level uint16
38-
39-
const (
40-
// Info represents the info log level
41-
Info Level = 4
42-
// Warn represents the warning info level
43-
Warn Level = 2
44-
// Erro represents the error log level
45-
Erro Level = 1
46-
)
47-
48-
func levelFromString(s string) Level {
49-
switch s {
50-
case "info", "INFO":
51-
return Info
52-
case "warn", "warning", "WARN", "WARNING":
53-
return Warn
54-
case "erro", "error", "ERRO", "ERROR":
55-
return Erro
56-
default:
57-
panic(fmt.Sprintf("unrecognized evtlog level: %s", s))
58-
}
59-
}
60-
6135
// Config contains configuration properties for fine-tuning the eventlog output.
6236
type Config struct {
6337
// Enabled determines whether the eventlog output is enabled.

pkg/outputs/eventlog/eventlog.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ package eventlog
2222

2323
import (
2424
"errors"
25+
"github.com/rabbitstack/fibratus/pkg/util/eventlog"
2526
"text/template"
2627

2728
"github.com/rabbitstack/fibratus/pkg/kevent/ktypes"
@@ -34,7 +35,7 @@ const (
3435
// source under which eventlog events are reported
3536
source = "Fibratus"
3637
// levels designates the supported eventlog levels
37-
levels = uint32(Info | Warn | Erro)
38+
levels = uint32(eventlog.Info | eventlog.Warn | eventlog.Erro)
3839
// msgFile specifies the location of the eventlog message DLL
3940
msgFile = "%ProgramFiles%\\Fibratus\\fibratus.dll"
4041

@@ -63,10 +64,10 @@ func initEventlog(config outputs.Config) (outputs.OutputGroup, error) {
6364
if !ok {
6465
return outputs.Fail(outputs.ErrInvalidConfig(outputs.Eventlog, config.Output))
6566
}
66-
err := Install(source, msgFile, false, levels)
67+
err := eventlog.Install(source, msgFile, addKeyName, false, levels, uint32(categoryCount))
6768
if err != nil {
6869
// ignore error if the key already exists
69-
if !errors.Is(err, ErrKeyExists) {
70+
if !errors.Is(err, eventlog.ErrKeyExists{}) {
7071
return outputs.Fail(err)
7172
}
7273
}
@@ -132,12 +133,12 @@ func (e *evtlog) publish(kevt *kevent.Kevent) error {
132133
}
133134

134135
func (e *evtlog) log(eventID uint32, categoryID uint16, buf []byte) error {
135-
switch levelFromString(e.config.Level) {
136-
case Info:
136+
switch eventlog.LevelFromString(e.config.Level) {
137+
case eventlog.Info:
137138
return e.evtlog.Info(eventID, categoryID, buf)
138-
case Warn:
139+
case eventlog.Warn:
139140
return e.evtlog.Warning(eventID, categoryID, buf)
140-
case Erro:
141+
case eventlog.Erro:
141142
return e.evtlog.Error(eventID, categoryID, buf)
142143
default:
143144
panic("unknown eventlog level")

pkg/ps/types/types_windows.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,72 @@ func (ps *PS) String() string {
201201
)
202202
}
203203

204+
// StringShort returns a string representation of the process' state
205+
// by removing some verbose attributes such as the env variables block.
206+
func (ps *PS) StringShort() string {
207+
parent := ps.Parent
208+
if parent != nil {
209+
return fmt.Sprintf(`
210+
Pid: %d
211+
Ppid: %d
212+
Name: %s
213+
Parent name: %s
214+
Cmdline: %s
215+
Parent cmdline: %s
216+
Exe: %s
217+
Cwd: %s
218+
SID: %s
219+
Username: %s
220+
Domain: %s
221+
Args: %s
222+
Session ID: %d
223+
Ancestors: %s
224+
`,
225+
ps.PID,
226+
ps.Ppid,
227+
ps.Name,
228+
parent.Name,
229+
ps.Cmdline,
230+
parent.Cmdline,
231+
ps.Exe,
232+
ps.Cwd,
233+
ps.SID,
234+
ps.Username,
235+
ps.Domain,
236+
ps.Args,
237+
ps.SessionID,
238+
strings.Join(ps.Ancestors(), " > "),
239+
)
240+
}
241+
return fmt.Sprintf(`
242+
Pid: %d
243+
Ppid: %d
244+
Name: %s
245+
Cmdline: %s
246+
Exe: %s
247+
Cwd: %s
248+
SID: %s
249+
Username: %s
250+
Domain: %s
251+
Args: %s
252+
Session ID: %d
253+
Ancestors: %s
254+
`,
255+
ps.PID,
256+
ps.Ppid,
257+
ps.Name,
258+
ps.Cmdline,
259+
ps.Exe,
260+
ps.Cwd,
261+
ps.SID,
262+
ps.Username,
263+
ps.Domain,
264+
ps.Args,
265+
ps.SessionID,
266+
strings.Join(ps.Ancestors(), " > "),
267+
)
268+
}
269+
204270
// Ancestors returns all ancestors of this process. The string slice contains
205271
// the process image name followed by the process id.
206272
func (ps *PS) Ancestors() []string {

0 commit comments

Comments
 (0)