summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/mattermost/logr/target.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/mattermost/logr/target.go')
-rw-r--r--vendor/github.com/mattermost/logr/target.go299
1 files changed, 0 insertions, 299 deletions
diff --git a/vendor/github.com/mattermost/logr/target.go b/vendor/github.com/mattermost/logr/target.go
deleted file mode 100644
index f8e7bf75..00000000
--- a/vendor/github.com/mattermost/logr/target.go
+++ /dev/null
@@ -1,299 +0,0 @@
-package logr
-
-import (
- "context"
- "fmt"
- "os"
- "sync"
- "time"
-)
-
-// Target represents a destination for log records such as file,
-// database, TCP socket, etc.
-type Target interface {
- // SetName provides an optional name for the target.
- SetName(name string)
-
- // IsLevelEnabled returns true if this target should emit
- // logs for the specified level. Also determines if
- // a stack trace is required.
- IsLevelEnabled(Level) (enabled bool, stacktrace bool)
-
- // Formatter returns the Formatter associated with this Target.
- Formatter() Formatter
-
- // Log outputs the log record to this target's destination.
- Log(rec *LogRec)
-
- // Shutdown makes best effort to flush target queue and
- // frees/closes all resources.
- Shutdown(ctx context.Context) error
-}
-
-// RecordWriter can convert a LogRecord to bytes and output to some data sink.
-type RecordWriter interface {
- Write(rec *LogRec) error
-}
-
-// Basic provides the basic functionality of a Target that can be used
-// to more easily compose your own Targets. To use, just embed Basic
-// in your target type, implement `RecordWriter`, and call `(*Basic).Start`.
-type Basic struct {
- target Target
-
- filter Filter
- formatter Formatter
-
- in chan *LogRec
- done chan struct{}
- w RecordWriter
-
- mux sync.RWMutex
- name string
-
- metrics bool
- queueSizeGauge Gauge
- loggedCounter Counter
- errorCounter Counter
- droppedCounter Counter
- blockedCounter Counter
-
- metricsUpdateFreqMillis int64
-}
-
-// Start initializes this target helper and starts accepting log records for processing.
-func (b *Basic) Start(target Target, rw RecordWriter, filter Filter, formatter Formatter, maxQueued int) {
- if filter == nil {
- filter = &StdFilter{Lvl: Fatal}
- }
- if formatter == nil {
- formatter = &DefaultFormatter{}
- }
-
- b.target = target
- b.filter = filter
- b.formatter = formatter
- b.in = make(chan *LogRec, maxQueued)
- b.done = make(chan struct{}, 1)
- b.w = rw
- go b.start()
-
- if b.hasMetrics() {
- go b.startMetricsUpdater()
- }
-}
-
-func (b *Basic) SetName(name string) {
- b.mux.Lock()
- defer b.mux.Unlock()
- b.name = name
-}
-
-// IsLevelEnabled returns true if this target should emit
-// logs for the specified level. Also determines if
-// a stack trace is required.
-func (b *Basic) IsLevelEnabled(lvl Level) (enabled bool, stacktrace bool) {
- return b.filter.IsEnabled(lvl), b.filter.IsStacktraceEnabled(lvl)
-}
-
-// Formatter returns the Formatter associated with this Target.
-func (b *Basic) Formatter() Formatter {
- return b.formatter
-}
-
-// Shutdown stops processing log records after making best
-// effort to flush queue.
-func (b *Basic) Shutdown(ctx context.Context) error {
- // close the incoming channel and wait for read loop to exit.
- close(b.in)
- select {
- case <-ctx.Done():
- case <-b.done:
- }
-
- // b.in channel should now be drained.
- return nil
-}
-
-// Log outputs the log record to this targets destination.
-func (b *Basic) Log(rec *LogRec) {
- lgr := rec.Logger().Logr()
- select {
- case b.in <- rec:
- default:
- handler := lgr.OnTargetQueueFull
- if handler != nil && handler(b.target, rec, cap(b.in)) {
- b.incDroppedCounter()
- return // drop the record
- }
- b.incBlockedCounter()
-
- select {
- case <-time.After(lgr.enqueueTimeout()):
- lgr.ReportError(fmt.Errorf("target enqueue timeout for log rec [%v]", rec))
- case b.in <- rec: // block until success or timeout
- }
- }
-}
-
-// Metrics enables metrics collection using the provided MetricsCollector.
-func (b *Basic) EnableMetrics(collector MetricsCollector, updateFreqMillis int64) error {
- name := fmt.Sprintf("%v", b)
-
- b.mux.Lock()
- defer b.mux.Unlock()
-
- b.metrics = true
- b.metricsUpdateFreqMillis = updateFreqMillis
-
- var err error
-
- if b.queueSizeGauge, err = collector.QueueSizeGauge(name); err != nil {
- return err
- }
- if b.loggedCounter, err = collector.LoggedCounter(name); err != nil {
- return err
- }
- if b.errorCounter, err = collector.ErrorCounter(name); err != nil {
- return err
- }
- if b.droppedCounter, err = collector.DroppedCounter(name); err != nil {
- return err
- }
- if b.blockedCounter, err = collector.BlockedCounter(name); err != nil {
- return err
- }
- return nil
-}
-
-func (b *Basic) hasMetrics() bool {
- b.mux.RLock()
- defer b.mux.RUnlock()
- return b.metrics
-}
-
-func (b *Basic) setQueueSizeGauge(val float64) {
- b.mux.RLock()
- defer b.mux.RUnlock()
- if b.queueSizeGauge != nil {
- b.queueSizeGauge.Set(val)
- }
-}
-
-func (b *Basic) incLoggedCounter() {
- b.mux.RLock()
- defer b.mux.RUnlock()
- if b.loggedCounter != nil {
- b.loggedCounter.Inc()
- }
-}
-
-func (b *Basic) incErrorCounter() {
- b.mux.RLock()
- defer b.mux.RUnlock()
- if b.errorCounter != nil {
- b.errorCounter.Inc()
- }
-}
-
-func (b *Basic) incDroppedCounter() {
- b.mux.RLock()
- defer b.mux.RUnlock()
- if b.droppedCounter != nil {
- b.droppedCounter.Inc()
- }
-}
-
-func (b *Basic) incBlockedCounter() {
- b.mux.RLock()
- defer b.mux.RUnlock()
- if b.blockedCounter != nil {
- b.blockedCounter.Inc()
- }
-}
-
-// String returns a name for this target. Use `SetName` to specify a name.
-func (b *Basic) String() string {
- b.mux.RLock()
- defer b.mux.RUnlock()
-
- if b.name != "" {
- return b.name
- }
- return fmt.Sprintf("%T", b.target)
-}
-
-// Start accepts log records via In channel and writes to the
-// supplied writer, until Done channel signaled.
-func (b *Basic) start() {
- defer func() {
- if r := recover(); r != nil {
- fmt.Fprintln(os.Stderr, "Basic.start -- ", r)
- go b.start()
- }
- }()
-
- for rec := range b.in {
- if rec.flush != nil {
- b.flush(rec.flush)
- } else {
- err := b.w.Write(rec)
- if err != nil {
- b.incErrorCounter()
- rec.Logger().Logr().ReportError(err)
- } else {
- b.incLoggedCounter()
- }
- }
- }
- close(b.done)
-}
-
-// startMetricsUpdater updates the metrics for any polled values every `MetricsUpdateFreqSecs` seconds until
-// target is closed.
-func (b *Basic) startMetricsUpdater() {
- for {
- updateFreq := b.getMetricsUpdateFreqMillis()
- if updateFreq == 0 {
- updateFreq = DefMetricsUpdateFreqMillis
- }
- if updateFreq < 250 {
- updateFreq = 250 // don't peg the CPU
- }
-
- select {
- case <-b.done:
- return
- case <-time.After(time.Duration(updateFreq) * time.Millisecond):
- b.setQueueSizeGauge(float64(len(b.in)))
- }
- }
-}
-
-func (b *Basic) getMetricsUpdateFreqMillis() int64 {
- b.mux.RLock()
- defer b.mux.RUnlock()
- return b.metricsUpdateFreqMillis
-}
-
-// flush drains the queue and notifies when done.
-func (b *Basic) flush(done chan<- struct{}) {
- for {
- var rec *LogRec
- var err error
- select {
- case rec = <-b.in:
- // ignore any redundant flush records.
- if rec.flush == nil {
- err = b.w.Write(rec)
- if err != nil {
- b.incErrorCounter()
- rec.Logger().Logr().ReportError(err)
- }
- }
- default:
- done <- struct{}{}
- return
- }
- }
-}