github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/service/log_queue.go (about) 1 // Copyright 2015 Keybase, Inc. All rights reserved. Use of 2 // this source code is governed by the included BSD license. 3 4 package service 5 6 import ( 7 "fmt" 8 "os" 9 10 keybase1 "github.com/keybase/client/go/protocol/keybase1" 11 ) 12 13 type logQueue struct { 14 name string 15 level keybase1.LogLevel 16 ui *LogUI 17 handleID int 18 buffer chan *logEntry 19 drop chan bool 20 } 21 22 func newLogQueue(name string, level keybase1.LogLevel, ui *LogUI) *logQueue { 23 q := &logQueue{ 24 name: name, 25 level: level, 26 ui: ui, 27 buffer: make(chan *logEntry, 10000), 28 drop: make(chan bool, 1), 29 } 30 31 go q.processQueue() 32 33 return q 34 } 35 36 func (q *logQueue) String() string { 37 return fmt.Sprintf("%s: level %d, handle id %d", q.name, q.level, q.handleID) 38 } 39 40 func (q *logQueue) SetHandleID(id int) { 41 q.handleID = id 42 } 43 44 func (q *logQueue) HandleID() int { 45 return q.handleID 46 } 47 48 func (q *logQueue) Log(e *logEntry) { 49 if e.level < q.level { 50 return 51 } 52 select { 53 case q.buffer <- e: 54 q.checkDropFlag() 55 default: 56 q.setDropFlag() 57 } 58 } 59 60 func (q *logQueue) Shutdown() { 61 close(q.buffer) 62 q.buffer = nil 63 } 64 65 func (q *logQueue) processQueue() { 66 for e := range q.buffer { 67 if e.level < q.level { 68 continue 69 } 70 q.ui.Log(e.level, e.format, e.args) 71 } 72 } 73 74 // setDropFlag puts a flag into the drop channel if the channel is 75 // empty. This is to signal that external log messages have been 76 // dropped. 77 func (q *logQueue) setDropFlag() { 78 select { 79 case q.drop <- true: 80 // do this outside the logging mechanism to make sure it gets through 81 fmt.Fprintf(os.Stderr, "WARNING: dropping log messages destined for %q due to full log buffer\n", q.name) 82 default: 83 } 84 } 85 86 // checkDropFlag checks to see if anything is in the drop channel. 87 // If there is a flag in there, it will warn client that log 88 // messages were dropped. 89 func (q *logQueue) checkDropFlag() { 90 select { 91 case <-q.drop: 92 q.buffer <- &logEntry{ 93 level: keybase1.LogLevel_WARN, 94 format: "Service log messages were dropped due to full buffer", 95 } 96 default: 97 } 98 }