Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions pkg/cli/cliflags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -1724,6 +1724,15 @@ necessary to support CockroachDB.
`,
}

ZipRedactLocally = FlagInfo{
Name: "redact-locally",
Description: `
Redact log files client-side instead of server-side.
When set, logs are fetched unredacted and redacted locally before
being written to the zip file.
`,
}

ZipIncludeRangeInfo = FlagInfo{
Name: "include-range-info",
Description: `
Expand Down
6 changes: 6 additions & 0 deletions pkg/cli/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,11 @@ type zipContext struct {
// range key data, which is necessary to support CockroachDB.
redact bool

// redactLocally indicates whether log redaction should happen client-side
// instead of server-side. This can help avoid memory issues on the server
// when processing large log files.
redactLocally bool

// Duration (in seconds) to run CPU profile for.
cpuProfDuration time.Duration

Expand Down Expand Up @@ -389,6 +394,7 @@ func setZipContextDefaults() {
zipCtx.files = fileSelection{}
zipCtx.redactLogs = false
zipCtx.redact = false
zipCtx.redactLocally = false
// Even though it makes debug.zip heavyweight, range infos are often the best source
// of information for range-level issues and so they are opt-out, not opt-in.
zipCtx.includeRangeInfo = true
Expand Down
1 change: 1 addition & 0 deletions pkg/cli/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,7 @@ func init() {
cliflagcfg.BoolFlag(f, &zipCtx.redactLogs, cliflags.ZipRedactLogs)
_ = f.MarkDeprecated(cliflags.ZipRedactLogs.Name, "use --"+cliflags.ZipRedact.Name+" instead")
cliflagcfg.BoolFlag(f, &zipCtx.redact, cliflags.ZipRedact)
cliflagcfg.BoolFlag(f, &zipCtx.redactLocally, cliflags.ZipRedactLocally)
cliflagcfg.DurationFlag(f, &zipCtx.cpuProfDuration, cliflags.ZipCPUProfileDuration)
cliflagcfg.IntFlag(f, &zipCtx.concurrency, cliflags.ZipConcurrency)
cliflagcfg.BoolFlag(f, &zipCtx.includeRangeInfo, cliflags.ZipIncludeRangeInfo)
Expand Down
2 changes: 1 addition & 1 deletion pkg/cli/zip_cluster_wide.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func (zc *debugZipContext) collectClusterData(

queryAndDumpTables := func(reg DebugZipTableRegistry) error {
for _, table := range reg.GetTables() {
query, err := reg.QueryForTable(table, zipCtx.redact)
query, err := reg.QueryForTable(table, zipCtx.redact || zipCtx.redactLocally)
if err != nil {
return err
}
Expand Down
10 changes: 7 additions & 3 deletions pkg/cli/zip_per_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ func (zc *debugZipContext) collectPerNodeData(
nodePrinter.info("using SQL connection URL: %s", curSQLConn.GetURL())

for _, table := range zipInternalTablesPerNode.GetTables() {
query, err := zipInternalTablesPerNode.QueryForTable(table, zipCtx.redact)
query, err := zipInternalTablesPerNode.QueryForTable(table, zipCtx.redact || zipCtx.redactLocally)
if err != nil {
return err
}
Expand Down Expand Up @@ -423,7 +423,7 @@ func (zc *debugZipContext) collectPerNodeData(
var err error
entries, err = zc.status.LogFile(
ctx, &serverpb.LogFileRequest{
NodeId: id, File: file.Name, Redact: zipCtx.redact,
NodeId: id, File: file.Name, Redact: zipCtx.redact && !zipCtx.redactLocally,
})
return err
}); requestErr != nil {
Expand Down Expand Up @@ -463,11 +463,15 @@ func (zc *debugZipContext) collectPerNodeData(
// most conservative way possible. (It's not great that
// possibly confidential data flew over the network, but
// at least it stops here.)
if zipCtx.redact && !e.Redactable {
if zipCtx.redact && !zipCtx.redactLocally && !e.Redactable {
e.Message = "REDACTEDBYZIP"
// We're also going to print a warning at the end.
warnRedactLeak = true
}
// Client-side redaction when --redact-locally is set.
if zipCtx.redactLocally {
log.RedactEntry(&e, log.WithoutSensitiveData)
}
if err := log.FormatLegacyEntry(e, logOut); err != nil {
return err
}
Expand Down
27 changes: 27 additions & 0 deletions pkg/util/log/redact.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"time"

"github.com/cockroachdb/cockroach/pkg/util/encoding/encodingtype"
"github.com/cockroachdb/cockroach/pkg/util/log/logpb"
"github.com/cockroachdb/errors"
"github.com/cockroachdb/redact"
)
Expand Down Expand Up @@ -133,6 +134,32 @@ func maybeRedactEntry(payload entryPayload, editor redactEditor) (res entryPaylo
return res
}

// RedactEntry applies redaction to a logpb.Entry in-place based on the given edit mode.
// This is useful for client-side redaction of log entries received from a server.
func RedactEntry(e *logpb.Entry, editMode EditSensitiveData) {
editor := getEditor(editMode)

// Redact the message.
msgPkg := redactablePackage{
msg: []byte(e.Message),
redactable: e.Redactable,
}
msgPkg = editor(msgPkg)
e.Message = string(msgPkg.msg)

// Redact the tags.
if len(e.Tags) > 0 {
tagsPkg := redactablePackage{
msg: []byte(e.Tags),
redactable: e.Redactable,
}
tagsPkg = editor(tagsPkg)
e.Tags = string(tagsPkg.msg)
}

e.Redactable = msgPkg.redactable
}

func init() {
// We consider booleans and numeric values to be always safe for
// reporting. A log call can opt out by using redact.Unsafe() around
Expand Down