github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/internal/logger/reqinfo.go (about) 1 // Copyright (c) 2015-2021 MinIO, Inc. 2 // 3 // This file is part of MinIO Object Storage stack 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package logger 19 20 import ( 21 "context" 22 "fmt" 23 "sync" 24 25 "github.com/minio/minio/internal/auth" 26 ) 27 28 // Key used for Get/SetReqInfo 29 type contextKeyType string 30 31 const contextLogKey = contextKeyType("miniolog") 32 33 // KeyVal - appended to ReqInfo.Tags 34 type KeyVal struct { 35 Key string 36 Val interface{} 37 } 38 39 // ObjectVersion object version key/versionId 40 type ObjectVersion struct { 41 ObjectName string 42 VersionID string `json:"VersionId,omitempty"` 43 } 44 45 // ReqInfo stores the request info. 46 // Reading/writing directly to struct requires appropriate R/W lock. 47 type ReqInfo struct { 48 RemoteHost string // Client Host/IP 49 Host string // Node Host/IP 50 UserAgent string // User Agent 51 DeploymentID string // x-minio-deployment-id 52 RequestID string // x-amz-request-id 53 API string // API name - GetObject PutObject NewMultipartUpload etc. 54 BucketName string `json:",omitempty"` // Bucket name 55 ObjectName string `json:",omitempty"` // Object name 56 VersionID string `json:",omitempty"` // corresponding versionID for the object 57 Objects []ObjectVersion `json:",omitempty"` // Only set during MultiObject delete handler. 58 Cred auth.Credentials `json:"-"` 59 Region string `json:"-"` 60 Owner bool `json:"-"` 61 AuthType string `json:"-"` 62 tags []KeyVal // Any additional info not accommodated by above fields 63 sync.RWMutex 64 } 65 66 // NewReqInfo : 67 func NewReqInfo(remoteHost, userAgent, deploymentID, requestID, api, bucket, object string) *ReqInfo { 68 return &ReqInfo{ 69 RemoteHost: remoteHost, 70 UserAgent: userAgent, 71 API: api, 72 DeploymentID: deploymentID, 73 RequestID: requestID, 74 BucketName: bucket, 75 ObjectName: object, 76 } 77 } 78 79 // AppendTags - appends key/val to ReqInfo.tags 80 func (r *ReqInfo) AppendTags(key string, val interface{}) *ReqInfo { 81 if r == nil { 82 return nil 83 } 84 r.Lock() 85 defer r.Unlock() 86 r.tags = append(r.tags, KeyVal{key, val}) 87 return r 88 } 89 90 // SetTags - sets key/val to ReqInfo.tags 91 func (r *ReqInfo) SetTags(key string, val interface{}) *ReqInfo { 92 if r == nil { 93 return nil 94 } 95 r.Lock() 96 defer r.Unlock() 97 // Search of tag key already exists in tags 98 var updated bool 99 for _, tag := range r.tags { 100 if tag.Key == key { 101 tag.Val = val 102 updated = true 103 break 104 } 105 } 106 if !updated { 107 // Append to the end of tags list 108 r.tags = append(r.tags, KeyVal{key, val}) 109 } 110 return r 111 } 112 113 // GetTags - returns the user defined tags 114 func (r *ReqInfo) GetTags() []KeyVal { 115 if r == nil { 116 return nil 117 } 118 r.RLock() 119 defer r.RUnlock() 120 return append(make([]KeyVal, 0, len(r.tags)), r.tags...) 121 } 122 123 // GetTagsMap - returns the user defined tags in a map structure 124 func (r *ReqInfo) GetTagsMap() map[string]interface{} { 125 if r == nil { 126 return nil 127 } 128 r.RLock() 129 defer r.RUnlock() 130 m := make(map[string]interface{}, len(r.tags)) 131 for _, t := range r.tags { 132 m[t.Key] = t.Val 133 } 134 return m 135 } 136 137 // PopulateTagsMap - returns the user defined tags in a map structure 138 func (r *ReqInfo) PopulateTagsMap(tagsMap map[string]interface{}) { 139 if r == nil { 140 return 141 } 142 if tagsMap == nil { 143 return 144 } 145 r.RLock() 146 defer r.RUnlock() 147 for _, t := range r.tags { 148 tagsMap[t.Key] = t.Val 149 } 150 return 151 } 152 153 // SetReqInfo sets ReqInfo in the context. 154 func SetReqInfo(ctx context.Context, req *ReqInfo) context.Context { 155 if ctx == nil { 156 LogIf(context.Background(), fmt.Errorf("context is nil")) 157 return nil 158 } 159 return context.WithValue(ctx, contextLogKey, req) 160 } 161 162 // GetReqInfo returns ReqInfo if set. 163 func GetReqInfo(ctx context.Context) *ReqInfo { 164 if ctx != nil { 165 r, ok := ctx.Value(contextLogKey).(*ReqInfo) 166 if ok { 167 return r 168 } 169 r = &ReqInfo{} 170 return r 171 } 172 return nil 173 }