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 }