github.com/snowflakedb/gosnowflake@v1.9.0/log.go (about) 1 // Copyright (c) 2017-2022 Snowflake Computing Inc. All rights reserved. 2 3 package gosnowflake 4 5 import ( 6 "context" 7 "fmt" 8 rlog "github.com/sirupsen/logrus" 9 "io" 10 "os" 11 "path" 12 "runtime" 13 "strings" 14 "time" 15 ) 16 17 // SFSessionIDKey is context key of session id 18 const SFSessionIDKey contextKey = "LOG_SESSION_ID" 19 20 // SFSessionUserKey is context key of user id of a session 21 const SFSessionUserKey contextKey = "LOG_USER" 22 23 // LogKeys these keys in context should be included in logging messages when using logger.WithContext 24 var LogKeys = [...]contextKey{SFSessionIDKey, SFSessionUserKey} 25 26 // SFLogger Snowflake logger interface to expose FieldLogger defined in logrus 27 type SFLogger interface { 28 rlog.Ext1FieldLogger 29 SetLogLevel(level string) error 30 GetLogLevel() string 31 WithContext(ctx context.Context) *rlog.Entry 32 SetOutput(output io.Writer) 33 CloseFileOnLoggerReplace(file *os.File) error 34 Replace(newLogger *SFLogger) 35 } 36 37 // SFCallerPrettyfier to provide base file name and function name from calling frame used in SFLogger 38 func SFCallerPrettyfier(frame *runtime.Frame) (string, string) { 39 return path.Base(frame.Function), fmt.Sprintf("%s:%d", path.Base(frame.File), frame.Line) 40 } 41 42 type defaultLogger struct { 43 inner *rlog.Logger 44 enabled bool 45 file *os.File 46 } 47 48 // SetLogLevel set logging level for calling defaultLogger 49 func (log *defaultLogger) SetLogLevel(level string) error { 50 newEnabled := strings.ToUpper(level) != "OFF" 51 log.enabled = newEnabled 52 if newEnabled { 53 actualLevel, err := rlog.ParseLevel(level) 54 if err != nil { 55 return err 56 } 57 log.inner.SetLevel(actualLevel) 58 } 59 return nil 60 } 61 62 // GetLogLevel return current log level 63 func (log *defaultLogger) GetLogLevel() string { 64 if !log.enabled { 65 return "OFF" 66 } 67 return log.inner.GetLevel().String() 68 } 69 70 // CloseFileOnLoggerReplace set a file to be closed when releasing resources occupied by the logger 71 func (log *defaultLogger) CloseFileOnLoggerReplace(file *os.File) error { 72 if log.file != nil && log.file != file { 73 return fmt.Errorf("could not set a file to close on logger reset because there were already set one") 74 } 75 log.file = file 76 return nil 77 } 78 79 // Replace substitute logger by a given one 80 func (log *defaultLogger) Replace(newLogger *SFLogger) { 81 SetLogger(newLogger) 82 closeLogFile(log.file) 83 } 84 85 func closeLogFile(file *os.File) { 86 if file != nil { 87 err := file.Close() 88 if err != nil { 89 logger.Errorf("failed to close log file: %s", err) 90 } 91 } 92 } 93 94 // WithContext return Entry to include fields in context 95 func (log *defaultLogger) WithContext(ctx context.Context) *rlog.Entry { 96 fields := context2Fields(ctx) 97 return log.inner.WithFields(*fields) 98 } 99 100 // CreateDefaultLogger return a new instance of SFLogger with default config 101 func CreateDefaultLogger() SFLogger { 102 var rLogger = rlog.New() 103 var formatter = rlog.TextFormatter{CallerPrettyfier: SFCallerPrettyfier} 104 rLogger.SetReportCaller(true) 105 rLogger.SetFormatter(&formatter) 106 var ret = defaultLogger{inner: rLogger, enabled: true} 107 return &ret //(&ret).(*SFLogger) 108 } 109 110 // WithField allocates a new entry and adds a field to it. 111 // Debug, Print, Info, Warn, Error, Fatal or Panic must be then applied to 112 // this new returned entry. 113 // If you want multiple fields, use `WithFields`. 114 func (log *defaultLogger) WithField(key string, value interface{}) *rlog.Entry { 115 return log.inner.WithField(key, value) 116 117 } 118 119 // Adds a struct of fields to the log entry. All it does is call `WithField` for 120 // each `Field`. 121 func (log *defaultLogger) WithFields(fields rlog.Fields) *rlog.Entry { 122 return log.inner.WithFields(fields) 123 } 124 125 // Add an error as single field to the log entry. All it does is call 126 // `WithError` for the given `error`. 127 func (log *defaultLogger) WithError(err error) *rlog.Entry { 128 return log.inner.WithError(err) 129 } 130 131 // Overrides the time of the log entry. 132 func (log *defaultLogger) WithTime(t time.Time) *rlog.Entry { 133 return log.inner.WithTime(t) 134 } 135 136 func (log *defaultLogger) Logf(level rlog.Level, format string, args ...interface{}) { 137 log.inner.Logf(level, format, args...) 138 } 139 140 func (log *defaultLogger) Tracef(format string, args ...interface{}) { 141 if log.enabled { 142 log.inner.Tracef(format, args...) 143 } 144 } 145 146 func (log *defaultLogger) Debugf(format string, args ...interface{}) { 147 if log.enabled { 148 log.inner.Debugf(format, args...) 149 } 150 } 151 152 func (log *defaultLogger) Infof(format string, args ...interface{}) { 153 if log.enabled { 154 log.inner.Infof(format, args...) 155 } 156 } 157 158 func (log *defaultLogger) Printf(format string, args ...interface{}) { 159 if log.enabled { 160 log.inner.Printf(format, args...) 161 } 162 } 163 164 func (log *defaultLogger) Warnf(format string, args ...interface{}) { 165 if log.enabled { 166 log.inner.Warnf(format, args...) 167 } 168 } 169 170 func (log *defaultLogger) Warningf(format string, args ...interface{}) { 171 if log.enabled { 172 log.inner.Warningf(format, args...) 173 } 174 } 175 176 func (log *defaultLogger) Errorf(format string, args ...interface{}) { 177 if log.enabled { 178 log.inner.Errorf(format, args...) 179 } 180 } 181 182 func (log *defaultLogger) Fatalf(format string, args ...interface{}) { 183 if log.enabled { 184 log.inner.Fatalf(format, args...) 185 } 186 } 187 188 func (log *defaultLogger) Panicf(format string, args ...interface{}) { 189 if log.enabled { 190 log.inner.Panicf(format, args...) 191 } 192 } 193 194 func (log *defaultLogger) Log(level rlog.Level, args ...interface{}) { 195 log.inner.Log(level, args...) 196 } 197 198 func (log *defaultLogger) LogFn(level rlog.Level, fn rlog.LogFunction) { 199 log.inner.LogFn(level, fn) 200 } 201 202 func (log *defaultLogger) Trace(args ...interface{}) { 203 if log.enabled { 204 log.inner.Trace(args...) 205 } 206 } 207 208 func (log *defaultLogger) Debug(args ...interface{}) { 209 if log.enabled { 210 log.inner.Debug(args...) 211 } 212 } 213 214 func (log *defaultLogger) Info(args ...interface{}) { 215 if log.enabled { 216 log.inner.Info(args...) 217 } 218 } 219 220 func (log *defaultLogger) Print(args ...interface{}) { 221 if log.enabled { 222 log.inner.Print(args...) 223 } 224 } 225 226 func (log *defaultLogger) Warn(args ...interface{}) { 227 if log.enabled { 228 log.inner.Warn(args...) 229 } 230 } 231 232 func (log *defaultLogger) Warning(args ...interface{}) { 233 if log.enabled { 234 log.inner.Warning(args...) 235 } 236 } 237 238 func (log *defaultLogger) Error(args ...interface{}) { 239 if log.enabled { 240 log.inner.Error(args...) 241 } 242 } 243 244 func (log *defaultLogger) Fatal(args ...interface{}) { 245 if log.enabled { 246 log.inner.Fatal(args...) 247 } 248 } 249 250 func (log *defaultLogger) Panic(args ...interface{}) { 251 if log.enabled { 252 log.inner.Panic(args...) 253 } 254 } 255 256 func (log *defaultLogger) TraceFn(fn rlog.LogFunction) { 257 if log.enabled { 258 log.inner.TraceFn(fn) 259 } 260 } 261 262 func (log *defaultLogger) DebugFn(fn rlog.LogFunction) { 263 if log.enabled { 264 log.inner.DebugFn(fn) 265 } 266 } 267 268 func (log *defaultLogger) InfoFn(fn rlog.LogFunction) { 269 if log.enabled { 270 log.inner.InfoFn(fn) 271 } 272 } 273 274 func (log *defaultLogger) PrintFn(fn rlog.LogFunction) { 275 if log.enabled { 276 log.inner.PrintFn(fn) 277 } 278 } 279 280 func (log *defaultLogger) WarnFn(fn rlog.LogFunction) { 281 if log.enabled { 282 log.inner.PrintFn(fn) 283 } 284 } 285 286 func (log *defaultLogger) WarningFn(fn rlog.LogFunction) { 287 if log.enabled { 288 log.inner.WarningFn(fn) 289 } 290 } 291 292 func (log *defaultLogger) ErrorFn(fn rlog.LogFunction) { 293 if log.enabled { 294 log.inner.ErrorFn(fn) 295 } 296 } 297 298 func (log *defaultLogger) FatalFn(fn rlog.LogFunction) { 299 if log.enabled { 300 log.inner.FatalFn(fn) 301 } 302 } 303 304 func (log *defaultLogger) PanicFn(fn rlog.LogFunction) { 305 if log.enabled { 306 log.inner.PanicFn(fn) 307 } 308 } 309 310 func (log *defaultLogger) Logln(level rlog.Level, args ...interface{}) { 311 log.inner.Logln(level, args...) 312 } 313 314 func (log *defaultLogger) Traceln(args ...interface{}) { 315 if log.enabled { 316 log.inner.Traceln(args...) 317 } 318 } 319 320 func (log *defaultLogger) Debugln(args ...interface{}) { 321 if log.enabled { 322 log.inner.Debugln(args...) 323 } 324 } 325 326 func (log *defaultLogger) Infoln(args ...interface{}) { 327 if log.enabled { 328 log.inner.Infoln(args...) 329 } 330 } 331 332 func (log *defaultLogger) Println(args ...interface{}) { 333 if log.enabled { 334 log.inner.Println(args...) 335 } 336 } 337 338 func (log *defaultLogger) Warnln(args ...interface{}) { 339 if log.enabled { 340 log.inner.Warnln(args...) 341 } 342 } 343 344 func (log *defaultLogger) Warningln(args ...interface{}) { 345 if log.enabled { 346 log.inner.Warningln(args...) 347 } 348 } 349 350 func (log *defaultLogger) Errorln(args ...interface{}) { 351 if log.enabled { 352 log.inner.Errorln(args...) 353 } 354 } 355 356 func (log *defaultLogger) Fatalln(args ...interface{}) { 357 if log.enabled { 358 log.inner.Fatalln(args...) 359 } 360 } 361 362 func (log *defaultLogger) Panicln(args ...interface{}) { 363 if log.enabled { 364 log.inner.Panicln(args...) 365 } 366 } 367 368 func (log *defaultLogger) Exit(code int) { 369 log.inner.Exit(code) 370 } 371 372 // SetLevel sets the logger level. 373 func (log *defaultLogger) SetLevel(level rlog.Level) { 374 log.inner.SetLevel(level) 375 } 376 377 // GetLevel returns the logger level. 378 func (log *defaultLogger) GetLevel() rlog.Level { 379 return log.inner.GetLevel() 380 } 381 382 // AddHook adds a hook to the logger hooks. 383 func (log *defaultLogger) AddHook(hook rlog.Hook) { 384 log.inner.AddHook(hook) 385 386 } 387 388 // IsLevelEnabled checks if the log level of the logger is greater than the level param 389 func (log *defaultLogger) IsLevelEnabled(level rlog.Level) bool { 390 return log.inner.IsLevelEnabled(level) 391 } 392 393 // SetFormatter sets the logger formatter. 394 func (log *defaultLogger) SetFormatter(formatter rlog.Formatter) { 395 log.inner.SetFormatter(formatter) 396 } 397 398 // SetOutput sets the logger output. 399 func (log *defaultLogger) SetOutput(output io.Writer) { 400 log.inner.SetOutput(output) 401 } 402 403 func (log *defaultLogger) SetReportCaller(reportCaller bool) { 404 log.inner.SetReportCaller(reportCaller) 405 } 406 407 // SetLogger set a new logger of SFLogger interface for gosnowflake 408 func SetLogger(inLogger *SFLogger) { 409 logger = *inLogger //.(*defaultLogger) 410 } 411 412 // GetLogger return logger that is not public 413 func GetLogger() SFLogger { 414 return logger 415 } 416 417 func context2Fields(ctx context.Context) *rlog.Fields { 418 var fields = rlog.Fields{} 419 if ctx == nil { 420 return &fields 421 } 422 423 for i := 0; i < len(LogKeys); i++ { 424 if ctx.Value(LogKeys[i]) != nil { 425 fields[string(LogKeys[i])] = ctx.Value(LogKeys[i]) 426 } 427 } 428 return &fields 429 }