Skip to content

Commit 87b8cac

Browse files
committed
Dynamic statement length.
Signed-off-by: Jakub Štiller <[email protected]>
1 parent 9e2e4a0 commit 87b8cac

File tree

3 files changed

+33
-19
lines changed

3 files changed

+33
-19
lines changed

collector/collector.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ const (
3737
// Namespace for all metrics.
3838
namespace = "pg"
3939

40-
defaultEnabled = true
41-
defaultDisabled = false
40+
collectorFlagPrefix = "collector."
41+
defaultEnabled = true
42+
defaultDisabled = false
4243
)
4344

4445
var (
@@ -74,7 +75,7 @@ func registerCollector(name string, isDefaultEnabled bool, createFunc func(colle
7475
}
7576

7677
// Create flag for this collector
77-
flagName := fmt.Sprintf("collector.%s", name)
78+
flagName := fmt.Sprint(collectorFlagPrefix, name)
7879
flagHelp := fmt.Sprintf("Enable the %s collector (default: %s).", name, helpDefaultState)
7980
defaultValue := fmt.Sprintf("%v", isDefaultEnabled)
8081

collector/pg_stat_statements.go

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,29 +26,40 @@ import (
2626

2727
const statStatementsSubsystem = "stat_statements"
2828

29-
var includeQueryFlag *bool = nil
29+
var (
30+
includeQueryFlag *bool = nil
31+
statementLengthFlag *uint = nil
32+
)
3033

3134
func init() {
3235
// WARNING:
3336
// Disabled by default because this set of metrics can be quite expensive on a busy server
3437
// Every unique query will cause a new timeseries to be created
3538
registerCollector(statStatementsSubsystem, defaultDisabled, NewPGStatStatementsCollector)
3639

37-
flagName := fmt.Sprintf("collector.%s.include_query", statStatementsSubsystem)
38-
flagHelp := "Enable selecting statement query together with queryId. (default: false)"
39-
defaultValue := fmt.Sprintf("%v", defaultDisabled)
40-
includeQueryFlag = kingpin.Flag(flagName, flagHelp).Default(defaultValue).Bool()
40+
includeQueryFlag = kingpin.Flag(
41+
fmt.Sprint(collectorFlagPrefix, statStatementsSubsystem, ".include_query"),
42+
"Enable selecting statement query together with queryId. (default: disabled)").
43+
Default(fmt.Sprintf("%v", defaultDisabled)).
44+
Bool()
45+
statementLengthFlag = kingpin.Flag(
46+
fmt.Sprint(collectorFlagPrefix, statStatementsSubsystem, ".query_length"),
47+
"Maximum length of the statement text.").
48+
Default("120").
49+
Uint()
4150
}
4251

4352
type PGStatStatementsCollector struct {
4453
log *slog.Logger
4554
includeQueryStatement bool
55+
statementLength uint
4656
}
4757

4858
func NewPGStatStatementsCollector(config collectorConfig) (Collector, error) {
4959
return &PGStatStatementsCollector{
5060
log: config.logger,
5161
includeQueryStatement: *includeQueryFlag,
62+
statementLength: *statementLengthFlag,
5263
}, nil
5364
}
5465

@@ -90,8 +101,10 @@ var (
90101
[]string{"queryid", "query"},
91102
prometheus.Labels{},
92103
)
104+
)
93105

94-
pgStatStatementQuerySelect = "LEFT(pg_stat_statements.query, 120) as query,"
106+
const (
107+
pgStatStatementQuerySelect = `LEFT(pg_stat_statements.query, %d) as query,`
95108

96109
pgStatStatementsQuery = `SELECT
97110
pg_get_userbyid(userid) as user,
@@ -172,7 +185,7 @@ func (c PGStatStatementsCollector) Update(ctx context.Context, instance *instanc
172185
}
173186
var querySelect = ""
174187
if c.includeQueryStatement {
175-
querySelect = pgStatStatementQuerySelect
188+
querySelect = fmt.Sprintf(pgStatStatementQuerySelect, c.statementLength)
176189
}
177190
query := fmt.Sprintf(queryTemplate, querySelect)
178191

collector/pg_stat_statements_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,15 @@ func TestPGStateStatementsCollectorWithStatement(t *testing.T) {
7676

7777
inst := &instance{db: db, version: semver.MustParse("12.0.0")}
7878

79-
columns := []string{"user", "datname", "queryid", "query", "calls_total", "seconds_total", "rows_total", "block_read_seconds_total", "block_write_seconds_total"}
79+
columns := []string{"user", "datname", "queryid", "LEFT(pg_stat_statements.query, 100) as query", "calls_total", "seconds_total", "rows_total", "block_read_seconds_total", "block_write_seconds_total"}
8080
rows := sqlmock.NewRows(columns).
8181
AddRow("postgres", "postgres", 1500, "select 1 from foo", 5, 0.4, 100, 0.1, 0.2)
82-
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery, pgStatStatementQuerySelect))).WillReturnRows(rows)
82+
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsQuery, fmt.Sprintf(pgStatStatementQuerySelect, 100)))).WillReturnRows(rows)
8383

8484
ch := make(chan prometheus.Metric)
8585
go func() {
8686
defer close(ch)
87-
c := PGStatStatementsCollector{includeQueryStatement: true}
87+
c := PGStatStatementsCollector{includeQueryStatement: true, statementLength: 100}
8888

8989
if err := c.Update(context.Background(), inst, ch); err != nil {
9090
t.Errorf("Error calling PGStatStatementsCollector.Update: %s", err)
@@ -163,15 +163,15 @@ func TestPGStateStatementsCollectorNullWithStatement(t *testing.T) {
163163

164164
inst := &instance{db: db, version: semver.MustParse("13.3.7")}
165165

166-
columns := []string{"user", "datname", "queryid", "query", "calls_total", "seconds_total", "rows_total", "block_read_seconds_total", "block_write_seconds_total"}
166+
columns := []string{"user", "datname", "queryid", "LEFT(pg_stat_statements.query, 200) as query", "calls_total", "seconds_total", "rows_total", "block_read_seconds_total", "block_write_seconds_total"}
167167
rows := sqlmock.NewRows(columns).
168168
AddRow(nil, nil, nil, nil, nil, nil, nil, nil, nil)
169-
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsNewQuery, pgStatStatementQuerySelect))).WillReturnRows(rows)
169+
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsNewQuery, fmt.Sprintf(pgStatStatementQuerySelect, 200)))).WillReturnRows(rows)
170170

171171
ch := make(chan prometheus.Metric)
172172
go func() {
173173
defer close(ch)
174-
c := PGStatStatementsCollector{includeQueryStatement: true}
174+
c := PGStatStatementsCollector{includeQueryStatement: true, statementLength: 200}
175175

176176
if err := c.Update(context.Background(), inst, ch); err != nil {
177177
t.Errorf("Error calling PGStatStatementsCollector.Update: %s", err)
@@ -250,15 +250,15 @@ func TestPGStateStatementsCollectorNewPGWithStatement(t *testing.T) {
250250

251251
inst := &instance{db: db, version: semver.MustParse("13.3.7")}
252252

253-
columns := []string{"user", "datname", "queryid", "query", "calls_total", "seconds_total", "rows_total", "block_read_seconds_total", "block_write_seconds_total"}
253+
columns := []string{"user", "datname", "queryid", "LEFT(pg_stat_statements.query, 300) as query", "calls_total", "seconds_total", "rows_total", "block_read_seconds_total", "block_write_seconds_total"}
254254
rows := sqlmock.NewRows(columns).
255255
AddRow("postgres", "postgres", 1500, "select 1 from foo", 5, 0.4, 100, 0.1, 0.2)
256-
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsNewQuery, pgStatStatementQuerySelect))).WillReturnRows(rows)
256+
mock.ExpectQuery(sanitizeQuery(fmt.Sprintf(pgStatStatementsNewQuery, fmt.Sprintf(pgStatStatementQuerySelect, 300)))).WillReturnRows(rows)
257257

258258
ch := make(chan prometheus.Metric)
259259
go func() {
260260
defer close(ch)
261-
c := PGStatStatementsCollector{includeQueryStatement: true}
261+
c := PGStatStatementsCollector{includeQueryStatement: true, statementLength: 300}
262262

263263
if err := c.Update(context.Background(), inst, ch); err != nil {
264264
t.Errorf("Error calling PGStatStatementsCollector.Update: %s", err)

0 commit comments

Comments
 (0)