Skip to content

Commit

Permalink
Postgresql/dbm screen metrics v102 (#86)
Browse files Browse the repository at this point in the history
* Added DBM metrics

* added tests
  • Loading branch information
naman47vyas authored Jul 5, 2024
1 parent f745d61 commit afb0585
Show file tree
Hide file tree
Showing 23 changed files with 3,008 additions and 49 deletions.
173 changes: 173 additions & 0 deletions receiver/postgresqlreceiver/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ type client interface {
getIndexStats(ctx context.Context, database string) (map[indexIdentifer]indexStat, error)
getActiveConnections(ctx context.Context) (int64, error)
listDatabases(ctx context.Context) ([]string, error)
getRowStats(ctx context.Context) ([]RowStats, error)
getQueryStats(ctx context.Context) ([]queryStats, error)
getBufferHit(ctx context.Context) ([]BufferHit, error)
getVersionString(ctx context.Context) (string, error)
}

type postgreSQLClient struct {
Expand Down Expand Up @@ -587,6 +591,175 @@ func (c *postgreSQLClient) getReplicationStats(ctx context.Context) ([]replicati
return rs, errors
}

type RowStats struct {
relationName string
rowsReturned int64
rowsFetched int64
rowsInserted int64
rowsUpdated int64
rowsDeleted int64
rowsHotUpdated int64
liveRows int64
deadRows int64
}

func (c *postgreSQLClient) getRowStats(ctx context.Context) ([]RowStats, error) {
query := `SELECT
relname,
pg_stat_get_tuples_returned(relid) AS rows_returned,
pg_stat_get_tuples_fetched(relid) AS rows_fetched,
pg_stat_get_tuples_inserted(relid) AS rows_inserted,
pg_stat_get_tuples_updated(relid) AS rows_updated,
pg_stat_get_tuples_deleted(relid) AS rows_deleted,
pg_stat_get_tuples_hot_updated(relid) AS rows_hot_updated,
pg_stat_get_live_tuples(relid) AS live_rows,
pg_stat_get_dead_tuples(relid) AS dead_rows
FROM
pg_stat_all_tables;
`

rows, err := c.client.QueryContext(ctx, query)
if err != nil {
return nil, fmt.Errorf("unable to query pg_stat_all_tables:: %w", err)
}

defer rows.Close()

var rs []RowStats
var errors error

for rows.Next() {
var (
relname sql.NullString
rowsReturned sql.NullInt64
rowsFetched sql.NullInt64
rowsInserted sql.NullInt64
rowsUpdated sql.NullInt64
rowsDeleted sql.NullInt64
rowsHotUpdated sql.NullInt64
liveRows sql.NullInt64
deadRows sql.NullInt64
)

err := rows.Scan(
&relname,
&rowsReturned,
&rowsFetched,
&rowsInserted,
&rowsUpdated,
&rowsDeleted,
&rowsHotUpdated,
&liveRows,
&deadRows,
)

if err != nil {
errors = multierr.Append(errors, err)
}

rs = append(rs, RowStats{
relname.String,
rowsReturned.Int64,
rowsFetched.Int64,
rowsInserted.Int64,
rowsUpdated.Int64,
rowsDeleted.Int64,
rowsHotUpdated.Int64,
liveRows.Int64,
deadRows.Int64,
})
}
return rs, nil
}

type queryStats struct {
queryId string
queryText string
queryCount int64
queryExecTime int64
}

func (c *postgreSQLClient) getQueryStats(ctx context.Context) ([]queryStats, error) {
query := `SELECT
queryid,
query,
calls,
total_exec_time
FROM pg_stat_statements;
`

rows, err := c.client.QueryContext(ctx, query)
if err != nil {
return nil, fmt.Errorf("unable to query pg_stat_statements: %w", err)
}
defer rows.Close()
var qs []queryStats
var errors error
for rows.Next() {
var queryId, queryText string
var queryCount int64
var queryExecTime float64
err = rows.Scan(&queryId, &queryText, &queryCount, &queryExecTime)
if err != nil {
errors = multierr.Append(errors, err)
}
queryExectimeNS := int64(queryExecTime * 1000000)
qs = append(qs, queryStats{
queryId: queryId,
queryText: queryText,
queryCount: queryCount,
queryExecTime: queryExectimeNS,
})
}
return qs, errors
}

type BufferHit struct {
dbName string
hits int64
}

func (c *postgreSQLClient) getBufferHit(ctx context.Context) ([]BufferHit, error) {
query := `SELECT datname, blks_hit FROM pg_stat_database;`

rows, err := c.client.QueryContext(ctx, query)
if err != nil {
return nil, fmt.Errorf("unable to query pg_stat_database:: %w", err)
}

defer rows.Close()

var bh []BufferHit
var errors error

for rows.Next() {
var dbname sql.NullString
var hits sql.NullInt64

err = rows.Scan(&dbname, &hits)

if err != nil {
errors = multierr.Append(errors, err)
continue
}
bh = append(bh, BufferHit{
dbName: dbname.String,
hits: hits.Int64,
})
}
return bh, errors
}

func (c *postgreSQLClient) getVersionString(ctx context.Context) (string, error) {
var version string
err := c.client.QueryRowContext(ctx, "SHOW server_version").Scan(&version)
if err != nil {
return "", fmt.Errorf("failed to get PostgreSQL version: %w", err)
}

return version, nil
}

func (c *postgreSQLClient) getLatestWalAgeSeconds(ctx context.Context) (int64, error) {
query := `SELECT
coalesce(last_archived_time, CURRENT_TIMESTAMP) AS last_archived_wal,
Expand Down
117 changes: 116 additions & 1 deletion receiver/postgresqlreceiver/documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,20 @@ The number of blocks read.
| ---- | ----------- | ------ |
| source | The block read source type. | Str: ``heap_read``, ``heap_hit``, ``idx_read``, ``idx_hit``, ``toast_read``, ``toast_hit``, ``tidx_read``, ``tidx_hit`` |
### postgresql.buffer_hit
The number of disk block hits in the buffer cache, thereby avoiding database reads, tagged with database name.
| Unit | Metric Type | Value Type |
| ---- | ----------- | ---------- |
| {hit}/s | Gauge | Int |
#### Attributes
| Name | Description | Values |
| ---- | ----------- | ------ |
| dbname | name of the database | Any Str |
### postgresql.commits
The number of commits.
Expand All @@ -114,7 +128,7 @@ Configured maximum number of client connections allowed
| Unit | Metric Type | Value Type |
| ---- | ----------- | ---------- |
| {connections} | Gauge | Int |
| {connection} | Gauge | Int |
### postgresql.database.count
Expand Down Expand Up @@ -148,6 +162,20 @@ The size of the index on disk.
| ---- | ----------- | ---------- |
| By | Gauge | Int |
### postgresql.live_rows
The approximate number of live rows, tagged with relation name.
| Unit | Metric Type | Value Type |
| ---- | ----------- | ---------- |
| {row} | Gauge | Int |
#### Attributes
| Name | Description | Values |
| ---- | ----------- | ------ |
| relation_name | name of the relation | Any Str |
### postgresql.operations
The number of db row operations.
Expand All @@ -162,6 +190,36 @@ The number of db row operations.
| ---- | ----------- | ------ |
| operation | The database operation. | Str: ``ins``, ``upd``, ``del``, ``hot_upd`` |
### postgresql.query.count
Number of times the statement was executed.
| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic |
| ---- | ----------- | ---------- | ----------------------- | --------- |
| 1 | Sum | Int | Cumulative | false |
#### Attributes
| Name | Description | Values |
| ---- | ----------- | ------ |
| query_text | Text of a representative statement | Any Str |
| query_id | Hash code to identify identical normalized queries. | Any Str |
### postgresql.query.total_exec_time
Total wait time of the normalised timed events in nanaoseconds.
| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic |
| ---- | ----------- | ---------- | ----------------------- | --------- |
| ns | Sum | Int | Cumulative | false |
#### Attributes
| Name | Description | Values |
| ---- | ----------- | ------ |
| query_text | Text of a representative statement | Any Str |
| query_id | Hash code to identify identical normalized queries. | Any Str |
### postgresql.replication.data_delay
The amount of data delayed in replication.
Expand Down Expand Up @@ -198,6 +256,62 @@ The number of rows in the database.
| ---- | ----------- | ------ |
| state | The tuple (row) state. | Str: ``dead``, ``live`` |
### postgresql.rows_deleted
Rows deleted by queries in this db, tagged with relation name.
| Unit | Metric Type | Value Type |
| ---- | ----------- | ---------- |
| {row}/s | Gauge | Int |
#### Attributes
| Name | Description | Values |
| ---- | ----------- | ------ |
| relation_name | name of the relation | Any Str |
### postgresql.rows_fetched
Rows fetched by queries in this db, tagged with relation name.
| Unit | Metric Type | Value Type |
| ---- | ----------- | ---------- |
| {row}/s | Gauge | Int |
#### Attributes
| Name | Description | Values |
| ---- | ----------- | ------ |
| relation_name | name of the relation | Any Str |
### postgresql.rows_inserted
Rows inserted by queries in the db, tagged with relation name.
| Unit | Metric Type | Value Type |
| ---- | ----------- | ---------- |
| {row}/s | Gauge | Int |
#### Attributes
| Name | Description | Values |
| ---- | ----------- | ------ |
| relation_name | name of the relation | Any Str |
### postgresql.rows_updated
Rows updated by queries in the db, tagged with relation name.
| Unit | Metric Type | Value Type |
| ---- | ----------- | ---------- |
| {row}/s | Gauge | Int |
#### Attributes
| Name | Description | Values |
| ---- | ----------- | ------ |
| relation_name | name of the relation | Any Str |
### postgresql.table.count
Number of user tables in a database.
Expand Down Expand Up @@ -324,6 +438,7 @@ This metric requires WAL to be enabled with at least one replica.
| Name | Description | Values | Enabled |
| ---- | ----------- | ------ | ------- |
| postgresql.database.name | The name of the database. | Any Str | true |
| postgresql.db.version | The version of postgresql databse | Any Str | true |
| postgresql.index.name | The name of the index on a table. | Any Str | true |
| postgresql.schema.name | The schema name. | Any Str | true |
| postgresql.table.name | The table name. | Any Str | true |
3 changes: 1 addition & 2 deletions receiver/postgresqlreceiver/generated_package_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit afb0585

Please sign in to comment.