LCOV - code coverage report
Current view: top level - pebble/internal/base - logger.go (source / functions) Hit Total Coverage
Test: 2024-05-28 08:16Z 542915b2 - tests only.lcov Lines: 30 51 58.8 %
Date: 2024-05-28 08:17:24 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright 2023 The LevelDB-Go and Pebble Authors. All rights reserved. Use
       2             : // of this source code is governed by a BSD-style license that can be found in
       3             : // the LICENSE file.
       4             : 
       5             : package base
       6             : 
       7             : import (
       8             :         "bytes"
       9             :         "context"
      10             :         "fmt"
      11             :         "log"
      12             :         "os"
      13             :         "sync"
      14             : 
      15             :         "github.com/cockroachdb/pebble/internal/invariants"
      16             : )
      17             : 
      18             : // Logger defines an interface for writing log messages.
      19             : type Logger interface {
      20             :         Infof(format string, args ...interface{})
      21             :         Errorf(format string, args ...interface{})
      22             :         Fatalf(format string, args ...interface{})
      23             : }
      24             : type defaultLogger struct{}
      25             : 
      26             : // DefaultLogger logs to the Go stdlib logs.
      27             : var DefaultLogger defaultLogger
      28             : 
      29             : var _ Logger = DefaultLogger
      30             : 
      31             : // Infof implements the Logger.Infof interface.
      32           1 : func (defaultLogger) Infof(format string, args ...interface{}) {
      33           1 :         _ = log.Output(2, fmt.Sprintf(format, args...))
      34           1 : }
      35             : 
      36             : // Errorf implements the Logger.Errorf interface.
      37           0 : func (defaultLogger) Errorf(format string, args ...interface{}) {
      38           0 :         _ = log.Output(2, fmt.Sprintf(format, args...))
      39           0 : }
      40             : 
      41             : // Fatalf implements the Logger.Fatalf interface.
      42           0 : func (defaultLogger) Fatalf(format string, args ...interface{}) {
      43           0 :         _ = log.Output(2, fmt.Sprintf(format, args...))
      44           0 :         os.Exit(1)
      45           0 : }
      46             : 
      47             : // InMemLogger implements Logger using an in-memory buffer (used for testing).
      48             : // The buffer can be read via String() and cleared via Reset().
      49             : type InMemLogger struct {
      50             :         mu struct {
      51             :                 sync.Mutex
      52             :                 buf bytes.Buffer
      53             :         }
      54             : }
      55             : 
      56             : var _ Logger = (*InMemLogger)(nil)
      57             : 
      58             : // Reset clears the internal buffer.
      59           1 : func (b *InMemLogger) Reset() {
      60           1 :         b.mu.Lock()
      61           1 :         defer b.mu.Unlock()
      62           1 :         b.mu.buf.Reset()
      63           1 : }
      64             : 
      65             : // String returns the current internal buffer.
      66           1 : func (b *InMemLogger) String() string {
      67           1 :         b.mu.Lock()
      68           1 :         defer b.mu.Unlock()
      69           1 :         return b.mu.buf.String()
      70           1 : }
      71             : 
      72             : // Infof is part of the Logger interface.
      73           1 : func (b *InMemLogger) Infof(format string, args ...interface{}) {
      74           1 :         s := fmt.Sprintf(format, args...)
      75           1 :         b.mu.Lock()
      76           1 :         defer b.mu.Unlock()
      77           1 :         b.mu.buf.Write([]byte(s))
      78           1 :         if n := len(s); n == 0 || s[n-1] != '\n' {
      79           1 :                 b.mu.buf.Write([]byte("\n"))
      80           1 :         }
      81             : }
      82             : 
      83             : // Errorf is part of the Logger interface.
      84           0 : func (b *InMemLogger) Errorf(format string, args ...interface{}) {
      85           0 :         b.Infof(format, args...)
      86           0 : }
      87             : 
      88             : // Fatalf is part of the Logger interface.
      89           1 : func (b *InMemLogger) Fatalf(format string, args ...interface{}) {
      90           1 :         b.Infof("FATAL: "+format, args...)
      91           1 : }
      92             : 
      93             : // LoggerAndTracer defines an interface for logging and tracing.
      94             : type LoggerAndTracer interface {
      95             :         Logger
      96             :         // Eventf formats and emits a tracing log, if tracing is enabled in the
      97             :         // current context.
      98             :         Eventf(ctx context.Context, format string, args ...interface{})
      99             :         // IsTracingEnabled returns true if tracing is enabled. It can be used as an
     100             :         // optimization to avoid calling Eventf (which will be a noop when tracing
     101             :         // is not enabled) to avoid the overhead of boxing the args.
     102             :         IsTracingEnabled(ctx context.Context) bool
     103             : }
     104             : 
     105             : // LoggerWithNoopTracer wraps a logger and does no tracing.
     106             : type LoggerWithNoopTracer struct {
     107             :         Logger
     108             : }
     109             : 
     110             : var _ LoggerAndTracer = &LoggerWithNoopTracer{}
     111             : 
     112             : // Eventf implements LoggerAndTracer.
     113           0 : func (*LoggerWithNoopTracer) Eventf(ctx context.Context, format string, args ...interface{}) {
     114           0 :         if invariants.Enabled && ctx == nil {
     115           0 :                 panic("Eventf context is nil")
     116             :         }
     117             : }
     118             : 
     119             : // IsTracingEnabled implements LoggerAndTracer.
     120           1 : func (*LoggerWithNoopTracer) IsTracingEnabled(ctx context.Context) bool {
     121           1 :         if invariants.Enabled && ctx == nil {
     122           0 :                 panic("IsTracingEnabled ctx is nil")
     123             :         }
     124           1 :         return false
     125             : }
     126             : 
     127             : // NoopLoggerAndTracer does no logging and tracing. Remember that struct{} is
     128             : // special cased in Go and does not incur an allocation when it backs the
     129             : // interface LoggerAndTracer.
     130             : type NoopLoggerAndTracer struct{}
     131             : 
     132             : var _ LoggerAndTracer = NoopLoggerAndTracer{}
     133             : 
     134             : // Infof implements LoggerAndTracer.
     135           0 : func (l NoopLoggerAndTracer) Infof(format string, args ...interface{}) {}
     136             : 
     137             : // Errorf implements LoggerAndTracer.
     138           0 : func (l NoopLoggerAndTracer) Errorf(format string, args ...interface{}) {}
     139             : 
     140             : // Fatalf implements LoggerAndTracer.
     141           0 : func (l NoopLoggerAndTracer) Fatalf(format string, args ...interface{}) {}
     142             : 
     143             : // Eventf implements LoggerAndTracer.
     144           0 : func (l NoopLoggerAndTracer) Eventf(ctx context.Context, format string, args ...interface{}) {
     145           0 :         if invariants.Enabled && ctx == nil {
     146           0 :                 panic("Eventf context is nil")
     147             :         }
     148             : }
     149             : 
     150             : // IsTracingEnabled implements LoggerAndTracer.
     151           1 : func (l NoopLoggerAndTracer) IsTracingEnabled(ctx context.Context) bool {
     152           1 :         if invariants.Enabled && ctx == nil {
     153           0 :                 panic("IsTracingEnabled ctx is nil")
     154             :         }
     155           1 :         return false
     156             : }

Generated by: LCOV version 1.14