Skip to content
Merged
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
1 change: 1 addition & 0 deletions app/services/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ func (mp *metricspusher) Push(cred credential.Credential) error {
ReplicationLagSeconds: dbMetrics.ReplicationLagSeconds,
CacheHitRatio: dbMetrics.CacheHitRatio,
TransactionsPerSecond: dbMetrics.TransactionsPerSecond,
BlocksReadPerSecond: dbMetrics.BlocksReadPerSecond,
}

return mp.apiserver.PushPostgreSQLMetrics(ctx, combined, agentID)
Expand Down
1 change: 1 addition & 0 deletions domain/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ type PostgreSQLMetrics struct {
ReplicationLagSeconds int `json:"replication_lag_seconds"`
CacheHitRatio float64 `json:"cache_hit_ratio"`
TransactionsPerSecond float64 `json:"transactions_per_second"`
BlocksReadPerSecond float64 `json:"blocks_read_per_second"`
}
15 changes: 15 additions & 0 deletions internal/pgmetrics/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type DatabaseMetrics struct {
MaxConnections int
CacheHitRatio float64
TransactionsPerSecond float64
BlocksReadPerSecond float64
ReplicationLagSeconds int
}

Expand Down Expand Up @@ -113,6 +114,20 @@ func (pgm pgmetrics) collectDatabaseMetrics(ctx context.Context, db *sql.DB, m *
m.TransactionsPerSecond = 0
}

// Blocks read per second
blocksQuery := `
SELECT
COALESCE(ROUND(
sum(blks_read)::numeric /
NULLIF(EXTRACT(EPOCH FROM (now() - min(stats_reset))), 0)
, 2), 0) as blocks_read_per_sec
FROM pg_stat_database
WHERE stats_reset IS NOT NULL;
`
if err := db.QueryRowContext(ctx, blocksQuery).Scan(&m.BlocksReadPerSecond); err != nil {
m.BlocksReadPerSecond = 0
}

return nil
}

Expand Down
10 changes: 6 additions & 4 deletions internal/pgmetrics/collector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,17 +109,21 @@ func TestCollector_Collect(t *testing.T) {
// Verify connections are being tracked
assert.GreaterOrEqual(t, metrics.ConnectionsTotal, 1, "should have at least 1 connection")

// Verify max connections is set (default is typically 100)
assert.Greater(t, metrics.MaxConnections, 0, "max_connections should be greater than 0")

// Verify cache hit ratio is calculated (should be between 0 and 100)
assert.GreaterOrEqual(t, metrics.CacheHitRatio, 0.0)
assert.LessOrEqual(t, metrics.CacheHitRatio, 100.0)

// TPS might be 0 for a new database without stats_reset or very low activity
assert.GreaterOrEqual(t, metrics.TransactionsPerSecond, 0.0)

// Blocks read per second might be 0 for a new database without stats_reset
assert.GreaterOrEqual(t, metrics.BlocksReadPerSecond, 0.0)

// Replication lag should be 0 when no replication is configured
assert.Equal(t, 0, metrics.ReplicationLagSeconds)

t.Logf("Collected metrics: %+v", metrics)
}

func TestCollector_Collect_InvalidCredentials(t *testing.T) {
Expand Down Expand Up @@ -154,8 +158,6 @@ func TestCollector_Collect_CacheHitRatio(t *testing.T) {
// It should be high since we're reading the same data multiple times
assert.Greater(t, metrics.CacheHitRatio, 0.0,
"cache hit ratio should be greater than 0 after queries")

t.Logf("Cache hit ratio: %.2f%%", metrics.CacheHitRatio)
}

func TestCollector_Collect_Timeout(t *testing.T) {
Expand Down