github.com/prysmaticlabs/prysm@v1.4.4/shared/logutil/stream.go (about) 1 package logutil 2 3 import ( 4 "io" 5 6 lru "github.com/hashicorp/golang-lru" 7 "github.com/prysmaticlabs/prysm/shared/event" 8 "github.com/prysmaticlabs/prysm/shared/rand" 9 ) 10 11 const ( 12 // The number of log entries to keep in memory. 13 logCacheSize = 20 14 ) 15 16 var ( 17 // Compile time interface checks. 18 _ = io.Writer(&StreamServer{}) 19 _ = Streamer(&StreamServer{}) 20 ) 21 22 // Streamer defines a struct which can retrieve and stream process logs. 23 type Streamer interface { 24 GetLastFewLogs() [][]byte 25 LogsFeed() *event.Feed 26 } 27 28 // StreamServer defines a a websocket server which can receive events from 29 // a feed and write them to open websocket connections. 30 type StreamServer struct { 31 feed *event.Feed 32 cache *lru.Cache 33 } 34 35 // NewStreamServer initializes a new stream server capable of 36 // streaming log events. 37 func NewStreamServer() *StreamServer { 38 c, err := lru.New(logCacheSize) 39 if err != nil { 40 panic(err) // This can only occur when the LogCacheSize is negative. 41 } 42 ss := &StreamServer{ 43 feed: new(event.Feed), 44 cache: c, 45 } 46 addLogWriter(ss) 47 return ss 48 } 49 50 // GetLastFewLogs returns the last few entries of logs stored in an LRU cache. 51 func (ss *StreamServer) GetLastFewLogs() [][]byte { 52 messages := make([][]byte, 0) 53 for _, k := range ss.cache.Keys() { 54 d, ok := ss.cache.Get(k) 55 if ok { 56 messages = append(messages, d.([]byte)) 57 } 58 } 59 return messages 60 } 61 62 // LogsFeed returns a feed callers can subscribe to to receive logs via a channel. 63 func (ss *StreamServer) LogsFeed() *event.Feed { 64 return ss.feed 65 } 66 67 // Write a binary message and send over the event feed. 68 func (ss *StreamServer) Write(p []byte) (n int, err error) { 69 ss.feed.Send(p) 70 ss.cache.Add(rand.NewGenerator().Uint64(), p) 71 return len(p), nil 72 }