1// Copyright 2015 Keybase, Inc. All rights reserved. Use of 2// this source code is governed by the included BSD license. 3 4package service 5 6import keybase1 "github.com/keybase/client/go/protocol/keybase1" 7 8type logEntry struct { 9 level keybase1.LogLevel 10 format string 11 args []interface{} 12} 13 14type extLogger interface { 15 Log(e *logEntry) 16 SetHandleID(id int) 17 HandleID() int 18 Shutdown() 19} 20 21type logFwd struct { 22 addCh chan extLogger 23 removeCh chan extLogger 24 logCh chan *logEntry 25 doneCh chan bool 26 27 loggers map[int]extLogger 28 idSeq int 29} 30 31func newLogFwd() *logFwd { 32 f := &logFwd{ 33 addCh: make(chan extLogger), 34 removeCh: make(chan extLogger), 35 logCh: make(chan *logEntry, 10000), 36 doneCh: make(chan bool), 37 loggers: make(map[int]extLogger), 38 } 39 40 go f.process() 41 42 return f 43} 44 45func (f *logFwd) Add(x extLogger) { 46 f.addCh <- x 47} 48 49func (f *logFwd) Remove(x extLogger) { 50 f.removeCh <- x 51} 52 53func (f *logFwd) Log(level keybase1.LogLevel, format string, args []interface{}) { 54 f.logCh <- &logEntry{level: level, format: format, args: args} 55} 56 57func (f *logFwd) Shutdown() { 58 f.doneCh <- true 59} 60 61func (f *logFwd) process() { 62 for { 63 select { 64 case x := <-f.addCh: 65 f.loggers[f.idSeq] = x 66 x.SetHandleID(f.idSeq) 67 f.idSeq++ 68 case x := <-f.removeCh: 69 delete(f.loggers, x.HandleID()) 70 x.Shutdown() 71 case e := <-f.logCh: 72 for _, x := range f.loggers { 73 x.Log(e) 74 } 75 case <-f.doneCh: 76 for _, x := range f.loggers { 77 x.Shutdown() 78 } 79 return 80 } 81 } 82} 83