blob: 31e121ee0a63e1a0e0d6df594800690fccf03a79 [file] [log] [blame]
khenaidoo106c61a2021-08-11 18:05:46 -04001// 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
15package etcdserverpb
16
17import (
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.
26type InternalRaftStringer struct {
27 Request *InternalRaftRequest
28}
29
30func (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.
77type txnRequestStringer struct {
78 Request *TxnRequest
79}
80
81func NewLoggableTxnRequest(request *TxnRequest) *txnRequestStringer {
82 return &txnRequestStringer{request}
83}
84
85func (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.
113type requestOpStringer struct {
114 Op *RequestOp
115}
116
117func newLoggableRequestOp(op *RequestOp) *requestOpStringer {
118 return &requestOpStringer{op}
119}
120
121func (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.
136type 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
144func 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
154func (m *loggableValueCompare) Reset() { *m = loggableValueCompare{} }
155func (m *loggableValueCompare) String() string { return proto.CompactTextString(m) }
156func (*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.
161type 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
170func 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
181func (m *loggablePutRequest) Reset() { *m = loggablePutRequest{} }
182func (m *loggablePutRequest) String() string { return proto.CompactTextString(m) }
183func (*loggablePutRequest) ProtoMessage() {}