logTo is the "core" logging function. All other logging functions (like Debugf(), WarnfCtx(), etc.) end up here. The function will fan out the log to all of the various outputs for them to decide if they should log it or not.
(ctx context.Context, logLevel LogLevel, logKey LogKey, format string, args ...any)
| 209 | // logTo is the "core" logging function. All other logging functions (like Debugf(), WarnfCtx(), etc.) end up here. |
| 210 | // The function will fan out the log to all of the various outputs for them to decide if they should log it or not. |
| 211 | func logTo(ctx context.Context, logLevel LogLevel, logKey LogKey, format string, args ...any) { |
| 212 | // no-op call to enable golang.org/x/tools/go/analysis/passes/printf checking in go vet |
| 213 | if false { |
| 214 | _ = fmt.Sprintf(format, args...) |
| 215 | } |
| 216 | // Defensive bounds-check for log level. All callers of this function should be within this range. |
| 217 | if logLevel < LevelNone || logLevel >= levelCount { |
| 218 | return |
| 219 | } |
| 220 | |
| 221 | if logLevel == LevelError { |
| 222 | SyncGatewayStats.GlobalStats.ResourceUtilizationStats().ErrorCount.Add(1) |
| 223 | } else if logLevel == LevelWarn { |
| 224 | SyncGatewayStats.GlobalStats.ResourceUtilizationStats().WarnCount.Add(1) |
| 225 | } |
| 226 | |
| 227 | shouldLogConsole := consoleLogger.Load().shouldLog(ctx, logLevel, logKey) |
| 228 | shouldLogError := errorLogger.Load().shouldLog(logLevel) |
| 229 | shouldLogWarn := warnLogger.Load().shouldLog(logLevel) |
| 230 | shouldLogInfo := infoLogger.Load().shouldLog(logLevel) |
| 231 | shouldLogDebug := debugLogger.Load().shouldLog(logLevel) |
| 232 | shouldLogTrace := traceLogger.Load().shouldLog(logLevel) |
| 233 | |
| 234 | // exit before string formatting if no loggers need to log |
| 235 | if !(shouldLogConsole || shouldLogError || shouldLogWarn || shouldLogInfo || shouldLogDebug || shouldLogTrace) { |
| 236 | return |
| 237 | } |
| 238 | |
| 239 | // Prepend timestamp, level, log key. |
| 240 | format = addPrefixes(format, ctx, logLevel, logKey) |
| 241 | |
| 242 | // Error, warn and trace logs also append caller name/line numbers. |
| 243 | if logLevel <= LevelWarn || logLevel == LevelTrace { |
| 244 | stackDepth := 2 |
| 245 | if logKey == KeyWalrus { |
| 246 | stackDepth++ // walrus logs go through another layer of fn call |
| 247 | } |
| 248 | format += " -- " + GetCallersName(stackDepth, true) |
| 249 | } |
| 250 | |
| 251 | // Perform log redaction, if necessary. |
| 252 | args = redact(args) |
| 253 | |
| 254 | // If either global console or db console wants to log, allow it |
| 255 | if shouldLogConsole { |
| 256 | consoleLogger.Load().logf(color(format, logLevel), args...) |
| 257 | } |
| 258 | if shouldLogError { |
| 259 | errorLogger.Load().logf(format, args...) |
| 260 | } |
| 261 | if shouldLogWarn { |
| 262 | warnLogger.Load().logf(format, args...) |
| 263 | } |
| 264 | if shouldLogInfo { |
| 265 | infoLogger.Load().logf(format, args...) |
| 266 | } |
| 267 | if shouldLogDebug { |
| 268 | debugLogger.Load().logf(format, args...) |
no test coverage detected