github.com/go-spring/spring-base@v1.1.3/log/log_entry.go (about) 1 /* 2 * Copyright 2012-2019 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * https://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package log 18 19 import ( 20 "context" 21 "fmt" 22 23 "github.com/go-spring/spring-base/clock" 24 "github.com/go-spring/spring-base/log/internal" 25 "github.com/go-spring/spring-base/util" 26 ) 27 28 type T = func() []interface{} 29 30 func W(fn func() []Field) Field { 31 return Field{Key: "", Val: funcValue(fn)} 32 } 33 34 type funcValue func() []Field 35 36 func (v funcValue) Encode(enc Encoder) error { 37 panic(util.ForbiddenMethod) 38 } 39 40 // publisher will drop a log message when the filter method returns true. 41 type publisher interface { 42 enableLevel(level Level) bool 43 publish(e *Event) 44 } 45 46 // Entry is an Entry implementation that has context and errno. 47 type Entry struct { 48 ctx context.Context 49 pub publisher 50 tag string 51 skip int 52 } 53 54 func (e *Entry) WithSkip(n int) *Entry { 55 e.skip = n 56 return e 57 } 58 59 func (e *Entry) WithTag(tag string) *Entry { 60 e.tag = tag 61 return e 62 } 63 64 func (e *Entry) WithContext(ctx context.Context) *Entry { 65 e.ctx = ctx 66 return e 67 } 68 69 // Trace outputs log with level TraceLevel. 70 func (e *Entry) Trace(args ...interface{}) *Event { 71 return publish(e.pub, TraceLevel, e.skip, e, "", args, nil) 72 } 73 74 // Tracef outputs log with level TraceLevel. 75 func (e *Entry) Tracef(format string, args ...interface{}) *Event { 76 return publish(e.pub, TraceLevel, e.skip, e, format, args, nil) 77 } 78 79 // Tracew outputs log with level TraceLevel. 80 func (e *Entry) Tracew(fields ...Field) *Event { 81 return publish(e.pub, TraceLevel, e.skip, e, "", nil, fields) 82 } 83 84 // Debug outputs log with level DebugLevel. 85 func (e *Entry) Debug(args ...interface{}) *Event { 86 return publish(e.pub, DebugLevel, e.skip, e, "", args, nil) 87 } 88 89 // Debugf outputs log with level DebugLevel. 90 func (e *Entry) Debugf(format string, args ...interface{}) *Event { 91 return publish(e.pub, DebugLevel, e.skip, e, format, args, nil) 92 } 93 94 // Debugw outputs log with level DebugLevel. 95 func (e *Entry) Debugw(fields ...Field) *Event { 96 return publish(e.pub, DebugLevel, e.skip, e, "", nil, fields) 97 } 98 99 // Info outputs log with level InfoLevel. 100 func (e *Entry) Info(args ...interface{}) *Event { 101 return publish(e.pub, InfoLevel, e.skip, e, "", args, nil) 102 } 103 104 // Infof outputs log with level InfoLevel. 105 func (e *Entry) Infof(format string, args ...interface{}) *Event { 106 return publish(e.pub, InfoLevel, e.skip, e, format, args, nil) 107 } 108 109 // Infow outputs log with level InfoLevel. 110 func (e *Entry) Infow(fields ...Field) *Event { 111 return publish(e.pub, InfoLevel, e.skip, e, "", nil, fields) 112 } 113 114 // Warn outputs log with level WarnLevel. 115 func (e *Entry) Warn(args ...interface{}) *Event { 116 return publish(e.pub, WarnLevel, e.skip, e, "", args, nil) 117 } 118 119 // Warnf outputs log with level WarnLevel. 120 func (e *Entry) Warnf(format string, args ...interface{}) *Event { 121 return publish(e.pub, WarnLevel, e.skip, e, format, args, nil) 122 } 123 124 // Warnw outputs log with level WarnLevel. 125 func (e *Entry) Warnw(fields ...Field) *Event { 126 return publish(e.pub, WarnLevel, e.skip, e, "", nil, fields) 127 } 128 129 // Error outputs log with level ErrorLevel. 130 func (e *Entry) Error(args ...interface{}) *Event { 131 return publish(e.pub, ErrorLevel, e.skip, e, "", args, nil) 132 } 133 134 // Errorf outputs log with level ErrorLevel. 135 func (e *Entry) Errorf(format string, args ...interface{}) *Event { 136 return publish(e.pub, ErrorLevel, e.skip, e, format, args, nil) 137 } 138 139 // Errorw outputs log with level ErrorLevel. 140 func (e *Entry) Errorw(fields ...Field) *Event { 141 return publish(e.pub, ErrorLevel, e.skip, e, "", nil, fields) 142 } 143 144 // Panic outputs log with level PanicLevel. 145 func (e *Entry) Panic(args ...interface{}) *Event { 146 return publish(e.pub, PanicLevel, e.skip, e, "", args, nil) 147 } 148 149 // Panicf outputs log with level PanicLevel. 150 func (e *Entry) Panicf(format string, args ...interface{}) *Event { 151 return publish(e.pub, PanicLevel, e.skip, e, format, args, nil) 152 } 153 154 // Panicw outputs log with level PanicLevel. 155 func (e *Entry) Panicw(fields ...Field) *Event { 156 return publish(e.pub, PanicLevel, e.skip, e, "", nil, fields) 157 } 158 159 // Fatal outputs log with level FatalLevel. 160 func (e *Entry) Fatal(args ...interface{}) *Event { 161 return publish(e.pub, FatalLevel, e.skip, e, "", args, nil) 162 } 163 164 // Fatalf outputs log with level FatalLevel. 165 func (e *Entry) Fatalf(format string, args ...interface{}) *Event { 166 return publish(e.pub, FatalLevel, e.skip, e, format, args, nil) 167 } 168 169 // Fatalw outputs log with level FatalLevel. 170 func (e *Entry) Fatalw(fields ...Field) *Event { 171 return publish(e.pub, FatalLevel, e.skip, e, "", nil, fields) 172 } 173 174 func getMessage(format string, args []interface{}) string { 175 if len(args) == 0 { 176 return format 177 } 178 if len(args) == 1 { 179 fn, ok := args[0].(func() []interface{}) 180 if ok { 181 args = fn() 182 } 183 } 184 if format == "" { 185 return fmt.Sprint(args...) 186 } 187 return fmt.Sprintf(format, args...) 188 } 189 190 func publish(p publisher, level Level, skip int, e *Entry, format string, args []interface{}, fields []Field) *Event { 191 if !p.enableLevel(level) { 192 return nil 193 } 194 if len(fields) == 1 { 195 v, ok := fields[0].Val.(funcValue) 196 if ok { 197 fields = v() 198 } 199 } 200 message := getMessage(format, args) 201 file, line, _ := internal.Caller(skip+2, true) 202 event := &Event{ 203 Tag: e.tag, 204 Time: clock.Now(e.ctx), 205 Context: e.ctx, 206 File: file, 207 Line: line, 208 Level: level, 209 Fields: fields, 210 Message: message, 211 } 212 p.publish(event) 213 return event 214 }