2020-07-17 13:22:37 +00:00
|
|
|
package journal
|
|
|
|
|
2020-07-17 17:35:15 +00:00
|
|
|
import (
|
2020-09-14 12:01:03 +00:00
|
|
|
"fmt"
|
|
|
|
"strings"
|
2020-07-17 17:35:15 +00:00
|
|
|
"time"
|
|
|
|
)
|
2020-07-17 13:22:37 +00:00
|
|
|
|
2020-08-11 12:48:32 +00:00
|
|
|
var (
|
|
|
|
// DefaultDisabledEvents lists the journal events disabled by
|
|
|
|
// default, usually because they are considered noisy.
|
|
|
|
DefaultDisabledEvents = DisabledEvents{
|
|
|
|
EventType{System: "mpool", Event: "add"},
|
|
|
|
EventType{System: "mpool", Event: "remove"},
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
2020-07-20 13:45:17 +00:00
|
|
|
// DisabledEvents is the set of event types whose journaling is suppressed.
|
|
|
|
type DisabledEvents []EventType
|
|
|
|
|
2020-09-28 20:13:18 +00:00
|
|
|
// ParseDisabledEvents parses a string of the form: "system1:event1,system1:event2[,...]"
|
2020-09-14 12:01:03 +00:00
|
|
|
// into a DisabledEvents object, returning an error if the string failed to parse.
|
|
|
|
//
|
|
|
|
// It sanitizes strings via strings.TrimSpace.
|
|
|
|
func ParseDisabledEvents(s string) (DisabledEvents, error) {
|
|
|
|
s = strings.TrimSpace(s) // sanitize
|
|
|
|
evts := strings.Split(s, ",")
|
|
|
|
ret := make(DisabledEvents, 0, len(evts))
|
2023-10-16 15:28:58 +00:00
|
|
|
if len(s) == 0 {
|
|
|
|
return ret, nil
|
|
|
|
}
|
2020-09-14 12:01:03 +00:00
|
|
|
for _, evt := range evts {
|
|
|
|
evt = strings.TrimSpace(evt) // sanitize
|
|
|
|
s := strings.Split(evt, ":")
|
|
|
|
if len(s) != 2 {
|
|
|
|
return nil, fmt.Errorf("invalid event type: %s", s)
|
|
|
|
}
|
|
|
|
ret = append(ret, EventType{System: s[0], Event: s[1]})
|
|
|
|
}
|
|
|
|
return ret, nil
|
|
|
|
}
|
|
|
|
|
2020-07-17 13:22:37 +00:00
|
|
|
// EventType represents the signature of an event.
|
|
|
|
type EventType struct {
|
|
|
|
System string
|
|
|
|
Event string
|
2020-07-17 17:35:15 +00:00
|
|
|
|
|
|
|
// enabled stores whether this event type is enabled.
|
|
|
|
enabled bool
|
|
|
|
|
|
|
|
// safe is a sentinel marker that's set to true if this EventType was
|
|
|
|
// constructed correctly (via Journal#RegisterEventType).
|
|
|
|
safe bool
|
|
|
|
}
|
|
|
|
|
2020-08-11 13:28:00 +00:00
|
|
|
func (et EventType) String() string {
|
|
|
|
return et.System + ":" + et.Event
|
|
|
|
}
|
|
|
|
|
2020-07-17 17:35:15 +00:00
|
|
|
// Enabled returns whether this event type is enabled in the journaling
|
|
|
|
// subsystem. Users are advised to check this before actually attempting to
|
|
|
|
// add a journal entry, as it helps bypass object construction for events that
|
|
|
|
// would be discarded anyway.
|
|
|
|
//
|
|
|
|
// All event types are enabled by default, and specific event types can only
|
|
|
|
// be disabled at Journal construction time.
|
|
|
|
func (et EventType) Enabled() bool {
|
2020-08-10 14:02:15 +00:00
|
|
|
return et.safe && et.enabled
|
|
|
|
}
|
|
|
|
|
2021-08-18 12:59:59 +00:00
|
|
|
//go:generate go run github.com/golang/mock/mockgen -destination=mockjournal/journal.go -package=mockjournal . Journal
|
|
|
|
|
2020-07-17 13:22:37 +00:00
|
|
|
// Journal represents an audit trail of system actions.
|
|
|
|
//
|
|
|
|
// Every entry is tagged with a timestamp, a system name, and an event name.
|
|
|
|
// The supplied data can be any type, as long as it is JSON serializable,
|
|
|
|
// including structs, map[string]interface{}, or primitive types.
|
|
|
|
//
|
|
|
|
// For cleanliness and type safety, we recommend to use typed events. See the
|
|
|
|
// *Evt struct types in this package for more info.
|
|
|
|
type Journal interface {
|
2020-08-26 15:09:37 +00:00
|
|
|
EventTypeRegistry
|
2020-07-17 13:22:37 +00:00
|
|
|
|
2020-08-26 15:09:37 +00:00
|
|
|
// RecordEvent records this event to the journal, if and only if the
|
|
|
|
// EventType is enabled. If so, it calls the supplier function to obtain
|
|
|
|
// the payload to record.
|
|
|
|
//
|
|
|
|
// Implementations MUST recover from panics raised by the supplier function.
|
|
|
|
RecordEvent(evtType EventType, supplier func() interface{})
|
2020-07-17 13:22:37 +00:00
|
|
|
|
|
|
|
// Close closes this journal for further writing.
|
|
|
|
Close() error
|
|
|
|
}
|
|
|
|
|
2020-07-21 16:32:01 +00:00
|
|
|
// Event represents a journal entry.
|
2020-07-17 13:22:37 +00:00
|
|
|
//
|
|
|
|
// See godocs on Journal for more information.
|
2020-07-21 16:32:01 +00:00
|
|
|
type Event struct {
|
2020-07-17 13:22:37 +00:00
|
|
|
EventType
|
|
|
|
|
|
|
|
Timestamp time.Time
|
|
|
|
Data interface{}
|
|
|
|
}
|