logging: Add subsystem to log API (#19002)

Create new code paths for multiple subsystems in the code. This will
make maintaing this easier later.

Also introduce bugLogIf() for errors that should not happen in the first
place.
This commit is contained in:
Anis Eleuch
2024-04-04 13:04:40 +01:00
committed by GitHub
parent 2228eb61cb
commit 95bf4a57b6
123 changed files with 972 additions and 786 deletions

View File

@@ -36,7 +36,7 @@ const contextAuditKey = contextKeyType("audit-entry")
// SetAuditEntry sets Audit info in the context.
func SetAuditEntry(ctx context.Context, audit *audit.Entry) context.Context {
if ctx == nil {
LogIf(context.Background(), fmt.Errorf("context is nil"))
LogIf(context.Background(), "audit", fmt.Errorf("context is nil"))
return nil
}
return context.WithValue(ctx, contextAuditKey, audit)
@@ -144,7 +144,7 @@ func AuditLog(ctx context.Context, w http.ResponseWriter, r *http.Request, reqCl
// Send audit logs only to http targets.
for _, t := range auditTgts {
if err := t.Send(ctx, entry); err != nil {
LogOnceIf(ctx, fmt.Errorf("Unable to send an audit event to the target `%v`: %v", t, err), "send-audit-event-failure")
LogOnceIf(ctx, "logging", fmt.Errorf("Unable to send an audit event to the target `%v`: %v", t, err), "send-audit-event-failure")
}
}
}

View File

@@ -299,7 +299,7 @@ func lookupLegacyConfigForSubSys(ctx context.Context, subSys string) Config {
}
url, err := xnet.ParseHTTPURL(endpoint)
if err != nil {
LogOnceIf(ctx, err, "logger-webhook-"+endpoint)
LogOnceIf(ctx, "logging", err, "logger-webhook-"+endpoint)
continue
}
cfg.HTTP[target] = http.Config{
@@ -327,7 +327,7 @@ func lookupLegacyConfigForSubSys(ctx context.Context, subSys string) Config {
}
url, err := xnet.ParseHTTPURL(endpoint)
if err != nil {
LogOnceIf(ctx, err, "audit-webhook-"+endpoint)
LogOnceIf(ctx, "logging", err, "audit-webhook-"+endpoint)
continue
}
cfg.AuditWebhook[target] = http.Config{

View File

@@ -242,27 +242,26 @@ func HashString(input string) string {
// LogAlwaysIf prints a detailed error message during
// the execution of the server.
func LogAlwaysIf(ctx context.Context, err error, errKind ...interface{}) {
func LogAlwaysIf(ctx context.Context, subsystem string, err error, errKind ...interface{}) {
if err == nil {
return
}
logIf(ctx, err, errKind...)
logIf(ctx, subsystem, err, errKind...)
}
// LogIf prints a detailed error message during
// the execution of the server, if it is not an
// ignored error.
func LogIf(ctx context.Context, err error, errKind ...interface{}) {
func LogIf(ctx context.Context, subsystem string, err error, errKind ...interface{}) {
if logIgnoreError(err) {
return
}
logIf(ctx, err, errKind...)
logIf(ctx, subsystem, err, errKind...)
}
// LogIfNot prints a detailed error message during
// the execution of the server, if it is not an ignored error (either internal or given).
func LogIfNot(ctx context.Context, err error, ignored ...error) {
func LogIfNot(ctx context.Context, subsystem string, err error, ignored ...error) {
if logIgnoreError(err) {
return
}
@@ -271,24 +270,24 @@ func LogIfNot(ctx context.Context, err error, ignored ...error) {
return
}
}
logIf(ctx, err)
logIf(ctx, subsystem, err)
}
func errToEntry(ctx context.Context, err error, errKind ...interface{}) log.Entry {
func errToEntry(ctx context.Context, subsystem string, err error, errKind ...interface{}) log.Entry {
var l string
if anonFlag {
l = reflect.TypeOf(err).String()
} else {
l = fmt.Sprintf("%v (%T)", err, err)
}
return buildLogEntry(ctx, l, getTrace(3), errKind...)
return buildLogEntry(ctx, subsystem, l, getTrace(3), errKind...)
}
func logToEntry(ctx context.Context, message string, errKind ...interface{}) log.Entry {
return buildLogEntry(ctx, message, nil, errKind...)
func logToEntry(ctx context.Context, subsystem, message string, errKind ...interface{}) log.Entry {
return buildLogEntry(ctx, subsystem, message, nil, errKind...)
}
func buildLogEntry(ctx context.Context, message string, trace []string, errKind ...interface{}) log.Entry {
func buildLogEntry(ctx context.Context, subsystem, message string, trace []string, errKind ...interface{}) log.Entry {
logKind := madmin.LogKindError
if len(errKind) > 0 {
if ek, ok := errKind[0].(madmin.LogKind); ok {
@@ -307,8 +306,11 @@ func buildLogEntry(ctx context.Context, message string, trace []string, errKind
defer req.RUnlock()
API := "SYSTEM"
if req.API != "" {
switch {
case req.API != "":
API = req.API
case subsystem != "":
API += "." + subsystem
}
// Copy tags. We hold read lock already.
@@ -374,7 +376,7 @@ func buildLogEntry(ctx context.Context, message string, trace []string, errKind
// consoleLogIf prints a detailed error message during
// the execution of the server.
func consoleLogIf(ctx context.Context, err error, errKind ...interface{}) {
func consoleLogIf(ctx context.Context, subsystem string, err error, errKind ...interface{}) {
if DisableErrorLog {
return
}
@@ -382,20 +384,22 @@ func consoleLogIf(ctx context.Context, err error, errKind ...interface{}) {
return
}
if consoleTgt != nil {
consoleTgt.Send(ctx, errToEntry(ctx, err, errKind...))
entry := errToEntry(ctx, subsystem, err, errKind...)
consoleTgt.Send(ctx, entry)
}
}
// logIf prints a detailed error message during
// the execution of the server.
func logIf(ctx context.Context, err error, errKind ...interface{}) {
func logIf(ctx context.Context, subsystem string, err error, errKind ...interface{}) {
if DisableErrorLog {
return
}
if err == nil {
return
}
sendLog(ctx, errToEntry(ctx, err, errKind...))
entry := errToEntry(ctx, subsystem, err, errKind...)
sendLog(ctx, entry)
}
func sendLog(ctx context.Context, entry log.Entry) {
@@ -416,11 +420,12 @@ func sendLog(ctx context.Context, entry log.Entry) {
}
// Event sends a event log to log targets
func Event(ctx context.Context, msg string, args ...interface{}) {
func Event(ctx context.Context, subsystem, msg string, args ...interface{}) {
if DisableErrorLog {
return
}
sendLog(ctx, logToEntry(ctx, fmt.Sprintf(msg, args...), EventKind))
entry := logToEntry(ctx, subsystem, fmt.Sprintf(msg, args...), EventKind)
sendLog(ctx, entry)
}
// ErrCritical is the value panic'd whenever CriticalIf is called.
@@ -430,7 +435,7 @@ var ErrCritical struct{}
// current go-routine by causing a `panic(ErrCritical)`.
func CriticalIf(ctx context.Context, err error, errKind ...interface{}) {
if err != nil {
LogIf(ctx, err, errKind...)
LogIf(ctx, "", err, errKind...)
panic(ErrCritical)
}
}

View File

@@ -38,7 +38,7 @@ type logOnceType struct {
sync.Mutex
}
func (l *logOnceType) logOnceConsoleIf(ctx context.Context, err error, id string, errKind ...interface{}) {
func (l *logOnceType) logOnceConsoleIf(ctx context.Context, subsystem string, err error, id string, errKind ...interface{}) {
if err == nil {
return
}
@@ -61,7 +61,7 @@ func (l *logOnceType) logOnceConsoleIf(ctx context.Context, err error, id string
l.Unlock()
if shouldLog {
consoleLogIf(ctx, err, errKind...)
consoleLogIf(ctx, subsystem, err, errKind...)
}
}
@@ -92,7 +92,7 @@ func unwrapErrs(err error) (leafErr error) {
}
// One log message per error.
func (l *logOnceType) logOnceIf(ctx context.Context, err error, id string, errKind ...interface{}) {
func (l *logOnceType) logOnceIf(ctx context.Context, subsystem string, err error, id string, errKind ...interface{}) {
if err == nil {
return
}
@@ -115,7 +115,7 @@ func (l *logOnceType) logOnceIf(ctx context.Context, err error, id string, errKi
l.Unlock()
if shouldLog {
logIf(ctx, err, errKind...)
logIf(ctx, subsystem, err, errKind...)
}
}
@@ -142,17 +142,17 @@ var logOnce = newLogOnceType()
// LogOnceIf - Logs notification errors - once per error.
// id is a unique identifier for related log messages, refer to cmd/notification.go
// on how it is used.
func LogOnceIf(ctx context.Context, err error, id string, errKind ...interface{}) {
func LogOnceIf(ctx context.Context, subsystem string, err error, id string, errKind ...interface{}) {
if logIgnoreError(err) {
return
}
logOnce.logOnceIf(ctx, err, id, errKind...)
logOnce.logOnceIf(ctx, subsystem, err, id, errKind...)
}
// LogOnceConsoleIf - similar to LogOnceIf but exclusively only logs to console target.
func LogOnceConsoleIf(ctx context.Context, err error, id string, errKind ...interface{}) {
func LogOnceConsoleIf(ctx context.Context, subsystem string, err error, id string, errKind ...interface{}) {
if logIgnoreError(err) {
return
}
logOnce.logOnceConsoleIf(ctx, err, id, errKind...)
logOnce.logOnceConsoleIf(ctx, subsystem, err, id, errKind...)
}

View File

@@ -153,7 +153,7 @@ func (r *ReqInfo) PopulateTagsMap(tagsMap map[string]interface{}) {
// SetReqInfo sets ReqInfo in the context.
func SetReqInfo(ctx context.Context, req *ReqInfo) context.Context {
if ctx == nil {
LogIf(context.Background(), fmt.Errorf("context is nil"))
LogIf(context.Background(), "", fmt.Errorf("context is nil"))
return nil
}
return context.WithValue(ctx, contextLogKey, req)

View File

@@ -88,22 +88,25 @@ func (c *Target) Send(e interface{}) error {
var apiString string
if entry.API != nil {
apiString = "API: " + entry.API.Name + "("
apiString = "API: " + entry.API.Name
if entry.API.Args != nil {
args := ""
if entry.API.Args.Bucket != "" {
apiString = apiString + "bucket=" + entry.API.Args.Bucket
args = args + "bucket=" + entry.API.Args.Bucket
}
if entry.API.Args.Object != "" {
apiString = apiString + ", object=" + entry.API.Args.Object
args = args + ", object=" + entry.API.Args.Object
}
if entry.API.Args.VersionID != "" {
apiString = apiString + ", versionId=" + entry.API.Args.VersionID
args = args + ", versionId=" + entry.API.Args.VersionID
}
if len(entry.API.Args.Objects) > 0 {
apiString = apiString + ", multiObject=true, numberOfObjects=" + strconv.Itoa(len(entry.API.Args.Objects))
args = args + ", multiObject=true, numberOfObjects=" + strconv.Itoa(len(entry.API.Args.Objects))
}
if len(args) > 0 {
apiString += "(" + args + ")"
}
}
apiString += ")"
} else {
apiString = "INTERNAL"
}