Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add deadlocks monotonic count metric #13374

Merged
merged 20 commits into from
Dec 1, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
Prev Previous commit
Next Next commit
DBM-790 WIP deadlock.count metric with QueryExecutor
  • Loading branch information
nenadnoveljic committed Nov 22, 2022
commit 09cec506effbdcff9995cce8c191776bfc28fc0c
54 changes: 53 additions & 1 deletion postgres/datadog_checks/postgres/postgres.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from six import iteritems

from datadog_checks.base import AgentCheck
from datadog_checks.base.utils.db import QueryExecutor
from datadog_checks.base.utils.db.utils import resolve_db_host as agent_host_resolver
from datadog_checks.postgres.metrics_cache import PostgresMetricsCache
from datadog_checks.postgres.relationsmanager import INDEX_BLOAT, RELATION_METRICS, TABLE_BLOAT, RelationsManager
Expand All @@ -21,12 +22,13 @@
from .util import (
CONNECTION_METRICS,
FUNCTION_METRICS,
QUERY_PG_STAT_DATABASE,
REPLICATION_METRICS,
DatabaseConfigurationError,
fmt,
get_schema_field,
)
from .version_utils import V9, V10, VersionUtils
from .version_utils import V9, V9_2, V10, VersionUtils

try:
import datadog_agent
Expand Down Expand Up @@ -72,6 +74,53 @@ def __init__(self, name, init_config, instances):
self._db_pool = {}
self._db_pool_lock = threading.Lock()

self.tags = copy.copy(self._config.tags)
self.tags=[t for t in self.tags if not t.startswith("db:")]
if self._config.tag_replication_role:
self.tags.extend(["replication_role:{}".format(self._get_replication_role())])

self._dynamic_queries = None

def _new_query_executor(self, queries):
return QueryExecutor(
self.execute_query_raw,
self,
queries=queries,
tags=self.tags,
hostname=self.resolved_hostname,
)

def execute_query_raw(self, query):
with self.db.cursor() as cursor:
cursor.execute(query)
return cursor.fetchall()

@property
def dynamic_queries(self):
if self._dynamic_queries:
return self._dynamic_queries

queries = []
if self.version >= V9_2:
QUERY_PG_STAT_DATABASE["query"] += " WHERE " + " AND ".join(
"datname not ilike '{}'".format(db) for db in self._config.ignore_databases
)

if self._config.dbstrict:
QUERY_PG_STAT_DATABASE["query"] += " AND datname in('{}')".format(self._config.dbname)

queries.extend([QUERY_PG_STAT_DATABASE])

if not queries:
self.log.debug("no dynamic queries defined")
return None

self._dynamic_queries = self._new_query_executor(queries)
self._dynamic_queries.compile_queries()
self.log.debug("initialized dynamic queries")

return self._dynamic_queries

def cancel(self):
self.statement_samples.cancel()
self.statement_metrics.cancel()
Expand Down Expand Up @@ -358,6 +407,9 @@ def _collect_stats(self, instance_tags):
for scope in list(metric_scope) + self._config.custom_metrics:
self._query_scope(cursor, scope, instance_tags, scope in self._config.custom_metrics)

if self.dynamic_queries:
self.dynamic_queries.execute()

cursor.close()

def _new_connection(self, dbname):
Expand Down
16 changes: 14 additions & 2 deletions postgres/datadog_checks/postgres/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,24 @@ def get_schema_field(descriptors):

NEWER_92_METRICS = {
'deadlocks': ('postgresql.deadlocks', AgentCheck.rate),
'deadlocks deadlocks_count': ('postgresql.deadlocks.count', AgentCheck.monotonic_count),
'deadlocks deadlocks_total': ('postgresql.deadlocks.total', AgentCheck.count),
'temp_bytes': ('postgresql.temp_bytes', AgentCheck.rate),
'temp_files': ('postgresql.temp_files', AgentCheck.rate),
}

QUERY_PG_STAT_DATABASE = {
'name': 'pg_stat_database',
'query': """
SELECT
datname,
deadlocks
FROM pg_stat_database
""".strip(),
'columns': [
{'name': 'db', 'type': 'tag'},
{'name': 'postgres.deadlocks.count', 'type': 'monotonic_count'},
],
}

COMMON_BGW_METRICS = {
'checkpoints_timed': ('postgresql.bgwriter.checkpoints_timed', AgentCheck.monotonic_count),
'checkpoints_req': ('postgresql.bgwriter.checkpoints_requested', AgentCheck.monotonic_count),
Expand Down
3 changes: 1 addition & 2 deletions postgres/tests/test_deadlock.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,8 @@ def wait_on_result(cursor = None, sql = None, binds = None, expected_value = Non

@pytest.mark.e2e
def test_deadlock(aggregator, dd_run_check, integration_check, pg_instance):
#aggregator = dd_agent_check(pg_instance, rate=True)
check = integration_check(pg_instance)
#dd_run_check(check)

check._connect()

cursor = check.db.cursor()
Expand Down