| 548 | } |
| 549 | |
| 550 | static void logQueryMetricLogFinish(ContextPtr context, bool internal, String query_id, std::chrono::system_clock::time_point finish_time, QueryStatusInfoPtr info) |
| 551 | { |
| 552 | if (auto query_metric_log = context->getQueryMetricLog(); query_metric_log && !internal) |
| 553 | { |
| 554 | auto interval_milliseconds = getQueryMetricLogInterval(context); |
| 555 | if (info && interval_milliseconds > 0) |
| 556 | { |
| 557 | /// Only collect data on query finish if the elapsed time exceeds the interval to collect. |
| 558 | /// If we don't do this, it's counter-intuitive to have a single entry for every quick query |
| 559 | /// where the data is basically a subset of the query_log. |
| 560 | /// On the other hand, it's very convenient to have a new entry whenever the query finishes |
| 561 | /// so that we can get nice time-series querying only query_metric_log without the need |
| 562 | /// to query the final state in query_log. |
| 563 | auto collect_on_finish = info->elapsed_microseconds > interval_milliseconds * 1000; |
| 564 | auto query_info = collect_on_finish ? info : nullptr; |
| 565 | query_metric_log->finishQuery(query_id, finish_time, query_info); |
| 566 | } |
| 567 | else |
| 568 | { |
| 569 | query_metric_log->finishQuery(query_id, finish_time, nullptr); |
| 570 | } |
| 571 | } |
| 572 | } |
| 573 | |
| 574 | static ResultProgress flushQueryProgress(const QueryPipeline & pipeline, bool pulling_pipeline, const ProgressCallback & progress_callback, QueryStatusPtr process_list_elem) |
| 575 | { |
no test coverage detected