diff --git a/.github/workflows/mamonsu-tests-dev.yml b/.github/workflows/mamonsu-tests-dev.yml index c259768..41f1f3b 100644 --- a/.github/workflows/mamonsu-tests-dev.yml +++ b/.github/workflows/mamonsu-tests-dev.yml @@ -45,6 +45,9 @@ jobs: - docker_os: 'ubuntu:24.04' pg_version: '16' zabbix_version: '6.4.13' + - docker_os: 'ubuntu:24.04' + pg_version: '18' + zabbix_version: '6.4.13' exclude: - docker_os: 'centos:8' pg_version: '12' diff --git a/.github/workflows/mamonsu-tests-master.yml b/.github/workflows/mamonsu-tests-master.yml index af22e98..d1a7943 100644 --- a/.github/workflows/mamonsu-tests-master.yml +++ b/.github/workflows/mamonsu-tests-master.yml @@ -45,6 +45,9 @@ jobs: - docker_os: 'ubuntu:24.04' pg_version: '16' zabbix_version: '6.4.13' + - docker_os: 'ubuntu:24.04' + pg_version: '18' + zabbix_version: '6.4.13' exclude: # excludes PG 15, 16 on CentOS - docker_os: 'centos:7' diff --git a/documentation/metrics.md b/documentation/metrics.md index d507a8e..ccdaebc 100644 --- a/documentation/metrics.md +++ b/documentation/metrics.md @@ -2374,6 +2374,69 @@ Default config: *Buffers Written During Checkpoints* maps `buffers_written`. +- **Done Checkpoints** + + Zabbix item: + + + + + + + + + + + + + + + + + + + + + + + + + +
NamePostgreSQL Checkpoints: Done (in hour)
Keypgsql.checkpoint[count_done]
TypeNumeric (float)
Units
DeltaSpeed Per Second
Supported Version18+
+ + *Done Checkpoints* maps `num_done`. + +- **SLRU Written** + + Zabbix item: + + + + + + + + + + + + + + + + + + + + + + + + + +
NamePostgreSQL Checkpoints: SLRU Written (in hour)
Keypgsql.checkpoint[slru_written]
TypeNumeric (float)
Units
DeltaSpeed Per Second
Supported Version18+
+ + *SLRU Written* maps `slru_written`. ### Graphs @@ -2920,6 +2983,70 @@ Default config: *Checksum Failures* maps `checksum_failures`. +- **Parallel Workers To Launch** + + Zabbix item: + + + + + + + + + + + + + + + + + + + + + + + + + +
NamePostgreSQL Instance: Parallel Workers To Launch
Keypgsql.parallel[instance_to_launch]
TypeNumeric (float)
Units
DeltaSimple Change
Supported Version18+
+ + *Parallel Workers To Launch* maps `parallel_workers_to_launch`. + +- **Parallel Workers Launched** + + Zabbix item: + + + + + + + + + + + + + + + + + + + + + + + + + +
NamePostgreSQL Instance: Parallel Workers Launched
Keypgsql.parallel[instance_launched]
TypeNumeric (float)
Units
DeltaSimple Change
Supported Version18+
+ + *Parallel Workers Launched* maps `parallel_workers_launched`. + ### Graphs @@ -4001,6 +4128,37 @@ Default config: *Amount of WAL Records* maps `wal_records`. +- **WAL Buffers Full** + + Zabbix item: +
+ + + + + + + + + + + + + + + + + + + + + + + + +
NamePostgreSQL Statements: WAL Buffers Full
Keypgsql.stat[wal_buffers_full]
TypeNumeric (float)
Units
DeltaSimple Change
Supported Version18+
+ + *WAL Buffers Full* maps `wal_buffers_full`. - **Dirty Bytes** @@ -4298,6 +4456,70 @@ Default config: *pg_stat_statements.max Exceeding Count* maps `dealloc`. +- **Parallel Workers To Launch** + + Zabbix item: + + + + + + + + + + + + + + + + + + + + + + + + + +
NamePostgreSQL Statements: Parallel Workers To Launch
Keypgsql.parallel[statements_to_launch]
TypeNumeric (float)
Units
DeltaSimple Change
Supported Version18+
+ + *Parallel Workers To Launch* maps `parallel_workers_to_launch`. + +- **Parallel Workers Launched** + + Zabbix item: + + + + + + + + + + + + + + + + + + + + + + + + + +
NamePostgreSQL Statements: Parallel Workers Launched
Keypgsql.parallel[statements_launched]
TypeNumeric (float)
Units
DeltaSimple Change
Supported Version18+
+ + *Parallel Workers Launched* maps `parallel_workers_launched`. + ### Graphs diff --git a/github-actions-tests/metrics.sh b/github-actions-tests/metrics.sh index 5ea6694..c7c37db 100644 --- a/github-actions-tests/metrics.sh +++ b/github-actions-tests/metrics.sh @@ -64,6 +64,7 @@ for metric in $(cat ${METRICS_FILE}); do GREP=$( mamonsu agent metric-get ${metric} | grep "pgsql\|sys\|mamonsu" ) if [ -z "$GREP" ]; then echo "---> ERROR: Cannot found metric $metric" + mamonsu agent metric-list exit 11 fi done diff --git a/github-actions-tests/sources/metrics-linux-18.txt b/github-actions-tests/sources/metrics-linux-18.txt new file mode 100644 index 0000000..3e0c098 --- /dev/null +++ b/github-actions-tests/sources/metrics-linux-18.txt @@ -0,0 +1,123 @@ +mamonsu.memory.rss[max] +mamonsu.plugin.errors[] +mamonsu.plugin.keepalive[] +pgsql.archive_command[archived_files] +pgsql.archive_command[count_files_to_archive] +pgsql.archive_command[failed_trying_to_archive] +pgsql.archive_command[size_files_to_archive] +pgsql.autovacuum.count[] +pgsql.autovacuum.utilization[] +pgsql.bgwriter[buffers_alloc] +pgsql.bgwriter[buffers_clean] +pgsql.bgwriter[maxwritten_clean] +pgsql.blocks[hit] +pgsql.blocks[read] +pgsql.checkpoint[checkpoint_sync_time] +pgsql.checkpoint[count_timed] +pgsql.checkpoint[count_wal] +pgsql.checkpoint[write_time] +pgsql.checkpoint[count_done] +pgsql.checkpoint[slru_written] +pgsql.connections[active] +pgsql.connections[disabled] +pgsql.connections[fastpath_function_call] +pgsql.connections[idle] +pgsql.connections[idle_in_transaction] +pgsql.connections[idle_in_transaction_aborted] +pgsql.connections[max_connections] +pgsql.connections[other] +pgsql.connections[total] +pgsql.connections[waiting] +pgsql.database.discovery[] +pgsql.database.bloating_tables[mamonsu_test_db] +pgsql.database.bloating_tables[postgres] +pgsql.database.invalid_indexes[mamonsu_test_db] +pgsql.database.invalid_indexes[postgres] +pgsql.database.max_age[mamonsu_test_db] +pgsql.database.max_age[postgres] +pgsql.database.size[mamonsu_test_db] +pgsql.database.size[postgres] +pgsql.events[checksum_failures] +pgsql.events[conflicts] +pgsql.events[deadlocks] +pgsql.events[xact_rollback] +pgsql.oldest[transaction_time] +pgsql.oldest[xid_age] +pgsql.ping[] +pgsql.pg_locks[accessexclusive] +pgsql.pg_locks[accessshare] +pgsql.pg_locks[exclusive] +pgsql.pg_locks[rowexclusive] +pgsql.pg_locks[rowshare] +pgsql.pg_locks[share] +pgsql.pg_locks[sharerowexclusive] +pgsql.pg_locks[shareupdateexclusive] +pgsql.parallel[instance_to_launch] +pgsql.parallel[instance_launched] +pgsql.parallel[queries] +pgsql.parallel[statements_to_launch] +pgsql.parallel[statements_launched] +pgsql.prepared.count +pgsql.prepared.oldest +pgsql.relation.size[] +pgsql.relation.size[mamonsu_test_db.mamonsu.config] +pgsql.relation.size[postgres.pg_catalog.pg_class] +pgsql.replication.non_active_slots[] +pgsql.replication_lag[sec] +pgsql.replication_lag[sec] +pgsql.stat[wal_buffers_full] +pgsql.temp[bytes] +pgsql.temp[files] +pgsql.transactions[committed] +pgsql.tuples[deleted] +pgsql.tuples[fetched] +pgsql.tuples[inserted] +pgsql.tuples[returned] +pgsql.tuples[updated] +pgsql.uptime[] +pgsql.wal.buffers_full[] +pgsql.wal.count[] +pgsql.wal.fpi.count[] +pgsql.wal.records.count[] +pgsql.wal.sync_time[] +pgsql.wal.write[] +pgsql.wal.write_time[] +system.cpu[idle] +system.cpu[iowait] +system.cpu[irq] +system.cpu[nice] +system.cpu[softirq] +system.cpu[system] +system.cpu[user] +system.disk.discovery[] +system.disk.all_read[] +system.disk.all_write[] +system.disk.all_read_b[] +system.disk.all_write_b[] +system.la[1] +system.memory[active] +system.memory[available] +system.memory[buffers] +system.memory[cached] +system.memory[committed] +system.memory[inactive] +system.memory[mapped] +system.memory[page_tables] +system.memory[slab] +system.memory[swap] +system.memory[swap_cache] +system.memory[total] +system.memory[vmalloc_used] +system.memory[unused] +system.memory[used] +system.net.discovery[] +system.open_files[] +system.processes[blocked] +system.processes[forkrate] +system.processes[running] +system.vfs.discovery[] +system.vfs.free[/] +system.vfs.percent_free[/] +system.vfs.percent_inode_free[/] +system.vfs.used[/] +system.uptime[] diff --git a/mamonsu/plugins/pgsql/checkpoint.py b/mamonsu/plugins/pgsql/checkpoint.py index c1ca9ac..bb663db 100644 --- a/mamonsu/plugins/pgsql/checkpoint.py +++ b/mamonsu/plugins/pgsql/checkpoint.py @@ -8,6 +8,7 @@ class Checkpoint(Plugin): AgentPluginType = "pg" Interval = 60 * 5 + FactorIndex = 6 key = "pgsql.checkpoint{0}" @@ -86,6 +87,18 @@ def __init__(self, config): ("PostgreSQL Checkpoints: Write/Sync", "FF5656", 1), Plugin.UNITS.ms, Plugin.DELTA.speed_per_second, 1) ] + if Pooler.server_version_greater("18"): + self.Items += [ + ("num_done", "count_done", + "Done (in hour)", + ("PostgreSQL Checkpoints: Done (in hour)", "00CC00", 0), + Plugin.UNITS.none, Plugin.DELTA.speed_per_second, 60 * 60), + + ("slru_written", "slru_written", + "SLRU Written (in hour)", + ("PostgreSQL Checkpoints: SLRU Written (in hour)", "00CC00", 0), + Plugin.UNITS.none, Plugin.DELTA.speed_per_second, 60 * 60) + ] def run(self, zbx): columns = [x[0] for x in self.Items] @@ -174,8 +187,8 @@ def triggers(self, template, dashboard=False): def keys_and_queries(self, template_zabbix): result = [] - for num, item in enumerate(self.Items): - if num > 1: + for item in self.Items: + if item[self.FactorIndex] == 1: result.append( "{0}[*],$2 $1 -c \"{1}\"".format(self.key.format("." + item[1]), self.query.format(item[0]))) else: diff --git a/mamonsu/plugins/pgsql/instance.py b/mamonsu/plugins/pgsql/instance.py index c0a3a9c..b7aa74c 100644 --- a/mamonsu/plugins/pgsql/instance.py +++ b/mamonsu/plugins/pgsql/instance.py @@ -68,6 +68,17 @@ class Instance(Plugin): ("PostgreSQL Instance: Events", "006AAE", 0), Plugin.UNITS.none, Plugin.DELTA.simple_change) ] + Items_pg_18 = [ + # key, zbx_key, description, + # ('graph name', color, side), units, delta + ("parallel_workers_to_launch", "parallel[instance_to_launch]", "", + ("PostgreSQL Instance: Parallel Workers To Launch", "00CC00", 0), + Plugin.UNITS.none, Plugin.DELTA.simple_change), + + ("parallel_workers_launched", "parallel[instance_launched]", "", + ("PostgreSQL Instance: Parallel Workers Launched", "00CC00", 0), + Plugin.UNITS.none, Plugin.DELTA.simple_change) + ] key_server_mode = "pgsql.server_mode{0}" query_server_mode = """ @@ -86,8 +97,9 @@ class Instance(Plugin): def run(self, zbx): all_items = self.Items if Pooler.server_version_greater("12.0"): - all_items = self.Items + self.Items_pg_12 - + all_items += self.Items_pg_12 + if Pooler.server_version_greater("18.0"): + all_items += self.Items_pg_18 columns = ["sum(COALESCE({0}, 0)) as {0}".format(x[0]) for x in all_items] result = Pooler.query(""" SELECT {0} @@ -102,7 +114,7 @@ def run(self, zbx): def items(self, template, dashboard=False): result = "" - for num, item in enumerate(self.Items + self.Items_pg_12): + for num, item in enumerate(self.Items + self.Items_pg_12 + self.Items_pg_18): if self.Type == "mamonsu": delta = Plugin.DELTA.as_is else: @@ -154,7 +166,7 @@ def graphs(self, template, dashboard=False): result = "" for name in self.graphs_name.values(): items = [] - for num, item in enumerate(self.Items + self.Items_pg_12): + for num, item in enumerate(self.Items + self.Items_pg_12 + self.Items_pg_18): if item[3][0] == name: # split each item to get values for keys of both agent type and mamonsu type keys = item[1].split("[") @@ -201,10 +213,11 @@ def triggers(self, template, dashboard=False): def keys_and_queries(self, template_zabbix): result = [] - if Pooler.server_version_less("11"): - all_items = self.Items - else: - all_items = self.Items + self.Items_pg_12 + all_items = self.Items + if Pooler.server_version_greater("12.0"): + all_items += self.Items_pg_12 + if Pooler.server_version_greater("18.0"): + all_items += self.Items_pg_18 for item in all_items: # split each item to get values for keys of both agent type and mamonsu type keys = item[1].split("[") diff --git a/mamonsu/plugins/pgsql/statements.py b/mamonsu/plugins/pgsql/statements.py index bab41ea..23783dd 100644 --- a/mamonsu/plugins/pgsql/statements.py +++ b/mamonsu/plugins/pgsql/statements.py @@ -88,6 +88,29 @@ class Statements(Plugin): ("PostgreSQL Statements Info: Last Statistics Reset Time", "9C8A4E", 0)) ] + Items_pg_18 = [ + ("parallel[statements_to_launch]", + "sum(parallel_workers_to_launch)", + "Number of parallel workers planned to be launched", + Plugin.UNITS.none, + Plugin.DELTA.simple_change, + ("PostgreSQL Statements: Parallel Workers To Launch", "87C2B9", 0)), + + ("parallel[statements_launched]", + "sum(parallel_workers_launched)", + "Number of parallel workers actually launched", + Plugin.UNITS.none, + Plugin.DELTA.simple_change, + ("PostgreSQL Statements: Parallel Workers Launched", "793F5D", 0)), + + ("stat[wal_buffers_full]", + "sum(wal_buffers_full)", + "Number of times the WAL buffers became full", + Plugin.UNITS.none, + Plugin.DELTA.simple_change, + ("PostgreSQL Statements: WAL Buffers Full", "9C8A4E", 0)), + ] + Items_pgpro_stats_1_8 = [ ("stat[read_bytes]", "(sum(shared_blks_read+local_blks_read+temp_blks_read)*8*1024)::bigint", @@ -168,6 +191,8 @@ def run(self, zbx): self.Items[3][1] = self.Items[3][1].format("blk_read_time") self.Items[4][1] = self.Items[4][1].format("blk_write_time") self.Items[5][1] = self.Items[5][1].format("total_exec_time+total_plan_time", "blk_read_time-blk_write_time") + if Pooler.server_version_greater("18"): + all_items += self.Items_pg_18 all_items += self.Items_pg_13 info_view = 'pgpro_stats_info' if self.extension == "pg_stat_statements": @@ -210,7 +235,7 @@ def items(self, template, dashboard=False): delta = Plugin.DELTA.as_is else: delta = Plugin.DELTA.speed_per_second - for item in self.Items + self.Items_pg_13 + self.Items_pg_14: + for item in self.Items + self.Items_pg_13 + self.Items_pg_14 + self.Items_pg_18: # split each item to get values for keys of both agent type and mamonsu type keys = item[0].split("[") result += template.item({ @@ -229,7 +254,7 @@ def graphs(self, template, dashboard=False): result = "" for graph_item in self.all_graphs: items = [] - for item in self.Items + self.Items_pg_13: + for item in self.Items + self.Items_pg_13 + self.Items_pg_18: if item[5][0] == graph_item[0]: keys = item[0].split("[") items.append({ @@ -271,6 +296,8 @@ def keys_and_queries(self, template_zabbix): self.Items[5][1] = self.Items[5][1].format("total_exec_time+total_plan_time") if Pooler.is_pgpro() or Pooler.is_pgpro_ee(): all_items += self.Items_pg_13 + if Pooler.server_version_greater("18"): + all_items += self.Items_pg_18 columns = [x[1] for x in all_items] @@ -287,6 +314,7 @@ def keys_and_queries(self, template_zabbix): extension_schema=extension_schema), i + 1)) + # Info view if Pooler.server_version_greater("14"): info_view = 'pgpro_stats_info' if self.extension == "pg_stat_statements":