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

[mysql] add dbms_flavor tag to tell if the database is mysql or mariadb #18950

Merged
merged 6 commits into from
Nov 1, 2024
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 mysql/changelog.d/18950.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added the `dbms_flavor` tag to MySQL integration metrics and events to identify the database type. This tag indicates whether the database is MySQL or MariaDB.
13 changes: 10 additions & 3 deletions mysql/datadog_checks/mysql/mysql.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,12 @@ def set_resource_tags(self):
)
)

def set_version_tags(self):
if not self.version or not self.version.flavor:
return

self.tags.append('dbms_flavor:{}'.format(self.version.flavor.lower()))

def _check_database_configuration(self, db):
self._check_performance_schema_enabled(db)
self._check_events_wait_current_enabled(db)
Expand Down Expand Up @@ -274,7 +280,6 @@ def check(self, _):
if self.instance.get('pass'):
self._log_deprecation('_config_renamed', 'pass', 'password')

tags = list(self.tags)
self._set_qcache_stats()
try:
with self._connect() as db:
Expand All @@ -283,11 +288,12 @@ def check(self, _):
# Update tag set with relevant information
if self._get_is_aurora(db):
aurora_tags = self._get_runtime_aurora_tags(db)
self.tags = tags + aurora_tags
self.tags = list(set(self.tags) | set(aurora_tags))
self._non_internal_tags = self._set_database_instance_tags(aurora_tags)

# version collection
self.version = get_version(db)
self.set_version_tags()
self._send_metadata()
self._send_database_instance_metadata()

Expand All @@ -299,6 +305,7 @@ def check(self, _):
self.check_userstat_enabled(db)

# Metric collection
tags = copy.deepcopy(self.tags)
if not self._config.only_custom_queries:
self._collect_metrics(db, tags=tags)
self._collect_system_metrics(self._config.host, db, tags)
Expand Down Expand Up @@ -676,7 +683,7 @@ def _collect_group_replica_metrics(self, db, results):
self.service_check(
self.GROUP_REPLICATION_SERVICE_CHECK_NAME,
status=status,
tags=self._service_check_tags() + additional_tags,
tags=self.service_check_tags + additional_tags,
)

metrics_to_fetch = SQL_GROUP_REPLICATION_METRICS_8_0_2 if above_802 else SQL_GROUP_REPLICATION_METRICS
Expand Down
1 change: 1 addition & 0 deletions mysql/tests/tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
'tag1:value1',
'tag2:value2',
DATABASE_INSTANCE_RESOURCE_TAG.format(hostname='stubbed.hostname'),
'dbms_flavor:{}'.format(common.MYSQL_FLAVOR.lower()),
]
SC_TAGS = [
'port:' + str(common.PORT),
Expand Down
1 change: 1 addition & 0 deletions mysql/tests/test_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,7 @@ def test_collect_schemas(aggregator, dd_run_check, dbm_instance):
assert schema_event.get("dbms_version") is not None
assert (schema_event.get("flavor") == "MariaDB") or (schema_event.get("flavor") == "MySQL")
assert sorted(schema_event["tags"]) == [
'dbms_flavor:{}'.format(common.MYSQL_FLAVOR.lower()),
'dd.internal.resource:database_instance:stubbed.hostname',
'port:13306',
'tag1:value1',
Expand Down
5 changes: 2 additions & 3 deletions mysql/tests/test_mysql.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
# Licensed under a 3-clause BSD style license (see LICENSE)
import copy
import logging
from os import environ

import mock
import pytest
Expand Down Expand Up @@ -118,7 +117,7 @@ def test_e2e(dd_agent_check, dd_default_hostname, instance_complex):
_assert_complex_config(
aggregator,
tags.SC_TAGS + [tags.DATABASE_INSTANCE_RESOURCE_TAG.format(hostname=dd_default_hostname)],
tags.METRIC_TAGS,
tags.METRIC_TAGS + ['dbms_flavor:{}'.format(MYSQL_FLAVOR.lower())],
hostname=dd_default_hostname,
e2e=True,
)
Expand Down Expand Up @@ -313,7 +312,7 @@ def test_complex_config_replica(aggregator, dd_run_check, instance_complex):
+ variables.REPLICATION_OPERATION_TIME_METRICS
)

if MYSQL_VERSION_PARSED >= parse_version('5.6') and environ.get('MYSQL_FLAVOR') != 'mariadb':
if MYSQL_VERSION_PARSED >= parse_version('5.6') and MYSQL_FLAVOR != 'mariadb':
testable_metrics.extend(variables.PERFORMANCE_VARS + variables.COMMON_PERFORMANCE_VARS)
operation_time_metrics.extend(
variables.COMMON_PERFORMANCE_OPERATION_TIME_METRICS + variables.PERFORMANCE_OPERATION_TIME_METRICS
Expand Down
22 changes: 13 additions & 9 deletions mysql/tests/test_query_activity.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from contextlib import closing
from copy import copy
from datetime import datetime
from os import environ
from threading import Event

import mock
Expand All @@ -23,7 +22,7 @@
from datadog_checks.mysql.activity import MySQLActivity
from datadog_checks.mysql.util import StatementTruncationState

from .common import CHECK_NAME, HOST, MYSQL_VERSION_PARSED, PORT
from .common import CHECK_NAME, HOST, MYSQL_FLAVOR, MYSQL_VERSION_PARSED, PORT

ACTIVITY_JSON_PLANS_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "activity")

Expand Down Expand Up @@ -59,7 +58,7 @@ def dbm_instance(instance_complex):
'SELECT id, name FROM testdb.users FOR UPDATE',
(
'4d09873d44c33af7'
if MYSQL_VERSION_PARSED > parse_version('5.7') and environ.get('MYSQL_FLAVOR') != 'mariadb'
if MYSQL_VERSION_PARSED > parse_version('5.7') and MYSQL_FLAVOR != 'mariadb'
else 'aca1be410fbadb61'
),
StatementTruncationState.not_truncated.value,
Expand All @@ -70,7 +69,7 @@ def dbm_instance(instance_complex):
),
(
'4a12d7afe06cf40'
if environ.get('MYSQL_FLAVOR') == 'mariadb'
if MYSQL_FLAVOR == 'mariadb'
else ('da7d6b1e9deb88e' if MYSQL_VERSION_PARSED > parse_version('5.7') else '63bd1fd025c7f7fb')
),
StatementTruncationState.truncated.value,
Expand Down Expand Up @@ -113,7 +112,12 @@ def _run_blocking(conn):
assert activity['dbm_type'] == 'activity'
assert activity['ddsource'] == 'mysql'
assert activity['ddagentversion'], "missing agent version"
assert set(activity['ddtags']) == {'tag1:value1', 'tag2:value2', 'port:13306'}
assert set(activity['ddtags']) == {
'tag1:value1',
'tag2:value2',
'port:13306',
'dbms_flavor:{}'.format(MYSQL_FLAVOR.lower()),
}
assert type(activity['collection_interval']) in (float, int), "invalid collection_interval"

assert activity['mysql_activity'], "should have at least one activity row"
Expand All @@ -132,8 +136,7 @@ def _run_blocking(conn):
# sql text length limits
expected_sql_text = (
query[:1021] + '...'
if len(query) > 1024
and (MYSQL_VERSION_PARSED == parse_version('5.6') or environ.get('MYSQL_FLAVOR') == 'mariadb')
if len(query) > 1024 and (MYSQL_VERSION_PARSED == parse_version('5.6') or MYSQL_FLAVOR == 'mariadb')
else query[:4093] + '...' if len(query) > 4096 else query
)
assert blocked_row['sql_text'] == expected_sql_text
Expand Down Expand Up @@ -193,7 +196,7 @@ def test_activity_metadata(aggregator, dd_run_check, dbm_instance, datadog_agent
"""
query_signature = (
'4d09873d44c33af7'
if MYSQL_VERSION_PARSED > parse_version('5.7') and environ.get('MYSQL_FLAVOR') != 'mariadb'
if MYSQL_VERSION_PARSED > parse_version('5.7') and MYSQL_FLAVOR != 'mariadb'
else 'e7f7cb251194df29'
)

Expand Down Expand Up @@ -525,6 +528,7 @@ def _expected_dbm_job_err_tags(dbm_instance):
'job:query-activity',
'port:{}'.format(PORT),
'dd.internal.resource:database_instance:stubbed.hostname',
'dbms_flavor:{}'.format(MYSQL_FLAVOR.lower()),
]


Expand All @@ -539,7 +543,7 @@ def test_if_deadlock_metric_is_collected(aggregator, dd_run_check, dbm_instance)


@pytest.mark.skipif(
environ.get('MYSQL_FLAVOR') == 'mariadb' or MYSQL_VERSION_PARSED < parse_version('8.0'),
MYSQL_FLAVOR == 'mariadb' or MYSQL_VERSION_PARSED < parse_version('8.0'),
reason='Deadock count is not updated in MariaDB or older MySQL versions',
)
@pytest.mark.integration
Expand Down
9 changes: 7 additions & 2 deletions mysql/tests/test_statements.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from datadog_checks.mysql.statement_samples import StatementTruncationState

from . import common
from .common import MYSQL_VERSION_PARSED
from .common import MYSQL_FLAVOR, MYSQL_VERSION_PARSED

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -853,7 +853,11 @@ def test_async_job_cancel(aggregator, dd_run_check, dbm_instance):


def _expected_dbm_instance_tags(dbm_instance):
return dbm_instance.get('tags', []) + ['server:{}'.format(common.HOST), 'port:{}'.format(common.PORT)]
return dbm_instance.get('tags', []) + [
'server:{}'.format(common.HOST),
'port:{}'.format(common.PORT),
'dbms_flavor:{}'.format(MYSQL_FLAVOR.lower()),
Comment on lines +856 to +859
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it better to use f"" formatting? it's a little bit less verbose.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

f"" is more concise. i use the same .format syntax for consistency. we used .format in the past because f"" is python3 only. it's no longer a concern now.

]


# the inactive job metrics are emitted from the main integrations
Expand All @@ -863,6 +867,7 @@ def _expected_dbm_job_err_tags(dbm_instance):
'port:{}'.format(common.PORT),
'server:{}'.format(common.HOST),
'dd.internal.resource:database_instance:stubbed.hostname',
'dbms_flavor:{}'.format(common.MYSQL_FLAVOR.lower()),
]


Expand Down
Loading