DBMON-6748 ClickHouse Async Inserts Monitoring Flush Log Collection#24549
DBMON-6748 ClickHouse Async Inserts Monitoring Flush Log Collection#24549jenny-chung wants to merge 21 commits into
Conversation
🎉 All green!🧪 All tests passed 🎯 Code Coverage (details) 🔗 Commit SHA: 240253e | Docs | Datadog PR Page | Give us feedback! |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d686cbc0b1
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| self._config.query_completions.enabled or self._config.asynchronous_insert_flush_log.enabled | ||
| ): | ||
| self.query_completions = ClickhouseQueryCompletions( | ||
| self, self._config.query_completions, self._config.asynchronous_insert_flush_log |
There was a problem hiding this comment.
Enable the shared job when only flush logs are configured
When a user enables asynchronous_insert_flush_log but disables query_completions, this still constructs ClickhouseQueryCompletions with self._config.query_completions; ClickhouseQueryLogJob passes that config's enabled value into DBMAsyncJob, whose run_job_loop returns immediately when _enabled is false. In that configuration self.query_completions exists but run_job() is never called, so _collect_flush() is never reached and no async insert flush events are emitted.
Useful? React with 👍 / 👎.
| {checkpoint_filter} | ||
| AND event_time_microseconds <= now64(6) |
There was a problem hiding this comment.
Add the date bound to flush-log collections
On instances that retain more than a few days of system.asynchronous_insert_log, this new query only has the microsecond checkpoint predicate. The existing query-log collectors also bind event_date >= toDate(fromUnixTimestamp64Micro({min_checkpoint_us:UInt64})) so ClickHouse can prune old daily partitions; here _collect_flush_rows discards _min_checkpoint and never adds the date predicate, so every async flush collection can scan historical log partitions that can never match. Please add the same event_date bound and parameter to the flush query.
Useful? React with 👍 / 👎.
…query completions
|
|
||
| def _flush_error_count(self, error_label): | ||
| self._check.count( | ||
| "dd.clickhouse.query_completions.error", |
There was a problem hiding this comment.
this should be a async insert specific metrics name maybe dd.clickhouse.async_inserts_flush.error
There was a problem hiding this comment.
I see, changed the name to be async insert specific in 52c4b33
| """ | ||
| Run the async insert flush log collection on its own collection interval | ||
| """ | ||
| if self._flush_enabled and time.time() - self._last_flush_collection_time >= self._flush_collection_interval: |
There was a problem hiding this comment.
Let's do one call of time.time(). since between these two calls there will be a few microseconds of elapsed time so the _last_flush_collection_time is later than the value being compared
| "{checkpoint_filter}", checkpoint_filter | ||
| ) | ||
| params["min_checkpoint_us"] = min_checkpoint | ||
| params["max_flush_rows"] = self._max_samples_per_collection |
There was a problem hiding this comment.
max_samples_per_collection seems to be coming from a different config section, we should have a max_flush_rows option under asynchronous_insert_flush_log in the spec.yaml.
This is confusing for anyone who disables query_completions entirely but runs flush.
There was a problem hiding this comment.
Changed to use max_flush_rows option in asynchronous_insert_flush_log config - e35973d
| 'collection_interval': self._flush_collection_interval, | ||
| 'ddtags': self._tags_no_db, | ||
| 'timestamp': time.time() * 1000, | ||
| 'clickhouse_version': self._check.dbms_version, |
There was a problem hiding this comment.
let's add service here too 'service': getattr(self._check._config, 'service', None),
|
|
||
| event_time_int = self.to_microseconds(event_time_microseconds) | ||
| flush_time_int = self.to_microseconds(flush_time_microseconds) | ||
| flush_latency_us = flush_time_int - event_time_int if event_time_int and flush_time_int else 0 |
There was a problem hiding this comment.
this can go negative when the system clocks skew across nodes, might be good to do a flush_latency_us = max(0, flush_time_int - event_time_int) if event_time_int and flush_time_int else 0
| SECURE_FIELD_NAMES = frozenset(['tls_ca_cert']) | ||
|
|
||
|
|
||
| class AsynchronousInsertFlushLog(BaseModel): |
There was a problem hiding this comment.
QQ: I'm guessing this was a generated change but wanted to confirm
There was a problem hiding this comment.
yes instance.py is auto generated
| type: number | ||
| example: 60 | ||
| fleet_configurable: false | ||
| - name: max_flush_rows |
There was a problem hiding this comment.
Is limit a clearer? Perhaps max_samples_per_collection? We should strive for following existing naming conventions for similar functionality so that we maintain a cohesive customer experience.
Validation ReportAll 21 validations passed. Show details
|
| type: boolean | ||
| example: false | ||
| fleet_configurable: false | ||
| - name: asynchronous_insert_flush_log |
There was a problem hiding this comment.
This config name is a bit of a mouthful and I'm not sure customers would easily understand what this feature collects. Let's brainstorm on this a bit 🤔
| example: false | ||
| fleet_configurable: false | ||
| - name: asynchronous_insert_flush_log | ||
| description: Configure asynchronous insert flush log monitoring |
There was a problem hiding this comment.
Currently this description is re-stating the config block currently. I think we should move parts of the description for enabled up into here to better describe this whole block and shrink down enabled description. The part below about calling out dbm:true requirement is good to keep there
What does this PR do?
Adds flush log collection for ClickHouse async inserts. The check queries
system.asynchronous_insert_logand submits one DBM event per flush record. The collection logic runs in the existing query completions job.Motivation
DBM currently has no visibility into ClickHouse async insert flush health, so customers have to manually query system tables just to see whether flushes are failing, how fast they're running, or how much data they're moving.
Agent payload (in mitm proxy):

Review checklist (to be filled by reviewers)
qa/requiredif this PR needs QA validation, orqa/skip-qaif it does not. Exactly one of the two is required.backport/<branch-name>label to the PR and it will automatically open a backport PR once this one is merged