| 
									
										
										
										
											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/>.
 | 
					
						
							| 
									
										
										
										
											2018-03-15 03:01:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | package logger | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | import ( | 
					
						
							|  |  |  | 	"context" | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"sync" | 
					
						
							| 
									
										
										
										
											2022-10-03 03:29:29 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/minio/minio/internal/auth" | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | ) | 
					
						
							| 
									
										
										
										
											2018-03-15 03:01:47 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | // Key used for Get/SetReqInfo
 | 
					
						
							| 
									
										
										
										
											2018-03-15 09:36:54 +08:00
										 |  |  | type contextKeyType string | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const contextLogKey = contextKeyType("miniolog") | 
					
						
							| 
									
										
										
										
											2018-03-15 03:01:47 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // KeyVal - appended to ReqInfo.Tags
 | 
					
						
							|  |  |  | type KeyVal struct { | 
					
						
							|  |  |  | 	Key string | 
					
						
							| 
									
										
										
										
											2021-01-27 05:21:51 +08:00
										 |  |  | 	Val interface{} | 
					
						
							| 
									
										
										
										
											2018-03-15 03:01:47 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-03 17:28:52 +08:00
										 |  |  | // ObjectVersion object version key/versionId
 | 
					
						
							|  |  |  | type ObjectVersion struct { | 
					
						
							|  |  |  | 	ObjectName string | 
					
						
							|  |  |  | 	VersionID  string `json:"VersionId,omitempty"` | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-15 03:01:47 +08:00
										 |  |  | // ReqInfo stores the request info.
 | 
					
						
							| 
									
										
										
										
											2022-07-01 01:48:50 +08:00
										 |  |  | // Reading/writing directly to struct requires appropriate R/W lock.
 | 
					
						
							| 
									
										
										
										
											2018-03-15 03:01:47 +08:00
										 |  |  | type ReqInfo struct { | 
					
						
							| 
									
										
										
										
											2022-10-03 03:29:29 +08:00
										 |  |  | 	RemoteHost   string           // Client Host/IP
 | 
					
						
							|  |  |  | 	Host         string           // Node Host/IP
 | 
					
						
							|  |  |  | 	UserAgent    string           // User Agent
 | 
					
						
							|  |  |  | 	DeploymentID string           // x-minio-deployment-id
 | 
					
						
							|  |  |  | 	RequestID    string           // x-amz-request-id
 | 
					
						
							|  |  |  | 	API          string           // API name - GetObject PutObject NewMultipartUpload etc.
 | 
					
						
							|  |  |  | 	BucketName   string           `json:",omitempty"` // Bucket name
 | 
					
						
							|  |  |  | 	ObjectName   string           `json:",omitempty"` // Object name
 | 
					
						
							|  |  |  | 	VersionID    string           `json:",omitempty"` // corresponding versionID for the object
 | 
					
						
							|  |  |  | 	Objects      []ObjectVersion  `json:",omitempty"` // Only set during MultiObject delete handler.
 | 
					
						
							|  |  |  | 	Cred         auth.Credentials `json:"-"` | 
					
						
							|  |  |  | 	Region       string           `json:"-"` | 
					
						
							|  |  |  | 	Owner        bool             `json:"-"` | 
					
						
							|  |  |  | 	AuthType     string           `json:"-"` | 
					
						
							|  |  |  | 	tags         []KeyVal         // Any additional info not accommodated by above fields
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 	sync.RWMutex | 
					
						
							| 
									
										
										
										
											2018-03-15 03:01:47 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | // NewReqInfo :
 | 
					
						
							| 
									
										
										
										
											2018-11-20 06:47:03 +08:00
										 |  |  | func NewReqInfo(remoteHost, userAgent, deploymentID, requestID, api, bucket, object string) *ReqInfo { | 
					
						
							| 
									
										
										
										
											2022-01-03 17:28:52 +08:00
										 |  |  | 	return &ReqInfo{ | 
					
						
							|  |  |  | 		RemoteHost:   remoteHost, | 
					
						
							|  |  |  | 		UserAgent:    userAgent, | 
					
						
							|  |  |  | 		API:          api, | 
					
						
							|  |  |  | 		DeploymentID: deploymentID, | 
					
						
							|  |  |  | 		RequestID:    requestID, | 
					
						
							|  |  |  | 		BucketName:   bucket, | 
					
						
							|  |  |  | 		ObjectName:   object, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // AppendTags - appends key/val to ReqInfo.tags
 | 
					
						
							| 
									
										
										
										
											2021-01-27 05:21:51 +08:00
										 |  |  | func (r *ReqInfo) AppendTags(key string, val interface{}) *ReqInfo { | 
					
						
							| 
									
										
										
										
											2018-03-15 03:01:47 +08:00
										 |  |  | 	if r == nil { | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 		return nil | 
					
						
							| 
									
										
										
										
											2018-03-15 03:01:47 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 	r.Lock() | 
					
						
							|  |  |  | 	defer r.Unlock() | 
					
						
							|  |  |  | 	r.tags = append(r.tags, KeyVal{key, val}) | 
					
						
							|  |  |  | 	return r | 
					
						
							| 
									
										
										
										
											2018-03-15 03:01:47 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-06 23:03:18 +08:00
										 |  |  | // SetTags - sets key/val to ReqInfo.tags
 | 
					
						
							| 
									
										
										
										
											2021-01-27 05:21:51 +08:00
										 |  |  | func (r *ReqInfo) SetTags(key string, val interface{}) *ReqInfo { | 
					
						
							| 
									
										
										
										
											2018-09-06 23:03:18 +08:00
										 |  |  | 	if r == nil { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	r.Lock() | 
					
						
							|  |  |  | 	defer r.Unlock() | 
					
						
							|  |  |  | 	// Search of tag key already exists in tags
 | 
					
						
							|  |  |  | 	var updated bool | 
					
						
							|  |  |  | 	for _, tag := range r.tags { | 
					
						
							|  |  |  | 		if tag.Key == key { | 
					
						
							|  |  |  | 			tag.Val = val | 
					
						
							|  |  |  | 			updated = true | 
					
						
							|  |  |  | 			break | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if !updated { | 
					
						
							|  |  |  | 		// Append to the end of tags list
 | 
					
						
							|  |  |  | 		r.tags = append(r.tags, KeyVal{key, val}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return r | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | // GetTags - returns the user defined tags
 | 
					
						
							|  |  |  | func (r *ReqInfo) GetTags() []KeyVal { | 
					
						
							|  |  |  | 	if r == nil { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	r.RLock() | 
					
						
							|  |  |  | 	defer r.RUnlock() | 
					
						
							| 
									
										
										
										
											2022-07-01 01:48:50 +08:00
										 |  |  | 	return append(make([]KeyVal, 0, len(r.tags)), r.tags...) | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-27 05:21:51 +08:00
										 |  |  | // GetTagsMap - returns the user defined tags in a map structure
 | 
					
						
							|  |  |  | func (r *ReqInfo) GetTagsMap() map[string]interface{} { | 
					
						
							|  |  |  | 	if r == nil { | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	r.RLock() | 
					
						
							|  |  |  | 	defer r.RUnlock() | 
					
						
							|  |  |  | 	m := make(map[string]interface{}, len(r.tags)) | 
					
						
							|  |  |  | 	for _, t := range r.tags { | 
					
						
							|  |  |  | 		m[t.Key] = t.Val | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return m | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | // 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")) | 
					
						
							|  |  |  | 		return nil | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2018-03-15 09:36:54 +08:00
										 |  |  | 	return context.WithValue(ctx, contextLogKey, req) | 
					
						
							| 
									
										
										
										
											2018-03-15 03:01:47 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | // GetReqInfo returns ReqInfo if set.
 | 
					
						
							|  |  |  | func GetReqInfo(ctx context.Context) *ReqInfo { | 
					
						
							|  |  |  | 	if ctx != nil { | 
					
						
							|  |  |  | 		r, ok := ctx.Value(contextLogKey).(*ReqInfo) | 
					
						
							|  |  |  | 		if ok { | 
					
						
							|  |  |  | 			return r | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2018-09-14 12:42:50 +08:00
										 |  |  | 		r = &ReqInfo{} | 
					
						
							|  |  |  | 		return r | 
					
						
							| 
									
										
										
										
											2018-03-15 03:01:47 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } |