Make SCUM logs live relay only
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
package companion
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type ConsoleLogStreamClient interface {
|
||||
StreamLogEvents(context.Context, func(LogStreamEvent) error) error
|
||||
}
|
||||
|
||||
type ConsoleLogStore interface {
|
||||
EnsureSchema(context.Context) error
|
||||
StoreConsoleRecords(context.Context, []ConsoleRecord) (int, error)
|
||||
StoreSemanticEventBatch(context.Context, SemanticEventBatch) (int, error)
|
||||
}
|
||||
|
||||
type ConsoleLogCollector struct {
|
||||
Client ConsoleLogStreamClient
|
||||
Store ConsoleLogStore
|
||||
ServerInstanceID string
|
||||
CorrelationSecret string
|
||||
Backoff time.Duration
|
||||
}
|
||||
|
||||
func NewConsoleLogCollector(client ConsoleLogStreamClient, store ConsoleLogStore, serverInstanceID string, correlationSecret string) *ConsoleLogCollector {
|
||||
return &ConsoleLogCollector{Client: client, Store: store, ServerInstanceID: serverInstanceID, CorrelationSecret: correlationSecret, Backoff: 2 * time.Second}
|
||||
}
|
||||
|
||||
func (collector *ConsoleLogCollector) Run(ctx context.Context) error {
|
||||
if collector == nil || collector.Client == nil || collector.Store == nil || strings.TrimSpace(collector.ServerInstanceID) == "" {
|
||||
return fmt.Errorf("console log collector is not configured")
|
||||
}
|
||||
if err := collector.Store.EnsureSchema(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
backoff := collector.Backoff
|
||||
if backoff <= 0 {
|
||||
backoff = 2 * time.Second
|
||||
}
|
||||
for {
|
||||
err := collector.Client.StreamLogEvents(ctx, collector.handleEvent(ctx))
|
||||
if ctx.Err() != nil {
|
||||
return ctx.Err()
|
||||
}
|
||||
if err != nil {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-time.After(backoff):
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (collector *ConsoleLogCollector) handleEvent(ctx context.Context) func(LogStreamEvent) error {
|
||||
return func(event LogStreamEvent) error {
|
||||
record, ok := consoleRecordFromLogEvent(collector.ServerInstanceID, event)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
if _, err := collector.Store.StoreConsoleRecords(ctx, []ConsoleRecord{record}); err != nil {
|
||||
return err
|
||||
}
|
||||
batch := ParseConsoleRecords(collector.ServerInstanceID, []ConsoleRecord{record}, collector.CorrelationSecret)
|
||||
if _, err := collector.Store.StoreSemanticEventBatch(ctx, batch); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func consoleRecordFromLogEvent(serverInstanceID string, event LogStreamEvent) (ConsoleRecord, bool) {
|
||||
if event.ServerInstanceID != serverInstanceID || event.Entry.Seq == 0 || strings.TrimSpace(event.Entry.Line) == "" {
|
||||
return ConsoleRecord{}, false
|
||||
}
|
||||
stream := consoleStreamName(event.StreamKey)
|
||||
if stream == "" {
|
||||
return ConsoleRecord{}, false
|
||||
}
|
||||
occurredAt := event.Entry.Timestamp
|
||||
if occurredAt.IsZero() {
|
||||
occurredAt = time.Now().UTC()
|
||||
}
|
||||
return ConsoleRecord{ServerID: serverInstanceID, Stream: stream, Sequence: event.Entry.Seq, OccurredAt: occurredAt.UTC(), Text: event.Entry.Line}, true
|
||||
}
|
||||
|
||||
func consoleStreamName(streamKey string) string {
|
||||
key := strings.ToLower(strings.TrimSpace(streamKey))
|
||||
if strings.Contains(key, "stderr") || strings.HasSuffix(key, ".err") || strings.HasSuffix(key, "-err") {
|
||||
return "stderr"
|
||||
}
|
||||
if strings.Contains(key, "stdout") || strings.Contains(key, "console") || strings.HasSuffix(key, ".out") || strings.HasSuffix(key, "-out") {
|
||||
return "stdout"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
Reference in New Issue
Block a user