github.com/volts-dev/volts@v0.0.0-20240120094013-5e9c65924106/logger/writer.go (about) 1 package logger 2 3 import ( 4 "bytes" 5 "fmt" 6 "os" 7 "path" 8 "runtime" 9 "sync" 10 ) 11 12 type ( 13 IWriter interface { 14 Init(config string) error 15 Destroy() 16 //Flush() 17 Write(level Level, msg string) error 18 } 19 20 // 创建新Writer类型函数接口 21 IWriterType func() IWriter 22 23 TWriterMsg struct { 24 level Level 25 msg string 26 } 27 28 // Manager all object and API function 29 TWriterManager struct { 30 config *Config 31 //prefix string // prefix to write at beginning of each line 32 flag int // properties 33 //level int 34 writer map[string]IWriter // destination for output 35 level_writer map[Level]IWriter // destination for output 36 writerName string // 现在使用的Writer 37 buf bytes.Buffer // for accumulating text to write 38 levelStats [6]int64 39 40 enableFuncCallDepth bool //report detail of the path,row 41 loggerFuncCallDepth int // 1:function 2:path 42 43 // 异步 44 asynchronous bool 45 msg chan *TWriterMsg // 消息通道 46 msgPool *sync.Pool // 缓存池 47 48 lock sync.Mutex // ensures atomic writes; protects the following fields 49 } 50 ) 51 52 func (self *TWriterManager) writeDown(msg string, level Level) { 53 for name, wt := range self.writer { 54 err := wt.Write(level, msg) 55 if err != nil { 56 fmt.Fprintf(os.Stderr, "unable to Write message to adapter:%v,error:%v\n", name, err) 57 } 58 } 59 } 60 func (self *TWriterManager) write(level Level, msg string) error { 61 if level > self.config.Level { 62 return nil 63 } 64 65 if self.enableFuncCallDepth { 66 _, file, line, ok := runtime.Caller(self.loggerFuncCallDepth) 67 if ok { 68 _, filename := path.Split(file) 69 msg = fmt.Sprintf("[%s:%d] %s", filename, line, msg) 70 } 71 } 72 73 msg = "[" + self.config.PrefixName + "]" + msg 74 75 // 异步执行 76 if self.asynchronous { 77 wm := self.msgPool.Get().(*TWriterMsg) 78 wm.level = level 79 wm.msg = msg 80 self.msg <- wm 81 } else { 82 self.writeDown(msg, level) 83 } 84 85 return nil 86 } 87 88 // start logger chan reading. 89 // when chan is not empty, write logs. 90 func (self *TWriterManager) listen() { 91 for { 92 // 如果不是异步则退出监听 93 if !self.asynchronous { 94 return 95 } 96 97 select { 98 case wm := <-self.msg: 99 // using level writer first 100 if wt, has := self.level_writer[wm.level]; has { 101 err := wt.Write(wm.level, wm.msg) 102 if err != nil { 103 fmt.Println("ERROR, unable to WriteMsg:", err) 104 } 105 } else { 106 for _, wt := range self.writer { 107 err := wt.Write(wm.level, wm.msg) 108 if err != nil { 109 fmt.Println("ERROR, unable to WriteMsg:", err) 110 } 111 } 112 } 113 114 } 115 } 116 }