github.com/micro/go-micro/v2@v2.9.1/debug/log/memory/memory.go (about)

     1  // Package memory provides an in memory log buffer
     2  package memory
     3  
     4  import (
     5  	"fmt"
     6  
     7  	"github.com/micro/go-micro/v2/debug/log"
     8  	"github.com/micro/go-micro/v2/util/ring"
     9  )
    10  
    11  var (
    12  	// DefaultSize of the logger buffer
    13  	DefaultSize = 1024
    14  )
    15  
    16  // memoryLog is default micro log
    17  type memoryLog struct {
    18  	*ring.Buffer
    19  }
    20  
    21  // NewLog returns default Logger with
    22  func NewLog(opts ...log.Option) log.Log {
    23  	// get default options
    24  	options := log.DefaultOptions()
    25  
    26  	// apply requested options
    27  	for _, o := range opts {
    28  		o(&options)
    29  	}
    30  
    31  	return &memoryLog{
    32  		Buffer: ring.New(options.Size),
    33  	}
    34  }
    35  
    36  // Write writes logs into logger
    37  func (l *memoryLog) Write(r log.Record) error {
    38  	l.Buffer.Put(fmt.Sprint(r.Message))
    39  	return nil
    40  }
    41  
    42  // Read reads logs and returns them
    43  func (l *memoryLog) Read(opts ...log.ReadOption) ([]log.Record, error) {
    44  	options := log.ReadOptions{}
    45  	// initialize the read options
    46  	for _, o := range opts {
    47  		o(&options)
    48  	}
    49  
    50  	var entries []*ring.Entry
    51  	// if Since options ha sbeen specified we honor it
    52  	if !options.Since.IsZero() {
    53  		entries = l.Buffer.Since(options.Since)
    54  	}
    55  
    56  	// only if we specified valid count constraint
    57  	// do we end up doing some serious if-else kung-fu
    58  	// if since constraint has been provided
    59  	// we return *count* number of logs since the given timestamp;
    60  	// otherwise we return last count number of logs
    61  	if options.Count > 0 {
    62  		switch len(entries) > 0 {
    63  		case true:
    64  			// if we request fewer logs than what since constraint gives us
    65  			if options.Count < len(entries) {
    66  				entries = entries[0:options.Count]
    67  			}
    68  		default:
    69  			entries = l.Buffer.Get(options.Count)
    70  		}
    71  	}
    72  
    73  	records := make([]log.Record, 0, len(entries))
    74  	for _, entry := range entries {
    75  		record := log.Record{
    76  			Timestamp: entry.Timestamp,
    77  			Message:   entry.Value,
    78  		}
    79  		records = append(records, record)
    80  	}
    81  
    82  	return records, nil
    83  }
    84  
    85  // Stream returns channel for reading log records
    86  // along with a stop channel, close it when done
    87  func (l *memoryLog) Stream() (log.Stream, error) {
    88  	// get stream channel from ring buffer
    89  	stream, stop := l.Buffer.Stream()
    90  	// make a buffered channel
    91  	records := make(chan log.Record, 128)
    92  	// get last 10 records
    93  	last10 := l.Buffer.Get(10)
    94  
    95  	// stream the log records
    96  	go func() {
    97  		// first send last 10 records
    98  		for _, entry := range last10 {
    99  			records <- log.Record{
   100  				Timestamp: entry.Timestamp,
   101  				Message:   entry.Value,
   102  				Metadata:  make(map[string]string),
   103  			}
   104  		}
   105  		// now stream continuously
   106  		for entry := range stream {
   107  			records <- log.Record{
   108  				Timestamp: entry.Timestamp,
   109  				Message:   entry.Value,
   110  				Metadata:  make(map[string]string),
   111  			}
   112  		}
   113  	}()
   114  
   115  	return &logStream{
   116  		stream: records,
   117  		stop:   stop,
   118  	}, nil
   119  }