blob: 547b7e227a04627b84e32954153f7f94ed7d6eca [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package tracer
import (
"fmt"
"sync"
"sync/atomic"
"time"
"github.com/rs/zerolog"
"github.com/apache/plc4x/plc4go/spi/options"
"github.com/apache/plc4x/plc4go/spi/utils"
)
type TraceEntry struct {
Timestamp time.Time
ConnectionId string
TransactionId string
Operation string
Message string
}
type Provider interface {
EnableTracer()
GetTracer() *Tracer
}
type Tracer interface {
GetConnectionId() string
SetConnectionId(connectionId string)
ResetTraces()
GetTraces() []TraceEntry
AddTrace(operation string, message string)
AddTransactionalStartTrace(operation string, message string) string
AddTransactionalTrace(transactionId string, operation string, message string)
FilterTraces(traces []TraceEntry, connectionIdFilter string, transactionIdFilter string, operationFilter string, messageFilter string) []TraceEntry
}
func NewTracer(connectionId string, _options ...options.WithOption) Tracer {
customLogger := options.ExtractCustomLoggerOrDefaultToGlobal(_options...)
t := tracer{
traceEntries: []TraceEntry{},
log: customLogger,
}
t.connectionId.Store(connectionId)
return &t
}
type tracer struct {
connectionId atomic.Value
traceEntries []TraceEntry
m sync.Mutex
log zerolog.Logger
}
func (t *tracer) GetConnectionId() string {
return t.connectionId.Load().(string)
}
func (t *tracer) SetConnectionId(connectionId string) {
t.connectionId.Store(connectionId)
}
func (t *tracer) ResetTraces() {
t.m.Lock()
defer t.m.Unlock()
t.traceEntries = []TraceEntry{}
}
func (t *tracer) GetTraces() []TraceEntry {
t.m.Lock()
defer t.m.Unlock()
return t.traceEntries
}
func (t *tracer) AddTrace(operation string, message string) {
t.m.Lock()
defer t.m.Unlock()
t.traceEntries = append(t.traceEntries, TraceEntry{
Timestamp: time.Now(),
ConnectionId: t.connectionId.Load().(string),
TransactionId: "",
Operation: operation,
Message: message,
})
}
func (t *tracer) AddTransactionalStartTrace(operation string, message string) string {
t.m.Lock()
defer t.m.Unlock()
transactionId := utils.GenerateId(t.log, 4)
t.traceEntries = append(t.traceEntries, TraceEntry{
Timestamp: time.Now(),
ConnectionId: t.connectionId.Load().(string),
TransactionId: transactionId,
Operation: operation,
Message: message,
})
return transactionId
}
func (t *tracer) AddTransactionalTrace(transactionId string, operation string, message string) {
t.m.Lock()
defer t.m.Unlock()
t.traceEntries = append(t.traceEntries, TraceEntry{
Timestamp: time.Now(),
ConnectionId: t.connectionId.Load().(string),
TransactionId: transactionId,
Operation: operation,
Message: message,
})
}
func (*tracer) FilterTraces(traces []TraceEntry, connectionIdFilter string, transactionIdFilter string, operationFilter string, messageFilter string) []TraceEntry {
var result []TraceEntry
traceFiltering:
for _, trace := range traces {
if connectionIdFilter != "" && trace.ConnectionId != connectionIdFilter {
continue traceFiltering
}
if transactionIdFilter != "" && trace.TransactionId != transactionIdFilter {
continue traceFiltering
}
if operationFilter != "" && trace.Operation != operationFilter {
continue traceFiltering
}
if messageFilter != "" && trace.Message != messageFilter {
continue traceFiltering
}
result = append(result, trace)
}
return result
}
func (t *tracer) String() string {
return fmt.Sprintf("Tracer for %s", t.connectionId.Load())
}