Skip to content

Commit 292ccf4

Browse files
committed
database_observability: don't log query text if redaction is enabled
Do not log sql text in postgres collector when `disable_query_redaction` is false (the default). Additionally, don't log it if it is set to true for op=wait_event entries (not really needed). Clarify that the unredacted sql text _might_ include parameters.
1 parent cfc4715 commit 292ccf4

File tree

4 files changed

+107
-113
lines changed

4 files changed

+107
-113
lines changed

docs/sources/reference/components/database_observability/database_observability.postgres.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ You can use the following blocks with `database_observability.postgres`:
4949

5050
| Block | Description | Required |
5151
|------------------------------------|---------------------------------------------------|----------|
52-
| [`cloud_provider`][cloud_provider] | Provide Cloud Provider information. | no |
53-
| `cloud_provider` > [`aws`][aws] | Provide AWS database host information. | no |
52+
| [`cloud_provider`][cloud_provider] | Provide Cloud Provider information. | no |
53+
| `cloud_provider` > [`aws`][aws] | Provide AWS database host information. | no |
5454
| [`query_details`][query_details] | Configure the queries collector. | no |
5555
| [`query_samples`][query_samples] | Configure the query samples collector. | no |
5656
| [`schema_details`][schema_details] | Configure the schema and table details collector. | no |
@@ -92,8 +92,8 @@ The `aws` block supplies the [ARN](https://docs.aws.amazon.com/IAM/latest/UserGu
9292

9393
| Name | Type | Description | Default | Required |
9494
|---------------------------|------------|---------------------------------------------------------|---------|----------|
95-
| `collect_interval` | `duration` | How frequently to collect information from database. | `"15s"` | no |
96-
| `disable_query_redaction` | `bool` | Collect unredacted SQL query text including parameters. | `false` | no |
95+
| `collect_interval` | `duration` | How frequently to collect information from database. | `"15s"` | no |
96+
| `disable_query_redaction` | `bool` | Collect unredacted SQL query text (might include parameters). | `false` | no |
9797

9898
### `schema_details`
9999

internal/component/database_observability/mysql/collector/query_samples.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ func (c *QuerySamples) Name() string {
127127

128128
func (c *QuerySamples) Start(ctx context.Context) error {
129129
if c.disableQueryRedaction {
130-
level.Warn(c.logger).Log("msg", "collector started with query redaction disabled. Query samples will include complete SQL text including query parameters.")
130+
level.Warn(c.logger).Log("msg", "collector started with query redaction disabled. SQL text in query samples might include query parameters.")
131131
} else {
132132
level.Debug(c.logger).Log("msg", "collector started")
133133
}

internal/component/database_observability/postgres/collector/query_samples.go

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ const (
2424
)
2525

2626
const (
27-
stateActive = "active"
27+
queryTextClause = ", s.query"
28+
stateActive = "active"
2829
)
2930

3031
const selectPgStatActivity = `
@@ -48,16 +49,16 @@ const selectPgStatActivity = `
4849
s.wait_event,
4950
pg_blocking_pids(s.pid) as blocked_by_pids,
5051
s.query_start,
51-
s.query_id,
52-
s.query
52+
s.query_id
53+
%s
5354
FROM pg_stat_activity s
5455
JOIN pg_database d ON s.datid = d.oid AND NOT d.datistemplate AND d.datallowconn
5556
WHERE
5657
s.pid != pg_backend_pid() AND
5758
s.state != 'idle' AND
5859
(
5960
s.backend_type != 'client backend' OR
60-
(
61+
(
6162
coalesce(TRIM(s.query), '') != '' AND
6263
s.query_id != 0
6364
)
@@ -194,7 +195,11 @@ func (c *QuerySamples) Name() string {
194195
}
195196

196197
func (c *QuerySamples) Start(ctx context.Context) error {
197-
level.Debug(c.logger).Log("msg", "collector started")
198+
if c.disableQueryRedaction {
199+
level.Warn(c.logger).Log("msg", "collector started with query redaction disabled. SQL text in query samples might include query parameters.")
200+
} else {
201+
level.Debug(c.logger).Log("msg", "collector started")
202+
}
198203

199204
c.running.Store(true)
200205
ctx, cancel := context.WithCancel(ctx)
@@ -236,7 +241,13 @@ func (c *QuerySamples) Stop() {
236241
}
237242

238243
func (c *QuerySamples) fetchQuerySample(ctx context.Context) error {
239-
rows, err := c.dbConnection.QueryContext(ctx, selectPgStatActivity)
244+
queryTextField := ""
245+
if c.disableQueryRedaction {
246+
queryTextField = queryTextClause
247+
}
248+
249+
query := fmt.Sprintf(selectPgStatActivity, queryTextField)
250+
rows, err := c.dbConnection.QueryContext(ctx, query)
240251
if err != nil {
241252
return fmt.Errorf("failed to query pg_stat_activity: %w", err)
242253
}
@@ -279,7 +290,7 @@ func (c *QuerySamples) fetchQuerySample(ctx context.Context) error {
279290

280291
func (c *QuerySamples) scanRow(rows *sql.Rows) (QuerySamplesInfo, error) {
281292
sample := QuerySamplesInfo{}
282-
err := rows.Scan(
293+
scanArgs := []interface{}{
283294
&sample.Now,
284295
&sample.DatabaseName,
285296
&sample.PID,
@@ -300,8 +311,11 @@ func (c *QuerySamples) scanRow(rows *sql.Rows) (QuerySamplesInfo, error) {
300311
&sample.BlockedByPIDs,
301312
&sample.QueryStart,
302313
&sample.QueryID,
303-
&sample.Query,
304-
)
314+
}
315+
if c.disableQueryRedaction {
316+
scanArgs = append(scanArgs, &sample.Query)
317+
}
318+
err := rows.Scan(scanArgs...)
305319
return sample, err
306320
}
307321

@@ -314,8 +328,10 @@ func (c *QuerySamples) processRow(sample QuerySamplesInfo) (SampleKey, error) {
314328
}
315329

316330
func (c QuerySamples) validateQuerySample(sample QuerySamplesInfo) error {
317-
if sample.Query.Valid && sample.Query.String == "<insufficient privilege>" {
318-
return fmt.Errorf("insufficient privilege to access query. sample set: %+v", sample)
331+
if c.disableQueryRedaction {
332+
if sample.Query.Valid && sample.Query.String == "<insufficient privilege>" {
333+
return fmt.Errorf("insufficient privilege to access query. sample set: %+v", sample)
334+
}
319335
}
320336

321337
if !sample.DatabaseName.Valid {
@@ -426,13 +442,8 @@ func (c *QuerySamples) buildQuerySampleLabels(state *SampleState) string {
426442
}
427443
}
428444

429-
queryText := state.LastRow.Query.String
430-
if !c.disableQueryRedaction {
431-
queryText = redact(queryText)
432-
}
433-
434445
labels := fmt.Sprintf(
435-
`datname="%s" pid="%d" leader_pid="%s" user="%s" app="%s" client="%s" backend_type="%s" state="%s" xid="%d" xmin="%d" xact_time="%s" query_time="%s" queryid="%d" query="%s" engine="postgres"`,
446+
`datname="%s" pid="%d" leader_pid="%s" user="%s" app="%s" client="%s" backend_type="%s" state="%s" xid="%d" xmin="%d" xact_time="%s" query_time="%s" queryid="%d"`,
436447
state.LastRow.DatabaseName.String,
437448
state.LastRow.PID,
438449
leaderPID,
@@ -446,11 +457,13 @@ func (c *QuerySamples) buildQuerySampleLabels(state *SampleState) string {
446457
xactDuration,
447458
queryDuration,
448459
state.LastRow.QueryID.Int64,
449-
queryText,
450460
)
451461
if state.LastCpuTime != "" {
452462
labels = fmt.Sprintf(`%s cpu_time="%s"`, labels, state.LastCpuTime)
453463
}
464+
if c.disableQueryRedaction && state.LastRow.Query.Valid {
465+
labels = fmt.Sprintf(`%s query="%s"`, labels, state.LastRow.Query.String)
466+
}
454467
return labels
455468
}
456469

@@ -460,12 +473,8 @@ func (c *QuerySamples) buildWaitEventLabels(state *SampleState, we WaitEventOccu
460473
if state.LastRow.LeaderPID.Valid {
461474
leaderPID = fmt.Sprintf(`%d`, state.LastRow.LeaderPID.Int64)
462475
}
463-
queryText := state.LastRow.Query.String
464-
if !c.disableQueryRedaction {
465-
queryText = redact(queryText)
466-
}
467476
return fmt.Sprintf(
468-
`datname="%s" pid="%d" leader_pid="%s" user="%s" backend_type="%s" state="%s" xid="%d" xmin="%d" wait_time="%s" wait_event_type="%s" wait_event="%s" wait_event_name="%s" blocked_by_pids="%v" queryid="%d" query="%s" engine="postgres"`,
477+
`datname="%s" pid="%d" leader_pid="%s" user="%s" backend_type="%s" state="%s" xid="%d" xmin="%d" wait_time="%s" wait_event_type="%s" wait_event="%s" wait_event_name="%s" blocked_by_pids="%v" queryid="%d"`,
469478
state.LastRow.DatabaseName.String,
470479
state.LastRow.PID,
471480
leaderPID,
@@ -480,7 +489,6 @@ func (c *QuerySamples) buildWaitEventLabels(state *SampleState, we WaitEventOccu
480489
waitEventFullName,
481490
we.BlockedByPIDs,
482491
state.LastRow.QueryID.Int64,
483-
queryText,
484492
)
485493
}
486494

0 commit comments

Comments
 (0)