Introduce wp profile queries command#207
Conversation
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
wp profile queries command
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
This comment was marked as resolved.
This comment was marked as resolved.
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
…e normalization Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com> Agent-Logs-Url: https://github.com/wp-cli/profile-command/sessions/03bb039a-1130-42cb-b79e-f3182e25c4e5
This comment was marked as resolved.
This comment was marked as resolved.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 11 out of 11 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| $order = Utils\get_flag_value( $assoc_args, 'order', 'ASC' ); | ||
| $orderby = Utils\get_flag_value( $assoc_args, 'orderby', null ); |
There was a problem hiding this comment.
In queries(), $order and $orderby are taken directly from Utils\get_flag_value() without the string/null normalization used elsewhere in this file (e.g. stage() around Command.php:142-145). If a non-string slips through, sorting/formatting can behave unexpectedly. Suggest normalizing $order to a string (defaulting to 'ASC') and $orderby to string|null the same way as the other subcommands for consistency and robustness.
| $order = Utils\get_flag_value( $assoc_args, 'order', 'ASC' ); | |
| $orderby = Utils\get_flag_value( $assoc_args, 'orderby', null ); | |
| $order_val = Utils\get_flag_value( $assoc_args, 'order', 'ASC' ); | |
| $order = is_string( $order_val ) ? $order_val : 'ASC'; | |
| $orderby_val = Utils\get_flag_value( $assoc_args, 'orderby', null ); | |
| $orderby = is_string( $orderby_val ) ? $orderby_val : null; |
| $query_time = $query_data[1]; | ||
| if ( null !== $time_threshold && $query_time < (float) $time_threshold ) { | ||
| continue; | ||
| } |
There was a problem hiding this comment.
--time_threshold is cast to (float) without validating that the provided value is numeric. For inputs like --time_threshold=abc, this becomes 0.0 and silently changes filtering behavior. Consider validating with is_numeric() and erroring with a clear message when the value is not a number.
| 'function' => function () use ( $func, $i, $current_filter ) { | ||
| if ( ! isset( $this->loggers[ $i ] ) ) { | ||
| $this->loggers[ $i ] = new Logger( | ||
| array( | ||
| 'hook' => $current_filter, | ||
| 'callback' => $func, | ||
| ) | ||
| ); |
There was a problem hiding this comment.
wrap_current_filter_callbacks() keys callback-level loggers only by $i (the callback unique ID). That ID can collide across different hooks when the same callback is attached to multiple hooks, so the same Logger instance can be reused for different $current_filter values and the stored hook/callback metadata (and collected query_indices) can become incorrect. Consider namespacing the logger key by hook+callback (e.g., $current_filter . ':' . $i) so each hook/callback pair has its own logger and query attribution is accurate when profiling all hooks (e.g. --callback mode).
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces the wp profile queries command, enabling users to profile database queries, execution times, and callers. Key implementation details include the new QueryLogger class, logic to map queries to hooks and callbacks, and updates to the Formatter to handle non-numeric fields. Review feedback suggests enhancing maintainability by replacing hardcoded method markers and field lists with more dynamic or constant-based solutions.
|
|
||
| $location_index = array_search( 'location', $fields, true ); | ||
| $location_index = array_search( 'location', $fields, true ); | ||
| $non_numeric_fields = array( 'query', 'caller', 'hook', 'callback' ); |
There was a problem hiding this comment.
The non_numeric_fields array is a hardcoded list of fields to exclude from numeric calculations. This approach is fragile as it requires manual updates whenever new non-numeric fields are added to the output. Consider using a more dynamic approach, such as checking the type of the field values or defining metadata on the logger classes to indicate which fields should be summed.
wp profile queriescommand structurequeries()method in Command.php--hook=<hook>parameter to filter queries for a specific hook--callback=<callback>parameter to filter queries for a specific callbackSummary
Fixed the root cause of hook and callback filtering always returning 0 results. The
Logger::stop()method was populatingquery_indicesduring the for-loop, but then immediately clearing it ($this->query_indices = array()). This meant the array was always empty when read by thequeries()command after profiling. Removed the reset fromstop()to match the behavior of other accumulated properties likequery_timeandquery_countwhich also accumulate across runs without being reset instop().Original prompt
wp profile queries#130✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.