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

Generated by: LCOV version 1.14