2025-02-27 13:05:20 +01:00
|
|
|
package logger
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2025-02-28 01:28:17 +01:00
|
|
|
"sync"
|
2025-02-27 13:05:20 +01:00
|
|
|
"sync/atomic"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/google/uuid"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
|
|
|
|
"github.com/netbirdio/netbird/client/internal/netflow/store"
|
|
|
|
"github.com/netbirdio/netbird/client/internal/netflow/types"
|
|
|
|
)
|
|
|
|
|
|
|
|
type rcvChan chan *types.EventFields
|
|
|
|
type Logger struct {
|
2025-02-28 01:28:17 +01:00
|
|
|
mux sync.Mutex
|
|
|
|
ctx context.Context
|
|
|
|
cancel context.CancelFunc
|
|
|
|
enabled atomic.Bool
|
|
|
|
rcvChan atomic.Pointer[rcvChan]
|
|
|
|
cancelReceiver context.CancelFunc
|
|
|
|
Store types.Store
|
2025-02-27 13:05:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func New(ctx context.Context) *Logger {
|
|
|
|
ctx, cancel := context.WithCancel(ctx)
|
|
|
|
return &Logger{
|
2025-02-28 01:28:17 +01:00
|
|
|
ctx: ctx,
|
|
|
|
cancel: cancel,
|
|
|
|
Store: store.NewMemoryStore(),
|
2025-02-27 13:05:20 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) StoreEvent(flowEvent types.EventFields) {
|
|
|
|
if !l.enabled.Load() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
c := l.rcvChan.Load()
|
|
|
|
if c == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
select {
|
|
|
|
case *c <- &flowEvent:
|
|
|
|
default:
|
|
|
|
// todo: we should collect or log on this
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Enable() {
|
|
|
|
go l.startReceiver()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) startReceiver() {
|
|
|
|
if l.enabled.Load() {
|
|
|
|
return
|
|
|
|
}
|
2025-03-07 13:56:00 +01:00
|
|
|
|
2025-02-28 01:28:17 +01:00
|
|
|
l.mux.Lock()
|
|
|
|
ctx, cancel := context.WithCancel(l.ctx)
|
|
|
|
l.cancelReceiver = cancel
|
|
|
|
l.mux.Unlock()
|
2025-02-27 13:05:20 +01:00
|
|
|
|
|
|
|
c := make(rcvChan, 100)
|
2025-03-07 13:56:00 +01:00
|
|
|
l.rcvChan.Store(&c)
|
2025-02-27 13:05:20 +01:00
|
|
|
l.enabled.Store(true)
|
|
|
|
|
|
|
|
for {
|
|
|
|
select {
|
2025-02-28 01:28:17 +01:00
|
|
|
case <-ctx.Done():
|
2025-02-27 13:05:20 +01:00
|
|
|
log.Info("flow Memory store receiver stopped")
|
|
|
|
return
|
|
|
|
case eventFields := <-c:
|
|
|
|
id := uuid.NewString()
|
|
|
|
event := types.Event{
|
|
|
|
ID: id,
|
|
|
|
EventFields: *eventFields,
|
|
|
|
Timestamp: time.Now(),
|
|
|
|
}
|
|
|
|
l.Store.StoreEvent(&event)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) Disable() {
|
|
|
|
l.stop()
|
|
|
|
l.Store.Close()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) stop() {
|
|
|
|
if !l.enabled.Load() {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
l.enabled.Store(false)
|
2025-02-28 01:28:17 +01:00
|
|
|
l.mux.Lock()
|
|
|
|
if l.cancelReceiver != nil {
|
|
|
|
l.cancelReceiver()
|
|
|
|
l.cancelReceiver = nil
|
|
|
|
}
|
2025-03-07 13:56:00 +01:00
|
|
|
l.rcvChan.Store(nil)
|
2025-02-28 01:28:17 +01:00
|
|
|
l.mux.Unlock()
|
2025-02-27 13:05:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (l *Logger) GetEvents() []*types.Event {
|
|
|
|
return l.Store.GetEvents()
|
|
|
|
}
|
|
|
|
|
2025-02-28 18:16:18 +01:00
|
|
|
func (l *Logger) DeleteEvents(ids []string) {
|
|
|
|
l.Store.DeleteEvents(ids)
|
|
|
|
}
|
|
|
|
|
2025-02-27 13:05:20 +01:00
|
|
|
func (l *Logger) Close() {
|
|
|
|
l.stop()
|
|
|
|
l.cancel()
|
|
|
|
}
|