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 {
|
||||
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
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
|
@ -104,6 +138,7 @@ class WC_Admin_Log_Table_List extends WP_List_Table {
|
|||
'level' => __( 'Level', 'woocommerce' ),
|
||||
'message' => __( 'Message', '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'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
|
@ -273,7 +338,7 @@ class WC_Admin_Log_Table_List extends WP_List_Table {
|
|||
$offset = $this->get_items_query_offset();
|
||||
|
||||
$query_items = "
|
||||
SELECT log_id, timestamp, level, message, source
|
||||
SELECT log_id, timestamp, level, message, source, context
|
||||
FROM {$wpdb->prefix}woocommerce_log
|
||||
{$where} {$order} {$limit} {$offset}
|
||||
";
|
||||
|
|
|
@ -20,6 +20,35 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
<?php submit_button( __( 'Flush all logs', 'woocommerce' ), 'delete', 'flush-logs' ); ?>
|
||||
<?php wp_nonce_field( 'woocommerce-status-logs' ); ?>
|
||||
</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
|
||||
wc_enqueue_js(
|
||||
"jQuery( '#flush-logs' ).on( 'click', function() {
|
||||
|
|
|
@ -77,12 +77,13 @@ class WC_Log_Handler_DB extends WC_Log_Handler {
|
|||
'%s', // possible serialized context.
|
||||
);
|
||||
|
||||
unset( $context['source'] );
|
||||
if ( ! empty( $context ) ) {
|
||||
try {
|
||||
$insert['context'] = serialize( $context ); // @codingStandardsIgnoreLine.
|
||||
} catch ( Exception $e ) {
|
||||
$insert['context'] = serialize( 'There was an error while serializing the context: ' . $e->getMessage() );
|
||||
if ( isset( $context['backtrace'] ) && true === filter_var( $context['backtrace'], FILTER_VALIDATE_BOOLEAN ) ) {
|
||||
$context['backtrace'] = self::get_backtrace();
|
||||
}
|
||||
|
||||
$insert['context'] = wp_json_encode( $context, JSON_PRETTY_PRINT );
|
||||
}
|
||||
|
||||
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' ),
|
||||
'message' => 'msg_debug',
|
||||
'source' => 'source_debug',
|
||||
'context' => serialize( array( 'source' => 'source_debug' ) ),
|
||||
'context' => '',
|
||||
),
|
||||
array(
|
||||
'timestamp' => $expected_ts,
|
||||
'level' => WC_Log_Levels::get_level_severity( 'info' ),
|
||||
'message' => 'msg_info',
|
||||
'source' => 'source_info',
|
||||
'context' => serialize( array( 'source' => 'source_info' ) ),
|
||||
'context' => '',
|
||||
),
|
||||
array(
|
||||
'timestamp' => $expected_ts,
|
||||
'level' => WC_Log_Levels::get_level_severity( 'notice' ),
|
||||
'message' => 'msg_notice',
|
||||
'source' => 'source_notice',
|
||||
'context' => serialize( array( 'source' => 'source_notice' ) ),
|
||||
'context' => '',
|
||||
),
|
||||
array(
|
||||
'timestamp' => $expected_ts,
|
||||
'level' => WC_Log_Levels::get_level_severity( 'warning' ),
|
||||
'message' => 'msg_warning',
|
||||
'source' => 'source_warning',
|
||||
'context' => serialize( array( 'source' => 'source_warning' ) ),
|
||||
'context' => '',
|
||||
),
|
||||
array(
|
||||
'timestamp' => $expected_ts,
|
||||
'level' => WC_Log_Levels::get_level_severity( 'error' ),
|
||||
'message' => 'msg_error',
|
||||
'source' => 'source_error',
|
||||
'context' => serialize( array( 'source' => 'source_error' ) ),
|
||||
'context' => '',
|
||||
),
|
||||
array(
|
||||
'timestamp' => $expected_ts,
|
||||
'level' => WC_Log_Levels::get_level_severity( 'critical' ),
|
||||
'message' => 'msg_critical',
|
||||
'source' => 'source_critical',
|
||||
'context' => serialize( array( 'source' => 'source_critical' ) ),
|
||||
'context' => '',
|
||||
),
|
||||
array(
|
||||
'timestamp' => $expected_ts,
|
||||
'level' => WC_Log_Levels::get_level_severity( 'alert' ),
|
||||
'message' => 'msg_alert',
|
||||
'source' => 'source_alert',
|
||||
'context' => serialize( array( 'source' => 'source_alert' ) ),
|
||||
'context' => '',
|
||||
),
|
||||
array(
|
||||
'timestamp' => $expected_ts,
|
||||
'level' => WC_Log_Levels::get_level_severity( 'emergency' ),
|
||||
'message' => 'msg_emergency',
|
||||
'source' => 'source_emergency',
|
||||
'context' => serialize( array( 'source' => 'source_emergency' ) ),
|
||||
'context' => '',
|
||||
),
|
||||
array(
|
||||
'timestamp' => $expected_ts,
|
||||
'level' => WC_Log_Levels::get_level_severity( 'debug' ),
|
||||
'message' => 'context_test',
|
||||
'source' => pathinfo( __FILE__, PATHINFO_FILENAME ),
|
||||
'context' => serialize( $context ),
|
||||
'context' => wp_json_encode( $context, JSON_PRETTY_PRINT ),
|
||||
),
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in New Issue