From 9e2acdba0bf3ba39438d7cacd5affa308e2286cb Mon Sep 17 00:00:00 2001 From: Andrei Matei Date: Tue, 29 Jan 2019 16:12:31 -0500 Subject: [PATCH] roachpb: make Transaction implement SafeMessager So it is included in Sentry reports. Also improve a Fatal message that's been seen to fire for unknown reasons (haven't yet looked if I can figure out why it fires). Touches #34341 Release note: None --- pkg/kv/txn_interceptor_heartbeat.go | 4 +++- pkg/roachpb/data.go | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/pkg/kv/txn_interceptor_heartbeat.go b/pkg/kv/txn_interceptor_heartbeat.go index 032d8f6ee97b..bc6d380fa5e2 100644 --- a/pkg/kv/txn_interceptor_heartbeat.go +++ b/pkg/kv/txn_interceptor_heartbeat.go @@ -426,7 +426,9 @@ func (h *txnHeartbeat) heartbeat(ctx context.Context) bool { // status. That response is supposed to have closed the txnHeartbeat. if h.mu.txn.Status != roachpb.PENDING { if h.mu.txnEnd != nil { - log.Fatalf(ctx, "txn status: %s, but heartbeat loop hasn't been signaled to stop", h.mu.txn.Status) + log.Fatalf(ctx, + "txn committed or aborted but heartbeat loop hasn't been signaled to stop. txn: %s", + h.mu.txn) } return false } diff --git a/pkg/roachpb/data.go b/pkg/roachpb/data.go index a4feda7242d6..998e25209f4b 100644 --- a/pkg/roachpb/data.go +++ b/pkg/roachpb/data.go @@ -683,6 +683,8 @@ func (v Value) PrettyPrint() string { return buf.String() } +var _ log.SafeMessager = Transaction{} + const ( // MinTxnPriority is the minimum allowed txn priority. MinTxnPriority = 0 @@ -1010,6 +1012,8 @@ func (t *Transaction) IsSerializable() bool { } // String formats transaction into human readable string. +// +// NOTE: When updating String(), you probably want to also update SafeMessage(). func (t Transaction) String() string { var buf bytes.Buffer // Compute priority as a floating point number from 0-100 for readability. @@ -1027,6 +1031,27 @@ func (t Transaction) String() string { return buf.String() } +// SafeMessage implements the SafeMessager interface. +// +// This method should be kept largely synchronized with String(), except that it +// can't include sensitive info (e.g. the transaction key). +func (t Transaction) SafeMessage() string { + var buf bytes.Buffer + // Compute priority as a floating point number from 0-100 for readability. + floatPri := 100 * float64(t.Priority) / float64(math.MaxInt32) + if len(t.Name) > 0 { + fmt.Fprintf(&buf, "%q ", t.Name) + } + fmt.Fprintf(&buf, "id=%s rw=%t pri=%.8f stat=%s epo=%d "+ + "ts=%s orig=%s max=%s wto=%t seq=%d", + t.Short(), t.Writing, floatPri, t.Status, t.Epoch, t.Timestamp, + t.OrigTimestamp, t.MaxTimestamp, t.WriteTooOld, t.Sequence) + if ni := len(t.Intents); t.Status != PENDING && ni > 0 { + fmt.Fprintf(&buf, " int=%d", ni) + } + return buf.String() +} + // ResetObservedTimestamps clears out all timestamps recorded from individual // nodes. func (t *Transaction) ResetObservedTimestamps() {