go.etcd.io/etcd@v3.3.27+incompatible/etcdserver/etcdserverpb/raft_internal_stringer.go (about) 1 // Copyright 2018 The etcd Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package etcdserverpb 16 17 import ( 18 "fmt" 19 "strings" 20 21 proto "github.com/golang/protobuf/proto" 22 ) 23 24 // InternalRaftStringer implements custom proto Stringer: 25 // redact password, replace value fields with value_size fields. 26 type InternalRaftStringer struct { 27 Request *InternalRaftRequest 28 } 29 30 func (as *InternalRaftStringer) String() string { 31 switch { 32 case as.Request.LeaseGrant != nil: 33 return fmt.Sprintf("header:<%s> lease_grant:<ttl:%d-second id:%016x>", 34 as.Request.Header.String(), 35 as.Request.LeaseGrant.TTL, 36 as.Request.LeaseGrant.ID, 37 ) 38 case as.Request.LeaseRevoke != nil: 39 return fmt.Sprintf("header:<%s> lease_revoke:<id:%016x>", 40 as.Request.Header.String(), 41 as.Request.LeaseRevoke.ID, 42 ) 43 case as.Request.Authenticate != nil: 44 return fmt.Sprintf("header:<%s> authenticate:<name:%s simple_token:%s>", 45 as.Request.Header.String(), 46 as.Request.Authenticate.Name, 47 as.Request.Authenticate.SimpleToken, 48 ) 49 case as.Request.AuthUserAdd != nil: 50 return fmt.Sprintf("header:<%s> auth_user_add:<name:%s>", 51 as.Request.Header.String(), 52 as.Request.AuthUserAdd.Name, 53 ) 54 case as.Request.AuthUserChangePassword != nil: 55 return fmt.Sprintf("header:<%s> auth_user_change_password:<name:%s>", 56 as.Request.Header.String(), 57 as.Request.AuthUserChangePassword.Name, 58 ) 59 case as.Request.Put != nil: 60 return fmt.Sprintf("header:<%s> put:<%s>", 61 as.Request.Header.String(), 62 NewLoggablePutRequest(as.Request.Put).String(), 63 ) 64 case as.Request.Txn != nil: 65 return fmt.Sprintf("header:<%s> txn:<%s>", 66 as.Request.Header.String(), 67 NewLoggableTxnRequest(as.Request.Txn).String(), 68 ) 69 default: 70 // nothing to redact 71 } 72 return as.Request.String() 73 } 74 75 // txnRequestStringer implements a custom proto String to replace value bytes fields with value size 76 // fields in any nested txn and put operations. 77 type txnRequestStringer struct { 78 Request *TxnRequest 79 } 80 81 func NewLoggableTxnRequest(request *TxnRequest) *txnRequestStringer { 82 return &txnRequestStringer{request} 83 } 84 85 func (as *txnRequestStringer) String() string { 86 var compare []string 87 for _, c := range as.Request.Compare { 88 switch cv := c.TargetUnion.(type) { 89 case *Compare_Value: 90 compare = append(compare, newLoggableValueCompare(c, cv).String()) 91 default: 92 // nothing to redact 93 compare = append(compare, c.String()) 94 } 95 } 96 var success []string 97 for _, s := range as.Request.Success { 98 success = append(success, newLoggableRequestOp(s).String()) 99 } 100 var failure []string 101 for _, f := range as.Request.Failure { 102 failure = append(failure, newLoggableRequestOp(f).String()) 103 } 104 return fmt.Sprintf("compare:<%s> success:<%s> failure:<%s>", 105 strings.Join(compare, " "), 106 strings.Join(success, " "), 107 strings.Join(failure, " "), 108 ) 109 } 110 111 // requestOpStringer implements a custom proto String to replace value bytes fields with value 112 // size fields in any nested txn and put operations. 113 type requestOpStringer struct { 114 Op *RequestOp 115 } 116 117 func newLoggableRequestOp(op *RequestOp) *requestOpStringer { 118 return &requestOpStringer{op} 119 } 120 121 func (as *requestOpStringer) String() string { 122 switch op := as.Op.Request.(type) { 123 case *RequestOp_RequestPut: 124 return fmt.Sprintf("request_put:<%s>", NewLoggablePutRequest(op.RequestPut).String()) 125 case *RequestOp_RequestTxn: 126 return fmt.Sprintf("request_txn:<%s>", NewLoggableTxnRequest(op.RequestTxn).String()) 127 default: 128 // nothing to redact 129 } 130 return as.Op.String() 131 } 132 133 // loggableValueCompare implements a custom proto String for Compare.Value union member types to 134 // replace the value bytes field with a value size field. 135 // To preserve proto encoding of the key and range_end bytes, a faked out proto type is used here. 136 type loggableValueCompare struct { 137 Result Compare_CompareResult `protobuf:"varint,1,opt,name=result,proto3,enum=etcdserverpb.Compare_CompareResult"` 138 Target Compare_CompareTarget `protobuf:"varint,2,opt,name=target,proto3,enum=etcdserverpb.Compare_CompareTarget"` 139 Key []byte `protobuf:"bytes,3,opt,name=key,proto3"` 140 ValueSize int64 `protobuf:"varint,7,opt,name=value_size,proto3"` 141 RangeEnd []byte `protobuf:"bytes,64,opt,name=range_end,proto3"` 142 } 143 144 func newLoggableValueCompare(c *Compare, cv *Compare_Value) *loggableValueCompare { 145 return &loggableValueCompare{ 146 c.Result, 147 c.Target, 148 c.Key, 149 int64(len(cv.Value)), 150 c.RangeEnd, 151 } 152 } 153 154 func (m *loggableValueCompare) Reset() { *m = loggableValueCompare{} } 155 func (m *loggableValueCompare) String() string { return proto.CompactTextString(m) } 156 func (*loggableValueCompare) ProtoMessage() {} 157 158 // loggablePutRequest implements a custom proto String to replace value bytes field with a value 159 // size field. 160 // To preserve proto encoding of the key bytes, a faked out proto type is used here. 161 type loggablePutRequest struct { 162 Key []byte `protobuf:"bytes,1,opt,name=key,proto3"` 163 ValueSize int64 `protobuf:"varint,2,opt,name=value_size,proto3"` 164 Lease int64 `protobuf:"varint,3,opt,name=lease,proto3"` 165 PrevKv bool `protobuf:"varint,4,opt,name=prev_kv,proto3"` 166 IgnoreValue bool `protobuf:"varint,5,opt,name=ignore_value,proto3"` 167 IgnoreLease bool `protobuf:"varint,6,opt,name=ignore_lease,proto3"` 168 } 169 170 func NewLoggablePutRequest(request *PutRequest) *loggablePutRequest { 171 return &loggablePutRequest{ 172 request.Key, 173 int64(len(request.Value)), 174 request.Lease, 175 request.PrevKv, 176 request.IgnoreValue, 177 request.IgnoreLease, 178 } 179 } 180 181 func (m *loggablePutRequest) Reset() { *m = loggablePutRequest{} } 182 func (m *loggablePutRequest) String() string { return proto.CompactTextString(m) } 183 func (*loggablePutRequest) ProtoMessage() {}