Logging: Enable viewing log entry context data in the DB logger list table (#41936)
This commit is contained in:
commit
7838adc1b9
|
@ -0,0 +1,4 @@
|
||||||
|
Significance: minor
|
||||||
|
Type: update
|
||||||
|
|
||||||
|
Enable viewing context data in the database logger list table
|
|
@ -1561,6 +1561,26 @@ table.wc_status_table--tools {
|
||||||
.column-source {
|
.column-source {
|
||||||
width: 15%;
|
width: 15%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.column-context {
|
||||||
|
width: 10%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-context {
|
||||||
|
.button {
|
||||||
|
span {
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-context {
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
pre {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,4 +54,37 @@ abstract class WC_Log_Handler implements WC_Log_Handler_Interface {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a backtrace that shows where the logging function was called.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected static function get_backtrace() {
|
||||||
|
// Get the filenames of the logging-related classes so we can ignore them.
|
||||||
|
$ignore_files = array_map(
|
||||||
|
function( $class ) {
|
||||||
|
try {
|
||||||
|
$reflector = new \ReflectionClass( $class );
|
||||||
|
return $reflector->getFileName();
|
||||||
|
} catch ( Exception $exception ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
array( wc_get_logger(), self::class, static::class )
|
||||||
|
);
|
||||||
|
|
||||||
|
$backtrace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_debug_backtrace
|
||||||
|
|
||||||
|
$filtered_backtrace = array_filter(
|
||||||
|
$backtrace,
|
||||||
|
function( $frame ) use ( $ignore_files ) {
|
||||||
|
$ignore = isset( $frame['file'] ) && in_array( $frame['file'], $ignore_files, true );
|
||||||
|
|
||||||
|
return ! $ignore;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return array_values( $filtered_backtrace );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,6 +92,40 @@ class WC_Admin_Log_Table_List extends WP_List_Table {
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the table rows.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function display_rows() {
|
||||||
|
foreach ( $this->items as $log ) {
|
||||||
|
$this->single_row( $log );
|
||||||
|
if ( ! empty( $log['context'] ) ) {
|
||||||
|
$this->context_row( $log );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the additional table row that contains extra log context data.
|
||||||
|
*
|
||||||
|
* @param array $log Log entry data.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function context_row( $log ) {
|
||||||
|
// Maintains alternating row background colors.
|
||||||
|
?>
|
||||||
|
<tr style="display: none"><td></td></tr>
|
||||||
|
<tr id="log-context-<?php echo esc_attr( $log['log_id'] ); ?>" class="log-context">
|
||||||
|
<td colspan="<?php echo esc_attr( $this->get_column_count() ); ?>">
|
||||||
|
<p><strong><?php esc_html_e( 'Additional context', 'woocommerce' ); ?></strong></p>
|
||||||
|
<pre><?php echo esc_html( $log['context'] ); ?></pre>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get list columns.
|
* Get list columns.
|
||||||
*
|
*
|
||||||
|
@ -104,6 +138,7 @@ class WC_Admin_Log_Table_List extends WP_List_Table {
|
||||||
'level' => __( 'Level', 'woocommerce' ),
|
'level' => __( 'Level', 'woocommerce' ),
|
||||||
'message' => __( 'Message', 'woocommerce' ),
|
'message' => __( 'Message', 'woocommerce' ),
|
||||||
'source' => __( 'Source', 'woocommerce' ),
|
'source' => __( 'Source', 'woocommerce' ),
|
||||||
|
'context' => __( 'Context', 'woocommerce' ),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,6 +215,36 @@ class WC_Admin_Log_Table_List extends WP_List_Table {
|
||||||
return esc_html( $log['source'] );
|
return esc_html( $log['source'] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Context column.
|
||||||
|
*
|
||||||
|
* @param array $log Log entry data.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function column_context( $log ) {
|
||||||
|
$content = '';
|
||||||
|
|
||||||
|
if ( ! empty( $log['context'] ) ) {
|
||||||
|
ob_start();
|
||||||
|
?>
|
||||||
|
<button
|
||||||
|
class="log-toggle button button-secondary button-small"
|
||||||
|
data-log-id="<?php echo esc_attr( $log['log_id'] ); ?>"
|
||||||
|
data-toggle-status="off"
|
||||||
|
data-label-show="<?php esc_attr_e( 'Show context', 'woocommerce' ); ?>"
|
||||||
|
data-label-hide="<?php esc_attr_e( 'Hide context', 'woocommerce' ); ?>"
|
||||||
|
>
|
||||||
|
<span class="dashicons dashicons-arrow-down-alt2"></span>
|
||||||
|
<span class="log-toggle-label screen-reader-text"><?php esc_html_e( 'Show context', 'woocommerce' ); ?></span>
|
||||||
|
</button>
|
||||||
|
<?php
|
||||||
|
$content = ob_get_clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get bulk actions.
|
* Get bulk actions.
|
||||||
*
|
*
|
||||||
|
@ -273,7 +338,7 @@ class WC_Admin_Log_Table_List extends WP_List_Table {
|
||||||
$offset = $this->get_items_query_offset();
|
$offset = $this->get_items_query_offset();
|
||||||
|
|
||||||
$query_items = "
|
$query_items = "
|
||||||
SELECT log_id, timestamp, level, message, source
|
SELECT log_id, timestamp, level, message, source, context
|
||||||
FROM {$wpdb->prefix}woocommerce_log
|
FROM {$wpdb->prefix}woocommerce_log
|
||||||
{$where} {$order} {$limit} {$offset}
|
{$where} {$order} {$limit} {$offset}
|
||||||
";
|
";
|
||||||
|
|
|
@ -20,6 +20,35 @@ if ( ! defined( 'ABSPATH' ) ) {
|
||||||
<?php submit_button( __( 'Flush all logs', 'woocommerce' ), 'delete', 'flush-logs' ); ?>
|
<?php submit_button( __( 'Flush all logs', 'woocommerce' ), 'delete', 'flush-logs' ); ?>
|
||||||
<?php wp_nonce_field( 'woocommerce-status-logs' ); ?>
|
<?php wp_nonce_field( 'woocommerce-status-logs' ); ?>
|
||||||
</form>
|
</form>
|
||||||
|
<script>
|
||||||
|
document.addEventListener( 'DOMContentLoaded', function() {
|
||||||
|
var contextToggles = Array.from( document.getElementsByClassName( 'log-toggle' ) );
|
||||||
|
contextToggles.forEach( ( element ) => {
|
||||||
|
element.addEventListener( 'click', ( event ) => {
|
||||||
|
event.preventDefault();
|
||||||
|
const button = event.currentTarget;
|
||||||
|
const buttonLabel = button.querySelector( '.log-toggle-label' );
|
||||||
|
const buttonIcon = button.querySelector( '.dashicons' );
|
||||||
|
const context = document.getElementById( 'log-context-' + button.dataset.logId );
|
||||||
|
|
||||||
|
switch ( button.dataset.toggleStatus ) {
|
||||||
|
case 'off':
|
||||||
|
context.style.display = 'table-row';
|
||||||
|
buttonLabel.textContent = button.dataset.labelHide;
|
||||||
|
buttonIcon.classList.replace( 'dashicons-arrow-down-alt2', 'dashicons-arrow-up-alt2' );
|
||||||
|
button.dataset.toggleStatus = 'on';
|
||||||
|
break;
|
||||||
|
case 'on':
|
||||||
|
context.style.display = 'none';
|
||||||
|
buttonLabel.textContent = button.dataset.labelShow;
|
||||||
|
buttonIcon.classList.replace( 'dashicons-arrow-up-alt2', 'dashicons-arrow-down-alt2' );
|
||||||
|
button.dataset.toggleStatus = 'off';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
</script>
|
||||||
<?php
|
<?php
|
||||||
wc_enqueue_js(
|
wc_enqueue_js(
|
||||||
"jQuery( '#flush-logs' ).on( 'click', function() {
|
"jQuery( '#flush-logs' ).on( 'click', function() {
|
||||||
|
|
|
@ -77,12 +77,13 @@ class WC_Log_Handler_DB extends WC_Log_Handler {
|
||||||
'%s', // possible serialized context.
|
'%s', // possible serialized context.
|
||||||
);
|
);
|
||||||
|
|
||||||
|
unset( $context['source'] );
|
||||||
if ( ! empty( $context ) ) {
|
if ( ! empty( $context ) ) {
|
||||||
try {
|
if ( isset( $context['backtrace'] ) && true === filter_var( $context['backtrace'], FILTER_VALIDATE_BOOLEAN ) ) {
|
||||||
$insert['context'] = serialize( $context ); // @codingStandardsIgnoreLine.
|
$context['backtrace'] = self::get_backtrace();
|
||||||
} catch ( Exception $e ) {
|
|
||||||
$insert['context'] = serialize( 'There was an error while serializing the context: ' . $e->getMessage() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$insert['context'] = wp_json_encode( $context, JSON_PRETTY_PRINT );
|
||||||
}
|
}
|
||||||
|
|
||||||
return false !== $wpdb->insert( "{$wpdb->prefix}woocommerce_log", $insert, $format );
|
return false !== $wpdb->insert( "{$wpdb->prefix}woocommerce_log", $insert, $format );
|
||||||
|
|
|
@ -49,63 +49,63 @@ class WC_Tests_Log_Handler_DB extends WC_Unit_Test_Case {
|
||||||
'level' => WC_Log_Levels::get_level_severity( 'debug' ),
|
'level' => WC_Log_Levels::get_level_severity( 'debug' ),
|
||||||
'message' => 'msg_debug',
|
'message' => 'msg_debug',
|
||||||
'source' => 'source_debug',
|
'source' => 'source_debug',
|
||||||
'context' => serialize( array( 'source' => 'source_debug' ) ),
|
'context' => '',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'timestamp' => $expected_ts,
|
'timestamp' => $expected_ts,
|
||||||
'level' => WC_Log_Levels::get_level_severity( 'info' ),
|
'level' => WC_Log_Levels::get_level_severity( 'info' ),
|
||||||
'message' => 'msg_info',
|
'message' => 'msg_info',
|
||||||
'source' => 'source_info',
|
'source' => 'source_info',
|
||||||
'context' => serialize( array( 'source' => 'source_info' ) ),
|
'context' => '',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'timestamp' => $expected_ts,
|
'timestamp' => $expected_ts,
|
||||||
'level' => WC_Log_Levels::get_level_severity( 'notice' ),
|
'level' => WC_Log_Levels::get_level_severity( 'notice' ),
|
||||||
'message' => 'msg_notice',
|
'message' => 'msg_notice',
|
||||||
'source' => 'source_notice',
|
'source' => 'source_notice',
|
||||||
'context' => serialize( array( 'source' => 'source_notice' ) ),
|
'context' => '',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'timestamp' => $expected_ts,
|
'timestamp' => $expected_ts,
|
||||||
'level' => WC_Log_Levels::get_level_severity( 'warning' ),
|
'level' => WC_Log_Levels::get_level_severity( 'warning' ),
|
||||||
'message' => 'msg_warning',
|
'message' => 'msg_warning',
|
||||||
'source' => 'source_warning',
|
'source' => 'source_warning',
|
||||||
'context' => serialize( array( 'source' => 'source_warning' ) ),
|
'context' => '',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'timestamp' => $expected_ts,
|
'timestamp' => $expected_ts,
|
||||||
'level' => WC_Log_Levels::get_level_severity( 'error' ),
|
'level' => WC_Log_Levels::get_level_severity( 'error' ),
|
||||||
'message' => 'msg_error',
|
'message' => 'msg_error',
|
||||||
'source' => 'source_error',
|
'source' => 'source_error',
|
||||||
'context' => serialize( array( 'source' => 'source_error' ) ),
|
'context' => '',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'timestamp' => $expected_ts,
|
'timestamp' => $expected_ts,
|
||||||
'level' => WC_Log_Levels::get_level_severity( 'critical' ),
|
'level' => WC_Log_Levels::get_level_severity( 'critical' ),
|
||||||
'message' => 'msg_critical',
|
'message' => 'msg_critical',
|
||||||
'source' => 'source_critical',
|
'source' => 'source_critical',
|
||||||
'context' => serialize( array( 'source' => 'source_critical' ) ),
|
'context' => '',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'timestamp' => $expected_ts,
|
'timestamp' => $expected_ts,
|
||||||
'level' => WC_Log_Levels::get_level_severity( 'alert' ),
|
'level' => WC_Log_Levels::get_level_severity( 'alert' ),
|
||||||
'message' => 'msg_alert',
|
'message' => 'msg_alert',
|
||||||
'source' => 'source_alert',
|
'source' => 'source_alert',
|
||||||
'context' => serialize( array( 'source' => 'source_alert' ) ),
|
'context' => '',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'timestamp' => $expected_ts,
|
'timestamp' => $expected_ts,
|
||||||
'level' => WC_Log_Levels::get_level_severity( 'emergency' ),
|
'level' => WC_Log_Levels::get_level_severity( 'emergency' ),
|
||||||
'message' => 'msg_emergency',
|
'message' => 'msg_emergency',
|
||||||
'source' => 'source_emergency',
|
'source' => 'source_emergency',
|
||||||
'context' => serialize( array( 'source' => 'source_emergency' ) ),
|
'context' => '',
|
||||||
),
|
),
|
||||||
array(
|
array(
|
||||||
'timestamp' => $expected_ts,
|
'timestamp' => $expected_ts,
|
||||||
'level' => WC_Log_Levels::get_level_severity( 'debug' ),
|
'level' => WC_Log_Levels::get_level_severity( 'debug' ),
|
||||||
'message' => 'context_test',
|
'message' => 'context_test',
|
||||||
'source' => pathinfo( __FILE__, PATHINFO_FILENAME ),
|
'source' => pathinfo( __FILE__, PATHINFO_FILENAME ),
|
||||||
'context' => serialize( $context ),
|
'context' => wp_json_encode( $context, JSON_PRETTY_PRINT ),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue