Skip to content

Commit

Permalink
Add constructor to avoid lazy init (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
vearutop authored Jan 5, 2024
1 parent 99aa89d commit b419518
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 23 deletions.
60 changes: 43 additions & 17 deletions observer.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,34 @@ type Config struct {
FilterMessage bool
}

// Observer keeps track of messages.
type Observer struct {
Config
// NewObserver creates PreparedObserver.
func NewObserver(cfg Config) *PreparedObserver {
o := PreparedObserver{}
o.initialize(cfg)

return &o
}

// PreparedObserver keeps track of messages.
type PreparedObserver struct {
samplingInterval int64
count uint32
maxCardinality uint32
maxSamples uint32
distResolution int
distRetentionPeriod int64
entries sync.Map
once sync.Once
other *entry
filterMessage bool
}

// Observer keeps track of messages.
// Deprecated: use NewObserver() to avoid lazy init.
type Observer struct {
Config
PreparedObserver

once sync.Once
}

type entry struct {
Expand Down Expand Up @@ -103,28 +118,28 @@ func (en *entry) push(now int64, sample Sample) {
en.samples <- sample
}

func (l *Observer) initialize() {
l.samplingInterval = int64(l.SamplingInterval)
func (l *PreparedObserver) initialize(cfg Config) {
l.samplingInterval = int64(cfg.SamplingInterval)
if l.samplingInterval == 0 {
l.samplingInterval = int64(time.Millisecond) // 1ms sampling interval by default.
}

l.maxCardinality = l.MaxCardinality
l.maxCardinality = cfg.MaxCardinality
if l.maxCardinality == 0 {
l.maxCardinality = 100
}

l.maxSamples = l.MaxSamples
l.maxSamples = cfg.MaxSamples
if l.maxSamples == 0 {
l.maxSamples = 10
}

l.distResolution = l.DistResolution
l.distResolution = cfg.DistResolution
if l.distResolution == 0 {
l.distResolution = 100
}

l.distRetentionPeriod = int64(l.DistRetentionPeriod)
l.distRetentionPeriod = int64(cfg.DistRetentionPeriod)
if l.distRetentionPeriod == 0 {
l.distRetentionPeriod = int64(168 * time.Hour)
}
Expand All @@ -142,12 +157,23 @@ func (l *Observer) initialize() {
}
l.other.distRetentionPeriod = l.distRetentionPeriod
}

if cfg.FilterMessage {
l.filterMessage = true
}
}

// ObserveMessage updates aggregated information about message.
func (l *Observer) ObserveMessage(msg string, data interface{}) {
l.once.Do(l.initialize)
l.once.Do(func() {
l.initialize(l.Config)
})

l.PreparedObserver.ObserveMessage(msg, data)
}

// ObserveMessage updates aggregated information about message.
func (l *PreparedObserver) ObserveMessage(msg string, data interface{}) {
tn := time.Now()
now := tn.UnixNano() / l.samplingInterval
s := Sample{
Expand All @@ -156,7 +182,7 @@ func (l *Observer) ObserveMessage(msg string, data interface{}) {
Time: tn,
}

if l.Config.FilterMessage {
if l.filterMessage {
msg = string(filter.Dynamic([]byte(msg), 200))
}

Expand Down Expand Up @@ -193,7 +219,7 @@ func (l *Observer) ObserveMessage(msg string, data interface{}) {
}
}

func (l *Observer) exportEntry(en *entry, withSamples bool) Entry {
func (l *PreparedObserver) exportEntry(en *entry, withSamples bool) Entry {
if en == nil {
return Entry{}
}
Expand Down Expand Up @@ -256,7 +282,7 @@ type Bucket struct {
}

// GetEntries returns a list of observed event entries without data samples.
func (l *Observer) GetEntries() []Entry {
func (l *PreparedObserver) GetEntries() []Entry {
result := make([]Entry, 0, atomic.LoadUint32(&l.count))

l.entries.Range(func(key, value interface{}) bool {
Expand All @@ -269,7 +295,7 @@ func (l *Observer) GetEntries() []Entry {
}

// GetEntriesWithSamples returns a list of observed event entries with data samples.
func (l *Observer) GetEntriesWithSamples() []Entry {
func (l *PreparedObserver) GetEntriesWithSamples() []Entry {
result := make([]Entry, 0, atomic.LoadUint32(&l.count))

l.entries.Range(func(key, value interface{}) bool {
Expand All @@ -282,7 +308,7 @@ func (l *Observer) GetEntriesWithSamples() []Entry {
}

// Find lookups entry by message.
func (l *Observer) Find(msg string) Entry {
func (l *PreparedObserver) Find(msg string) Entry {
var e Entry

l.entries.Range(func(key, value interface{}) bool {
Expand All @@ -299,7 +325,7 @@ func (l *Observer) Find(msg string) Entry {
}

// Other returns entry for other events.
func (l *Observer) Other(withSamples bool) Entry {
func (l *PreparedObserver) Other(withSamples bool) Entry {
return l.exportEntry(l.other, withSamples)
}

Expand Down
10 changes: 4 additions & 6 deletions observer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

func TestObserver_ObserveMessage(t *testing.T) {
o := logz.Observer{}
o := logz.NewObserver(logz.Config{})

o.ObserveMessage("test", 123)
o.ObserveMessage("test", 456)
Expand Down Expand Up @@ -43,8 +43,7 @@ func TestObserver_ObserveMessage(t *testing.T) {
}

func TestObserver_ObserveMessage_filter(t *testing.T) {
o := logz.Observer{}
o.Config.FilterMessage = true
o := logz.NewObserver(logz.Config{FilterMessage: true})

o.ObserveMessage("test foo123", 123)
o.ObserveMessage("test bar456", 456)
Expand Down Expand Up @@ -76,7 +75,7 @@ func TestObserver_ObserveMessage_filter(t *testing.T) {
}

func BenchmarkObserver_ObserveMessage(b *testing.B) {
o := logz.Observer{}
o := logz.NewObserver(logz.Config{})
wg := sync.WaitGroup{}
concurrency := 50

Expand All @@ -99,8 +98,7 @@ func BenchmarkObserver_ObserveMessage(b *testing.B) {
}

func BenchmarkObserver_ObserveMessage_filter(b *testing.B) {
o := logz.Observer{}
o.Config.FilterMessage = true
o := logz.NewObserver(logz.Config{FilterMessage: true})
wg := sync.WaitGroup{}
concurrency := 50

Expand Down

0 comments on commit b419518

Please sign in to comment.