| 
									
										
										
										
											2021-04-19 03:41:13 +08:00
										 |  |  | // Copyright (c) 2015-2021 MinIO, Inc.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This file is part of MinIO Object Storage stack
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This program is free software: you can redistribute it and/or modify
 | 
					
						
							|  |  |  | // it under the terms of the GNU Affero General Public License as published by
 | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or
 | 
					
						
							|  |  |  | // (at your option) any later version.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This program is distributed in the hope that it will be useful
 | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					
						
							|  |  |  | // GNU Affero General Public License for more details.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // You should have received a copy of the GNU Affero General Public License
 | 
					
						
							|  |  |  | // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							| 
									
										
										
										
											2015-09-18 14:49:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | package logger | 
					
						
							| 
									
										
										
										
											2015-09-18 14:49:06 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2018-12-19 08:08:11 +08:00
										 |  |  | 	"encoding/hex" | 
					
						
							| 
									
										
										
										
											2016-10-11 15:50:27 +08:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2018-03-31 10:13:25 +08:00
										 |  |  | 	"go/build" | 
					
						
							| 
									
										
										
										
											2018-01-17 23:24:46 +08:00
										 |  |  | 	"path/filepath" | 
					
						
							| 
									
										
										
										
											2018-12-19 08:08:11 +08:00
										 |  |  | 	"reflect" | 
					
						
							| 
									
										
										
										
											2016-10-11 15:50:27 +08:00
										 |  |  | 	"runtime" | 
					
						
							| 
									
										
										
										
											2016-05-25 17:32:35 +08:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2018-01-17 23:24:46 +08:00
										 |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2015-09-18 14:49:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-19 08:08:11 +08:00
										 |  |  | 	"github.com/minio/highwayhash" | 
					
						
							| 
									
										
										
										
											2022-12-07 05:46:50 +08:00
										 |  |  | 	"github.com/minio/madmin-go/v2" | 
					
						
							| 
									
										
										
										
											2020-07-15 00:38:05 +08:00
										 |  |  | 	"github.com/minio/minio-go/v7/pkg/set" | 
					
						
							| 
									
										
										
										
											2022-02-24 05:36:01 +08:00
										 |  |  | 	xhttp "github.com/minio/minio/internal/http" | 
					
						
							| 
									
										
										
										
											2023-02-22 13:21:17 +08:00
										 |  |  | 	"github.com/minio/pkg/logger/message/log" | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 01:15:06 +08:00
										 |  |  | // HighwayHash key for logging in anonymous mode
 | 
					
						
							|  |  |  | var magicHighwayHash256Key = []byte("\x4b\xe7\x34\xfa\x8e\x23\x8a\xcd\x26\x3e\x83\xe6\xbb\x96\x85\x52\x04\x0f\x93\x5d\xa3\x9f\x44\x14\x97\xe0\x9d\x13\x22\xde\x36\xa0") | 
					
						
							| 
									
										
										
										
											2018-12-19 08:08:11 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-30 23:23:40 +08:00
										 |  |  | // LogLevel type
 | 
					
						
							|  |  |  | type LogLevel int8 | 
					
						
							| 
									
										
										
										
											2017-03-24 07:36:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-17 23:24:46 +08:00
										 |  |  | // Enumerated level types
 | 
					
						
							|  |  |  | const ( | 
					
						
							| 
									
										
										
										
											2022-08-30 23:23:40 +08:00
										 |  |  | 	InfoLvl LogLevel = iota + 1 | 
					
						
							| 
									
										
										
										
											2018-05-09 10:04:36 +08:00
										 |  |  | 	ErrorLvl | 
					
						
							|  |  |  | 	FatalLvl | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	Application = madmin.LogKindApplication | 
					
						
							|  |  |  | 	Minio       = madmin.LogKindMinio | 
					
						
							|  |  |  | 	All         = madmin.LogKindAll | 
					
						
							| 
									
										
										
										
											2018-01-17 23:24:46 +08:00
										 |  |  | ) | 
					
						
							| 
									
										
										
										
											2017-03-24 07:36:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-30 23:23:40 +08:00
										 |  |  | // MinimumLogLevel holds the minimum logging level to print - info by default
 | 
					
						
							|  |  |  | var MinimumLogLevel = InfoLvl | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 06:47:03 +08:00
										 |  |  | var trimStrings []string | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TimeFormat - logging time format.
 | 
					
						
							|  |  |  | const TimeFormat string = "15:04:05 MST 01/02/2006" | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | var matchingFuncNames = [...]string{ | 
					
						
							|  |  |  | 	"http.HandlerFunc.ServeHTTP", | 
					
						
							|  |  |  | 	"cmd.serverMain", | 
					
						
							|  |  |  | 	// add more here ..
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-30 23:23:40 +08:00
										 |  |  | func (level LogLevel) String() string { | 
					
						
							| 
									
										
										
										
											2018-01-17 23:24:46 +08:00
										 |  |  | 	switch level { | 
					
						
							| 
									
										
										
										
											2022-08-30 23:23:40 +08:00
										 |  |  | 	case InfoLvl: | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 		return "INFO" | 
					
						
							| 
									
										
										
										
											2018-05-09 10:04:36 +08:00
										 |  |  | 	case ErrorLvl: | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 		return "ERROR" | 
					
						
							| 
									
										
										
										
											2018-05-09 10:04:36 +08:00
										 |  |  | 	case FatalLvl: | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 		return "FATAL" | 
					
						
							| 
									
										
										
										
											2018-01-17 23:24:46 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 	return "" | 
					
						
							| 
									
										
										
										
											2017-03-24 07:36:00 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 06:47:03 +08:00
										 |  |  | // quietFlag: Hide startup messages if enabled
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | // jsonFlag: Display in JSON format, if enabled
 | 
					
						
							|  |  |  | var ( | 
					
						
							| 
									
										
										
										
											2018-12-19 08:08:11 +08:00
										 |  |  | 	quietFlag, jsonFlag, anonFlag bool | 
					
						
							| 
									
										
										
										
											2018-05-09 10:04:36 +08:00
										 |  |  | 	// Custom function to format error
 | 
					
						
							|  |  |  | 	errorFmtFunc func(string, error, bool) string | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-17 23:24:46 +08:00
										 |  |  | // EnableQuiet - turns quiet option on.
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | func EnableQuiet() { | 
					
						
							| 
									
										
										
										
											2018-11-20 06:47:03 +08:00
										 |  |  | 	quietFlag = true | 
					
						
							| 
									
										
										
										
											2017-03-24 07:36:00 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-17 23:24:46 +08:00
										 |  |  | // EnableJSON - outputs logs in json format.
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | func EnableJSON() { | 
					
						
							|  |  |  | 	jsonFlag = true | 
					
						
							| 
									
										
										
										
											2018-11-20 06:47:03 +08:00
										 |  |  | 	quietFlag = true | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-19 08:08:11 +08:00
										 |  |  | // EnableAnonymous - turns anonymous flag
 | 
					
						
							|  |  |  | // to avoid printing sensitive information.
 | 
					
						
							|  |  |  | func EnableAnonymous() { | 
					
						
							|  |  |  | 	anonFlag = true | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 06:47:03 +08:00
										 |  |  | // IsJSON - returns true if jsonFlag is true
 | 
					
						
							|  |  |  | func IsJSON() bool { | 
					
						
							|  |  |  | 	return jsonFlag | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // IsQuiet - returns true if quietFlag is true
 | 
					
						
							|  |  |  | func IsQuiet() bool { | 
					
						
							|  |  |  | 	return quietFlag | 
					
						
							| 
									
										
										
										
											2017-03-24 07:36:00 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-05 01:35:33 +08:00
										 |  |  | // RegisterError registers the specified rendering function. This latter
 | 
					
						
							| 
									
										
										
										
											2018-05-09 10:04:36 +08:00
										 |  |  | // will be called for a pretty rendering of fatal errors.
 | 
					
						
							| 
									
										
										
										
											2019-10-05 01:35:33 +08:00
										 |  |  | func RegisterError(f func(string, error, bool) string) { | 
					
						
							| 
									
										
										
										
											2018-05-09 10:04:36 +08:00
										 |  |  | 	errorFmtFunc = f | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 06:47:03 +08:00
										 |  |  | // Remove any duplicates and return unique entries.
 | 
					
						
							|  |  |  | func uniqueEntries(paths []string) []string { | 
					
						
							|  |  |  | 	m := make(set.StringSet) | 
					
						
							|  |  |  | 	for _, p := range paths { | 
					
						
							|  |  |  | 		if !m.Contains(p) { | 
					
						
							|  |  |  | 			m.Add(p) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return m.ToSlice() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | // Init sets the trimStrings to possible GOPATHs
 | 
					
						
							|  |  |  | // and GOROOT directories. Also append github.com/minio/minio
 | 
					
						
							|  |  |  | // This is done to clean up the filename, when stack trace is
 | 
					
						
							|  |  |  | // displayed when an error happens.
 | 
					
						
							| 
									
										
										
										
											2018-06-19 03:04:46 +08:00
										 |  |  | func Init(goPath string, goRoot string) { | 
					
						
							| 
									
										
										
										
											2018-01-17 23:24:46 +08:00
										 |  |  | 	var goPathList []string | 
					
						
							| 
									
										
										
										
											2018-06-19 03:04:46 +08:00
										 |  |  | 	var goRootList []string | 
					
						
							| 
									
										
										
										
											2018-03-31 10:13:25 +08:00
										 |  |  | 	var defaultgoPathList []string | 
					
						
							| 
									
										
										
										
											2018-06-19 03:04:46 +08:00
										 |  |  | 	var defaultgoRootList []string | 
					
						
							|  |  |  | 	pathSeperator := ":" | 
					
						
							| 
									
										
										
										
											2018-01-17 23:24:46 +08:00
										 |  |  | 	// Add all possible GOPATH paths into trimStrings
 | 
					
						
							|  |  |  | 	// Split GOPATH depending on the OS type
 | 
					
						
							|  |  |  | 	if runtime.GOOS == "windows" { | 
					
						
							| 
									
										
										
										
											2018-06-19 03:04:46 +08:00
										 |  |  | 		pathSeperator = ";" | 
					
						
							| 
									
										
										
										
											2016-11-24 03:35:04 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-03-24 07:36:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-19 03:04:46 +08:00
										 |  |  | 	goPathList = strings.Split(goPath, pathSeperator) | 
					
						
							|  |  |  | 	goRootList = strings.Split(goRoot, pathSeperator) | 
					
						
							|  |  |  | 	defaultgoPathList = strings.Split(build.Default.GOPATH, pathSeperator) | 
					
						
							|  |  |  | 	defaultgoRootList = strings.Split(build.Default.GOROOT, pathSeperator) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-17 23:24:46 +08:00
										 |  |  | 	// Add trim string "{GOROOT}/src/" into trimStrings
 | 
					
						
							|  |  |  | 	trimStrings = []string{filepath.Join(runtime.GOROOT(), "src") + string(filepath.Separator)} | 
					
						
							| 
									
										
										
										
											2017-03-24 07:36:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-17 23:24:46 +08:00
										 |  |  | 	// Add all possible path from GOPATH=path1:path2...:pathN
 | 
					
						
							|  |  |  | 	// as "{path#}/src/" into trimStrings
 | 
					
						
							|  |  |  | 	for _, goPathString := range goPathList { | 
					
						
							|  |  |  | 		trimStrings = append(trimStrings, filepath.Join(goPathString, "src")+string(filepath.Separator)) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-03-31 10:13:25 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-19 03:04:46 +08:00
										 |  |  | 	for _, goRootString := range goRootList { | 
					
						
							|  |  |  | 		trimStrings = append(trimStrings, filepath.Join(goRootString, "src")+string(filepath.Separator)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-31 10:13:25 +08:00
										 |  |  | 	for _, defaultgoPathString := range defaultgoPathList { | 
					
						
							|  |  |  | 		trimStrings = append(trimStrings, filepath.Join(defaultgoPathString, "src")+string(filepath.Separator)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-19 03:04:46 +08:00
										 |  |  | 	for _, defaultgoRootString := range defaultgoRootList { | 
					
						
							|  |  |  | 		trimStrings = append(trimStrings, filepath.Join(defaultgoRootString, "src")+string(filepath.Separator)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Remove duplicate entries.
 | 
					
						
							|  |  |  | 	trimStrings = uniqueEntries(trimStrings) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-17 23:24:46 +08:00
										 |  |  | 	// Add "github.com/minio/minio" as the last to cover
 | 
					
						
							|  |  |  | 	// paths like "{GOROOT}/src/github.com/minio/minio"
 | 
					
						
							|  |  |  | 	// and "{GOPATH}/src/github.com/minio/minio"
 | 
					
						
							|  |  |  | 	trimStrings = append(trimStrings, filepath.Join("github.com", "minio", "minio")+string(filepath.Separator)) | 
					
						
							| 
									
										
										
										
											2015-09-19 17:36:50 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-17 23:24:46 +08:00
										 |  |  | func trimTrace(f string) string { | 
					
						
							|  |  |  | 	for _, trimString := range trimStrings { | 
					
						
							|  |  |  | 		f = strings.TrimPrefix(filepath.ToSlash(f), filepath.ToSlash(trimString)) | 
					
						
							| 
									
										
										
										
											2017-03-24 07:36:00 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-01-17 23:24:46 +08:00
										 |  |  | 	return filepath.FromSlash(f) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2017-03-24 07:36:00 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-09 10:04:36 +08:00
										 |  |  | func getSource(level int) string { | 
					
						
							|  |  |  | 	pc, file, lineNumber, ok := runtime.Caller(level) | 
					
						
							| 
									
										
										
										
											2018-04-11 00:37:14 +08:00
										 |  |  | 	if ok { | 
					
						
							|  |  |  | 		// Clean up the common prefixes
 | 
					
						
							|  |  |  | 		file = trimTrace(file) | 
					
						
							|  |  |  | 		_, funcName := filepath.Split(runtime.FuncForPC(pc).Name()) | 
					
						
							|  |  |  | 		return fmt.Sprintf("%v:%v:%v()", file, lineNumber, funcName) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return "" | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-17 23:24:46 +08:00
										 |  |  | // getTrace method - creates and returns stack trace
 | 
					
						
							|  |  |  | func getTrace(traceLevel int) []string { | 
					
						
							|  |  |  | 	var trace []string | 
					
						
							|  |  |  | 	pc, file, lineNumber, ok := runtime.Caller(traceLevel) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-19 03:04:46 +08:00
										 |  |  | 	for ok && file != "" { | 
					
						
							| 
									
										
										
										
											2018-01-17 23:24:46 +08:00
										 |  |  | 		// Clean up the common prefixes
 | 
					
						
							|  |  |  | 		file = trimTrace(file) | 
					
						
							|  |  |  | 		// Get the function name
 | 
					
						
							|  |  |  | 		_, funcName := filepath.Split(runtime.FuncForPC(pc).Name()) | 
					
						
							|  |  |  | 		// Skip duplicate traces that start with file name, "<autogenerated>"
 | 
					
						
							|  |  |  | 		// and also skip traces with function name that starts with "runtime."
 | 
					
						
							|  |  |  | 		if !strings.HasPrefix(file, "<autogenerated>") && | 
					
						
							|  |  |  | 			!strings.HasPrefix(funcName, "runtime.") { | 
					
						
							|  |  |  | 			// Form and append a line of stack trace into a
 | 
					
						
							|  |  |  | 			// collection, 'trace', to build full stack trace
 | 
					
						
							|  |  |  | 			trace = append(trace, fmt.Sprintf("%v:%v:%v()", file, lineNumber, funcName)) | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			// Ignore trace logs beyond the following conditions
 | 
					
						
							|  |  |  | 			for _, name := range matchingFuncNames { | 
					
						
							|  |  |  | 				if funcName == name { | 
					
						
							|  |  |  | 					return trace | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2018-01-17 23:24:46 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		traceLevel++ | 
					
						
							|  |  |  | 		// Read stack trace information from PC
 | 
					
						
							|  |  |  | 		pc, file, lineNumber, ok = runtime.Caller(traceLevel) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return trace | 
					
						
							| 
									
										
										
										
											2017-03-24 07:36:00 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-19 08:08:11 +08:00
										 |  |  | // Return the highway hash of the passed string
 | 
					
						
							|  |  |  | func hashString(input string) string { | 
					
						
							| 
									
										
										
										
											2021-11-10 07:28:08 +08:00
										 |  |  | 	hh, _ := highwayhash.New(magicHighwayHash256Key) | 
					
						
							|  |  |  | 	hh.Write([]byte(input)) | 
					
						
							|  |  |  | 	return hex.EncodeToString(hh.Sum(nil)) | 
					
						
							| 
									
										
										
										
											2018-12-19 08:08:11 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-15 04:58:48 +08:00
										 |  |  | // LogAlwaysIf prints a detailed error message during
 | 
					
						
							| 
									
										
										
										
											2018-05-09 10:04:36 +08:00
										 |  |  | // the execution of the server.
 | 
					
						
							| 
									
										
										
										
											2019-10-12 09:50:54 +08:00
										 |  |  | func LogAlwaysIf(ctx context.Context, err error, errKind ...interface{}) { | 
					
						
							| 
									
										
										
										
											2018-08-15 04:58:48 +08:00
										 |  |  | 	if err == nil { | 
					
						
							| 
									
										
										
										
											2018-04-28 06:03:19 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-12 09:50:54 +08:00
										 |  |  | 	logIf(ctx, err, errKind...) | 
					
						
							| 
									
										
										
										
											2018-08-15 04:58:48 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // LogIf prints a detailed error message during
 | 
					
						
							|  |  |  | // the execution of the server, if it is not an
 | 
					
						
							|  |  |  | // ignored error.
 | 
					
						
							| 
									
										
										
										
											2019-10-12 09:50:54 +08:00
										 |  |  | func LogIf(ctx context.Context, err error, errKind ...interface{}) { | 
					
						
							| 
									
										
										
										
											2022-07-26 08:53:03 +08:00
										 |  |  | 	if logIgnoreError(err) { | 
					
						
							| 
									
										
										
										
											2020-10-31 05:55:50 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	logIf(ctx, err, errKind...) | 
					
						
							| 
									
										
										
										
											2018-08-15 04:58:48 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-12 22:20:58 +08:00
										 |  |  | func errToEntry(ctx context.Context, err error, errKind ...interface{}) log.Entry { | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 	logKind := madmin.LogKindAll | 
					
						
							| 
									
										
										
										
											2019-10-12 09:50:54 +08:00
										 |  |  | 	if len(errKind) > 0 { | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 		if ek, ok := errKind[0].(madmin.LogKind); ok { | 
					
						
							|  |  |  | 			logKind = ek | 
					
						
							| 
									
										
										
										
											2019-10-12 09:50:54 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 	req := GetReqInfo(ctx) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if req == nil { | 
					
						
							|  |  |  | 		req = &ReqInfo{API: "SYSTEM"} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-07-01 01:48:50 +08:00
										 |  |  | 	req.RLock() | 
					
						
							|  |  |  | 	defer req.RUnlock() | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	API := "SYSTEM" | 
					
						
							|  |  |  | 	if req.API != "" { | 
					
						
							|  |  |  | 		API = req.API | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-11 02:37:22 +08:00
										 |  |  | 	kv := req.GetTags() | 
					
						
							| 
									
										
										
										
											2021-01-27 05:21:51 +08:00
										 |  |  | 	tags := make(map[string]interface{}, len(kv)) | 
					
						
							| 
									
										
										
										
											2020-09-11 02:37:22 +08:00
										 |  |  | 	for _, entry := range kv { | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 		tags[entry.Key] = entry.Val | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Get full stack trace
 | 
					
						
							| 
									
										
										
										
											2018-10-27 05:41:25 +08:00
										 |  |  | 	trace := getTrace(3) | 
					
						
							| 
									
										
										
										
											2018-05-09 10:04:36 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Get the cause for the Error
 | 
					
						
							| 
									
										
										
										
											2020-10-29 00:18:35 +08:00
										 |  |  | 	message := fmt.Sprintf("%v (%T)", err, err) | 
					
						
							| 
									
										
										
										
											2022-11-12 04:42:15 +08:00
										 |  |  | 	deploymentID := req.DeploymentID | 
					
						
							| 
									
										
										
										
											2019-07-02 03:22:01 +08:00
										 |  |  | 	if req.DeploymentID == "" { | 
					
						
							| 
									
										
										
										
											2022-11-12 04:42:15 +08:00
										 |  |  | 		deploymentID = xhttp.GlobalDeploymentID | 
					
						
							| 
									
										
										
										
											2019-07-02 03:22:01 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-01-03 17:28:52 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	objects := make([]log.ObjectVersion, 0, len(req.Objects)) | 
					
						
							|  |  |  | 	for _, ov := range req.Objects { | 
					
						
							|  |  |  | 		objects = append(objects, log.ObjectVersion{ | 
					
						
							|  |  |  | 			ObjectName: ov.ObjectName, | 
					
						
							|  |  |  | 			VersionID:  ov.VersionID, | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-20 06:47:03 +08:00
										 |  |  | 	entry := log.Entry{ | 
					
						
							| 
									
										
										
										
											2022-11-12 04:42:15 +08:00
										 |  |  | 		DeploymentID: deploymentID, | 
					
						
							| 
									
										
										
										
											2018-07-20 06:55:06 +08:00
										 |  |  | 		Level:        ErrorLvl.String(), | 
					
						
							| 
									
										
										
										
											2019-10-12 09:50:54 +08:00
										 |  |  | 		LogKind:      logKind, | 
					
						
							| 
									
										
										
										
											2018-07-20 06:55:06 +08:00
										 |  |  | 		RemoteHost:   req.RemoteHost, | 
					
						
							| 
									
										
										
										
											2019-07-19 00:58:37 +08:00
										 |  |  | 		Host:         req.Host, | 
					
						
							| 
									
										
										
										
											2018-07-20 06:55:06 +08:00
										 |  |  | 		RequestID:    req.RequestID, | 
					
						
							|  |  |  | 		UserAgent:    req.UserAgent, | 
					
						
							| 
									
										
										
										
											2021-12-24 07:33:54 +08:00
										 |  |  | 		Time:         time.Now().UTC(), | 
					
						
							| 
									
										
										
										
											2018-11-20 06:47:03 +08:00
										 |  |  | 		API: &log.API{ | 
					
						
							|  |  |  | 			Name: API, | 
					
						
							|  |  |  | 			Args: &log.Args{ | 
					
						
							| 
									
										
										
										
											2022-01-03 17:28:52 +08:00
										 |  |  | 				Bucket:    req.BucketName, | 
					
						
							|  |  |  | 				Object:    req.ObjectName, | 
					
						
							|  |  |  | 				VersionID: req.VersionID, | 
					
						
							|  |  |  | 				Objects:   objects, | 
					
						
							| 
									
										
										
										
											2018-11-20 06:47:03 +08:00
										 |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		Trace: &log.Trace{ | 
					
						
							|  |  |  | 			Message:   message, | 
					
						
							|  |  |  | 			Source:    trace, | 
					
						
							|  |  |  | 			Variables: tags, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2018-07-20 06:55:06 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-19 08:08:11 +08:00
										 |  |  | 	if anonFlag { | 
					
						
							|  |  |  | 		entry.API.Args.Bucket = hashString(entry.API.Args.Bucket) | 
					
						
							|  |  |  | 		entry.API.Args.Object = hashString(entry.API.Args.Object) | 
					
						
							|  |  |  | 		entry.RemoteHost = hashString(entry.RemoteHost) | 
					
						
							| 
									
										
										
										
											2019-03-26 04:40:08 +08:00
										 |  |  | 		entry.Trace.Message = reflect.TypeOf(err).String() | 
					
						
							| 
									
										
										
										
											2021-01-27 05:21:51 +08:00
										 |  |  | 		entry.Trace.Variables = make(map[string]interface{}) | 
					
						
							| 
									
										
										
										
											2018-12-19 08:08:11 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-05-12 22:20:58 +08:00
										 |  |  | 	return entry | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // consoleLogIf prints a detailed error message during
 | 
					
						
							|  |  |  | // the execution of the server.
 | 
					
						
							|  |  |  | func consoleLogIf(ctx context.Context, err error, errKind ...interface{}) { | 
					
						
							| 
									
										
										
										
											2022-08-30 23:23:40 +08:00
										 |  |  | 	if MinimumLogLevel > ErrorLvl { | 
					
						
							| 
									
										
										
										
											2022-05-12 22:20:58 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if consoleTgt != nil { | 
					
						
							|  |  |  | 		entry := errToEntry(ctx, err, errKind...) | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 		consoleTgt.Send(entry) | 
					
						
							| 
									
										
										
										
											2022-05-12 22:20:58 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // logIf prints a detailed error message during
 | 
					
						
							|  |  |  | // the execution of the server.
 | 
					
						
							|  |  |  | func logIf(ctx context.Context, err error, errKind ...interface{}) { | 
					
						
							| 
									
										
										
										
											2022-08-30 23:23:40 +08:00
										 |  |  | 	if MinimumLogLevel > ErrorLvl { | 
					
						
							| 
									
										
										
										
											2022-05-12 22:20:58 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	systemTgts := SystemTargets() | 
					
						
							|  |  |  | 	if len(systemTgts) == 0 { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	entry := errToEntry(ctx, err, errKind...) | 
					
						
							| 
									
										
										
										
											2018-07-20 06:55:06 +08:00
										 |  |  | 	// Iterate over all logger targets to send the log entry
 | 
					
						
							| 
									
										
										
										
											2022-05-12 22:20:58 +08:00
										 |  |  | 	for _, t := range systemTgts { | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 		if err := t.Send(entry); err != nil { | 
					
						
							| 
									
										
										
										
											2022-03-16 08:45:51 +08:00
										 |  |  | 			if consoleTgt != nil { | 
					
						
							|  |  |  | 				entry.Trace.Message = fmt.Sprintf("event(%#v) was not sent to Logger target (%#v): %#v", entry, t, err) | 
					
						
							| 
									
										
										
										
											2022-07-06 05:45:49 +08:00
										 |  |  | 				consoleTgt.Send(entry) | 
					
						
							| 
									
										
										
										
											2022-03-16 08:45:51 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-12-21 05:16:53 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-11-24 08:36:26 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2018-04-11 00:37:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-26 04:51:49 +08:00
										 |  |  | // ErrCritical is the value panic'd whenever CriticalIf is called.
 | 
					
						
							|  |  |  | var ErrCritical struct{} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // CriticalIf logs the provided error on the console. It fails the
 | 
					
						
							|  |  |  | // current go-routine by causing a `panic(ErrCritical)`.
 | 
					
						
							| 
									
										
										
										
											2019-10-12 09:50:54 +08:00
										 |  |  | func CriticalIf(ctx context.Context, err error, errKind ...interface{}) { | 
					
						
							| 
									
										
										
										
											2018-04-20 08:24:43 +08:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2019-10-12 09:50:54 +08:00
										 |  |  | 		LogIf(ctx, err, errKind...) | 
					
						
							| 
									
										
										
										
											2018-06-26 04:51:49 +08:00
										 |  |  | 		panic(ErrCritical) | 
					
						
							| 
									
										
										
										
											2018-04-20 08:24:43 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-09 10:04:36 +08:00
										 |  |  | // FatalIf is similar to Fatal() but it ignores passed nil error
 | 
					
						
							| 
									
										
										
										
											2018-04-11 00:37:14 +08:00
										 |  |  | func FatalIf(err error, msg string, data ...interface{}) { | 
					
						
							| 
									
										
										
										
											2018-05-09 10:04:36 +08:00
										 |  |  | 	if err == nil { | 
					
						
							|  |  |  | 		return | 
					
						
							| 
									
										
										
										
											2018-04-11 00:37:14 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-05-09 10:04:36 +08:00
										 |  |  | 	fatal(err, msg, data...) | 
					
						
							|  |  |  | } |