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

Change DBM statement config keys and metric terminology to query #9661

Merged
merged 2 commits into from
Jul 9, 2021
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
24 changes: 12 additions & 12 deletions mysql/assets/configuration/spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -245,43 +245,43 @@ files:
type: boolean
example: false
display_default: false
- name: statement_metrics
description: Configure collection of statement metrics
- name: query_metrics
description: Configure collection of query metrics
options:
- name: enabled
description: |
Enable collection of statement metrics. Requires `dbm: true`.
Enable collection of query metrics. Requires `dbm: true`.
value:
type: boolean
example: true
- name: collection_interval
description: |
Set the statement metric collection interval (in seconds). Each collection involves a single query to
Set the query metric collection interval (in seconds). Each collection involves a single query to
`pg_stat_statements`. If a non-default value is chosen then that exact same value must be used for *every*
check instance. Running different instances with different collection intervals is not supported.
value:
type: number
example: 10
- name: statement_samples
description: Configure collection of statement samples
- name: query_samples
description: Configure collection of query samples
options:
- name: enabled
description: |
Enables collection of statement samples. Requires `dbm: true`.
Enables collection of query samples. Requires `dbm: true`.
value:
type: boolean
example: true
- name: collection_interval
description: |
Sets the statement sample collection interval (in seconds). Each collection involves a single query to one
Sets the query sample collection interval (in seconds). Each collection involves a single query to one
of the `performance_schema.events_statements_*` tables, followed by at most one `EXPLAIN` query per
unique statement seen.
value:
type: number
example: 1
- name: explained_statements_per_hour_per_query
- name: explained_queries_per_hour_per_query
description: |
Sets the rate limit for how many execution plans will be collected per hour per normalized statement.
Sets the rate limit for how many execution plans will be collected per hour per normalized query.
value:
type: integer
example: 60
Expand All @@ -292,9 +292,9 @@ files:
value:
type: integer
example: 15
- name: explained_statements_cache_maxsize
- name: explained_queries_cache_maxsize
description: |
Sets the max size of the cache used for the explained_statements_per_hour_per_query rate limit. This
Sets the max size of the cache used for the explained_queries_per_hour_per_query rate limit. This
should be increased for databases with a very large number of unique normalized queries which exceed the
cache's limit.
value:
Expand Down
4 changes: 2 additions & 2 deletions mysql/datadog_checks/mysql/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ def __init__(self, instance):
self.full_statement_text_samples_per_hour_per_query = instance.get(
'full_statement_text_samples_per_hour_per_query', 1
)
self.statement_samples_config = instance.get('statement_samples', {}) or {}
self.statement_metrics_config = instance.get('statement_metrics', {}) or {}
self.statement_samples_config = instance.get('query_samples', instance.get('statement_samples', {})) or {}
self.statement_metrics_config = instance.get('query_metrics', {}) or {}
self.min_collection_interval = instance.get('min_collection_interval', 15)
self.configuration_checks()

Expand Down
10 changes: 5 additions & 5 deletions mysql/datadog_checks/mysql/config_models/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,23 +64,23 @@ def instance_queries(field, value):
return get_default_field_value(field, value)


def instance_service(field, value):
def instance_query_metrics(field, value):
return get_default_field_value(field, value)


def instance_sock(field, value):
def instance_query_samples(field, value):
return get_default_field_value(field, value)


def instance_ssl(field, value):
def instance_service(field, value):
return get_default_field_value(field, value)


def instance_statement_metrics(field, value):
def instance_sock(field, value):
return get_default_field_value(field, value)


def instance_statement_samples(field, value):
def instance_ssl(field, value):
return get_default_field_value(field, value)


Expand Down
30 changes: 15 additions & 15 deletions mysql/datadog_checks/mysql/config_models/instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,24 +37,15 @@ class Config:
schema_size_metrics: Optional[bool]


class Ssl(BaseModel):
class Config:
allow_mutation = False

ca: Optional[str]
cert: Optional[str]
key: Optional[str]


class StatementMetrics(BaseModel):
class QueryMetrics(BaseModel):
class Config:
allow_mutation = False

collection_interval: Optional[float]
enabled: Optional[bool]


class StatementSamples(BaseModel):
class QuerySamples(BaseModel):
class Config:
allow_mutation = False

Expand All @@ -67,13 +58,22 @@ class Config:
events_statements_table: Optional[str]
events_statements_temp_table_name: Optional[str]
explain_procedure: Optional[str]
explained_statements_cache_maxsize: Optional[int]
explained_statements_per_hour_per_query: Optional[int]
explained_queries_cache_maxsize: Optional[int]
explained_queries_per_hour_per_query: Optional[int]
fully_qualified_explain_procedure: Optional[str]
samples_per_hour_per_query: Optional[int]
seen_samples_cache_maxsize: Optional[int]


class Ssl(BaseModel):
class Config:
allow_mutation = False

ca: Optional[str]
cert: Optional[str]
key: Optional[str]


class InstanceConfig(BaseModel):
class Config:
allow_mutation = False
Expand All @@ -91,11 +91,11 @@ class Config:
password: Optional[str]
port: Optional[float]
queries: Optional[Sequence[Mapping[str, Any]]]
query_metrics: Optional[QueryMetrics]
query_samples: Optional[QuerySamples]
service: Optional[str]
sock: Optional[str]
ssl: Optional[Ssl]
statement_metrics: Optional[StatementMetrics]
statement_samples: Optional[StatementSamples]
tags: Optional[Sequence[str]]
use_global_custom_queries: Optional[str]
username: Optional[str]
Expand Down
28 changes: 14 additions & 14 deletions mysql/datadog_checks/mysql/data/conf.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -231,55 +231,55 @@ instances:
#
# dbm: false

## Configure collection of statement metrics
## Configure collection of query metrics
#
statement_metrics:
query_metrics:

## @param enabled - boolean - optional - default: true
## Enable collection of statement metrics. Requires `dbm: true`.
## Enable collection of query metrics. Requires `dbm: true`.
#
# enabled: true

## @param collection_interval - number - optional - default: 10
## Set the statement metric collection interval (in seconds). Each collection involves a single query to
## Set the query metric collection interval (in seconds). Each collection involves a single query to
## `pg_stat_statements`. If a non-default value is chosen then that exact same value must be used for *every*
## check instance. Running different instances with different collection intervals is not supported.
#
# collection_interval: 10

## Configure collection of statement samples
## Configure collection of query samples
#
statement_samples:
query_samples:

## @param enabled - boolean - optional - default: true
## Enables collection of statement samples. Requires `dbm: true`.
## Enables collection of query samples. Requires `dbm: true`.
#
# enabled: true

## @param collection_interval - number - optional - default: 1
## Sets the statement sample collection interval (in seconds). Each collection involves a single query to one
## Sets the query sample collection interval (in seconds). Each collection involves a single query to one
## of the `performance_schema.events_statements_*` tables, followed by at most one `EXPLAIN` query per
## unique statement seen.
#
# collection_interval: 1

## @param explained_statements_per_hour_per_query - integer - optional - default: 60
## Sets the rate limit for how many execution plans will be collected per hour per normalized statement.
## @param explained_queries_per_hour_per_query - integer - optional - default: 60
## Sets the rate limit for how many execution plans will be collected per hour per normalized query.
#
# explained_statements_per_hour_per_query: 60
# explained_queries_per_hour_per_query: 60

## @param samples_per_hour_per_query - integer - optional - default: 15
## Sets the rate limit for how many statement sample events will be ingested per hour per normalized
## execution plan.
#
# samples_per_hour_per_query: 15

## @param explained_statements_cache_maxsize - integer - optional - default: 5000
## Sets the max size of the cache used for the explained_statements_per_hour_per_query rate limit. This
## @param explained_queries_cache_maxsize - integer - optional - default: 5000
## Sets the max size of the cache used for the explained_queries_per_hour_per_query rate limit. This
## should be increased for databases with a very large number of unique normalized queries which exceed the
## cache's limit.
#
# explained_statements_cache_maxsize: 5000
# explained_queries_cache_maxsize: 5000

## @param seen_samples_cache_maxsize - integer - optional - default: 10000
## Sets the max size of the cache used for the samples_per_hour_per_query rate limit. This should be
Expand Down
28 changes: 14 additions & 14 deletions mysql/datadog_checks/mysql/statement_samples.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,8 @@ class DBExplainError(Enum):
# agent may not have access to the default schema
use_schema_error = 'use_schema_error'

# a truncated statement can't be explained
statement_truncated = 'statement_truncated'
# a truncated query can't be explained
query_truncated = 'query_truncated'


class MySQLStatementSamples(DBMAsyncJob):
Expand Down Expand Up @@ -298,8 +298,8 @@ def _init_caches(self):

# explained_statements_cache: limit how often we try to re-explain the same query
self._explained_statements_ratelimiter = RateLimitingTTLCache(
maxsize=self._config.statement_samples_config.get('explained_statements_cache_maxsize', 5000),
ttl=60 * 60 / self._config.statement_samples_config.get('explained_statements_per_hour_per_query', 60),
maxsize=self._config.statement_samples_config.get('explained_queries_cache_maxsize', 5000),
ttl=60 * 60 / self._config.statement_samples_config.get('explained_queries_per_hour_per_query', 60),
)

# seen_samples_cache: limit the ingestion rate per (query_signature, plan_signature)
Expand Down Expand Up @@ -365,7 +365,7 @@ def _get_new_events_statements(self, events_statements_table, row_limit):
)
except pymysql.err.DatabaseError as e:
self._check.count(
"dd.mysql.statement_samples.error",
"dd.mysql.query_samples.error",
1,
tags=self._tags + ["error:create-temp-table-{}".format(type(e))],
)
Expand Down Expand Up @@ -427,7 +427,7 @@ def _collect_plan_for_statement(self, row):
# do not log the raw sql_text to avoid leaking sensitive data into logs. digest_text is safe as parameters
# are obfuscated by the database
self._log.debug("Failed to obfuscate statement: %s", row['digest_text'])
self._check.count("dd.mysql.statement_samples.error", 1, tags=self._tags + ["error:sql-obfuscate"])
self._check.count("dd.mysql.query_samples.error", 1, tags=self._tags + ["error:sql-obfuscate"])
return None

apm_resource_hash = compute_sql_signature(obfuscated_statement)
Expand All @@ -441,14 +441,14 @@ def _collect_plan_for_statement(self, row):
truncated = self._get_truncation_state(row['sql_text'])
if truncated == StatementTruncationState.truncated:
self._check.count(
"dd.mysql.statement_samples.error",
"dd.mysql.query_samples.error",
1,
tags=self._tags + ["error:explain-{}".format(DBExplainError.statement_truncated)],
tags=self._tags + ["error:explain-{}".format(DBExplainError.query_truncated)],
)
explain_errors = [
(
None,
DBExplainError.statement_truncated,
DBExplainError.query_truncated,
'truncated length: {}'.format(len(row['sql_text'])),
)
]
Expand All @@ -460,7 +460,7 @@ def _collect_plan_for_statement(self, row):
)
except Exception as e:
self._check.count(
"dd.mysql.statement_samples.error", 1, tags=self._tags + ["error:explain-{}".format(type(e))]
"dd.mysql.query_samples.error", 1, tags=self._tags + ["error:explain-{}".format(type(e))]
)
self._log.exception("Failed to explain statement: %s", obfuscated_statement)

Expand Down Expand Up @@ -506,7 +506,7 @@ def _collect_plan_for_statement(self, row):
"query_signature": query_signature,
"resource_hash": apm_resource_hash,
"statement": obfuscated_statement,
"statement_truncated": truncated.value,
"query_truncated": truncated.value,
},
'mysql': {k: v for k, v in row.items() if k not in EVENTS_STATEMENTS_SAMPLE_EXCLUDE_KEYS},
}
Expand Down Expand Up @@ -569,7 +569,7 @@ def _get_sample_collection_strategy(self):
"statement samples."
)
self._check.count(
"dd.mysql.statement_samples.error",
"dd.mysql.query_samples.error",
1,
tags=self._tags + ["error:no-enabled-events-statements-consumers"],
)
Expand Down Expand Up @@ -684,7 +684,7 @@ def _explain_statement(self, cursor, statement, schema, obfuscated_statement):
if e.args[0] in PYMYSQL_NON_RETRYABLE_ERRORS:
self._collection_strategy_cache[strategy_cache_key] = explain_errors
self._check.count(
"dd.mysql.statement_samples.error", 1, tags=tags + ["error:explain-use-schema-{}".format(type(e))]
"dd.mysql.query_samples.error", 1, tags=tags + ["error:explain-use-schema-{}".format(type(e))]
)
self._log.debug(
'Failed to collect execution plan because schema could not be accessed. error=%s, schema=%s, '
Expand Down Expand Up @@ -736,7 +736,7 @@ def _explain_statement(self, cursor, statement, schema, obfuscated_statement):
# so we won't try to explain it again for the cache duration there.
explain_errors.append((strategy, DBExplainError.database_error, '{}'.format(type(e))))
self._check.count(
"dd.mysql.statement_samples.error",
"dd.mysql.query_samples.error",
1,
tags=tags + ["error:explain-attempt-{}-{}".format(strategy, type(e))],
)
Expand Down
Loading