storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/cmd/logger/reqinfo.go (about) 1 /* 2 * MinIO Cloud Storage, (C) 2018 MinIO, Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package logger 18 19 import ( 20 "context" 21 "fmt" 22 "sync" 23 ) 24 25 // Key used for Get/SetReqInfo 26 type contextKeyType string 27 28 const contextLogKey = contextKeyType("miniolog") 29 30 // KeyVal - appended to ReqInfo.Tags 31 type KeyVal struct { 32 Key string 33 Val interface{} 34 } 35 36 // ReqInfo stores the request info. 37 type ReqInfo struct { 38 RemoteHost string // Client Host/IP 39 Host string // Node Host/IP 40 UserAgent string // User Agent 41 DeploymentID string // x-minio-deployment-id 42 RequestID string // x-amz-request-id 43 API string // API name - GetObject PutObject NewMultipartUpload etc. 44 BucketName string // Bucket name 45 ObjectName string // Object name 46 AccessKey string // Access Key 47 AccessGrant string // Access Grant 48 tags []KeyVal // Any additional info not accommodated by above fields 49 sync.RWMutex 50 } 51 52 // NewReqInfo : 53 func NewReqInfo(remoteHost, userAgent, deploymentID, requestID, api, bucket, object string) *ReqInfo { 54 req := ReqInfo{} 55 req.RemoteHost = remoteHost 56 req.UserAgent = userAgent 57 req.API = api 58 req.DeploymentID = deploymentID 59 req.RequestID = requestID 60 req.BucketName = bucket 61 req.ObjectName = object 62 return &req 63 } 64 65 // AppendTags - appends key/val to ReqInfo.tags 66 func (r *ReqInfo) AppendTags(key string, val interface{}) *ReqInfo { 67 if r == nil { 68 return nil 69 } 70 r.Lock() 71 defer r.Unlock() 72 r.tags = append(r.tags, KeyVal{key, val}) 73 return r 74 } 75 76 // SetTags - sets key/val to ReqInfo.tags 77 func (r *ReqInfo) SetTags(key string, val interface{}) *ReqInfo { 78 if r == nil { 79 return nil 80 } 81 r.Lock() 82 defer r.Unlock() 83 // Search of tag key already exists in tags 84 var updated bool 85 for _, tag := range r.tags { 86 if tag.Key == key { 87 tag.Val = val 88 updated = true 89 break 90 } 91 } 92 if !updated { 93 // Append to the end of tags list 94 r.tags = append(r.tags, KeyVal{key, val}) 95 } 96 return r 97 } 98 99 // GetTags - returns the user defined tags 100 func (r *ReqInfo) GetTags() []KeyVal { 101 if r == nil { 102 return nil 103 } 104 r.RLock() 105 defer r.RUnlock() 106 return append([]KeyVal(nil), r.tags...) 107 } 108 109 // GetTagsMap - returns the user defined tags in a map structure 110 func (r *ReqInfo) GetTagsMap() map[string]interface{} { 111 if r == nil { 112 return nil 113 } 114 r.RLock() 115 defer r.RUnlock() 116 m := make(map[string]interface{}, len(r.tags)) 117 for _, t := range r.tags { 118 m[t.Key] = t.Val 119 } 120 return m 121 } 122 123 // SetReqInfo sets ReqInfo in the context. 124 func SetReqInfo(ctx context.Context, req *ReqInfo) context.Context { 125 if ctx == nil { 126 LogIf(context.Background(), fmt.Errorf("context is nil")) 127 return nil 128 } 129 return context.WithValue(ctx, contextLogKey, req) 130 } 131 132 // GetReqInfo returns ReqInfo if set. 133 func GetReqInfo(ctx context.Context) *ReqInfo { 134 if ctx != nil { 135 r, ok := ctx.Value(contextLogKey).(*ReqInfo) 136 if ok { 137 return r 138 } 139 r = &ReqInfo{} 140 SetReqInfo(ctx, r) 141 return r 142 } 143 return nil 144 }