github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/debug/log/memory/memory.go (about) 1 // Licensed under the Apache License, Version 2.0 (the "License"); 2 // you may not use this file except in compliance with the License. 3 // You may obtain a copy of the License at 4 // 5 // https://www.apache.org/licenses/LICENSE-2.0 6 // 7 // Unless required by applicable law or agreed to in writing, software 8 // distributed under the License is distributed on an "AS IS" BASIS, 9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 // See the License for the specific language governing permissions and 11 // limitations under the License. 12 // 13 // Original source: github.com/micro/go-micro/v3/debug/log/memory/memory.go 14 15 // Package memory provides an in memory log buffer 16 package memory 17 18 import ( 19 "fmt" 20 21 "github.com/tickoalcantara12/micro/v3/service/debug/log" 22 "github.com/tickoalcantara12/micro/v3/util/ring" 23 ) 24 25 // memoryLog is default micro log 26 type memoryLog struct { 27 *ring.Buffer 28 } 29 30 // NewLog returns default Logger with 31 func NewLog(opts ...log.Option) log.Log { 32 // get default options 33 options := log.DefaultOptions() 34 35 // apply requested options 36 for _, o := range opts { 37 o(&options) 38 } 39 40 return &memoryLog{ 41 Buffer: ring.New(options.Size), 42 } 43 } 44 45 // Write writes logs into logger 46 func (l *memoryLog) Write(r log.Record) error { 47 l.Buffer.Put(fmt.Sprint(r.Message)) 48 return nil 49 } 50 51 // Read reads logs and returns them 52 func (l *memoryLog) Read(opts ...log.ReadOption) ([]log.Record, error) { 53 options := log.ReadOptions{} 54 // initialize the read options 55 for _, o := range opts { 56 o(&options) 57 } 58 59 var entries []*ring.Entry 60 // if Since options ha sbeen specified we honor it 61 if !options.Since.IsZero() { 62 entries = l.Buffer.Since(options.Since) 63 } 64 65 // only if we specified valid count constraint 66 // do we end up doing some serious if-else kung-fu 67 // if since constraint has been provided 68 // we return *count* number of logs since the given timestamp; 69 // otherwise we return last count number of logs 70 if options.Count > 0 { 71 switch len(entries) > 0 { 72 case true: 73 // if we request fewer logs than what since constraint gives us 74 if options.Count < len(entries) { 75 entries = entries[0:options.Count] 76 } 77 default: 78 entries = l.Buffer.Get(options.Count) 79 } 80 } 81 82 records := make([]log.Record, 0, len(entries)) 83 for _, entry := range entries { 84 record := log.Record{ 85 Timestamp: entry.Timestamp, 86 Message: entry.Value, 87 } 88 records = append(records, record) 89 } 90 91 return records, nil 92 } 93 94 // Stream returns channel for reading log records 95 // along with a stop channel, close it when done 96 func (l *memoryLog) Stream() (log.Stream, error) { 97 // get stream channel from ring buffer 98 stream, stop := l.Buffer.Stream() 99 // make a buffered channel 100 records := make(chan log.Record, 128) 101 // get last 10 records 102 last10 := l.Buffer.Get(10) 103 104 // stream the log records 105 go func() { 106 // first send last 10 records 107 for _, entry := range last10 { 108 records <- log.Record{ 109 Timestamp: entry.Timestamp, 110 Message: entry.Value, 111 Metadata: make(map[string]string), 112 } 113 } 114 // now stream continuously 115 for entry := range stream { 116 records <- log.Record{ 117 Timestamp: entry.Timestamp, 118 Message: entry.Value, 119 Metadata: make(map[string]string), 120 } 121 } 122 }() 123 124 return &logStream{ 125 stream: records, 126 stop: stop, 127 }, nil 128 }