Skip to content

Commit a6a26c9

Browse files
authored
Improve plugin logger (#4468)
* Add default log context * Add shortcut methods for each log severity level * Use logger context for Webhook logs with structured data (headers, event, error, etc) * Always log messages with severity error and above
1 parent 5f46f43 commit a6a26c9

File tree

6 files changed

+174
-24
lines changed

6 files changed

+174
-24
lines changed

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
* Add - Show payment methods sync status on the UI
1717
* Fix - No such customer error when creating a payment method with a new Stripe account
1818
* Fix - Validate create customer payload against required billing fields before sending to Stripe
19+
* Update - Enhanced logging system with support for all log levels and improved context handling
1920

2021
= 9.6.0 - 2025-07-07 =
2122
* Fix - Register Express Checkout script before use to restore buttons on “order-pay” pages

client/settings/advanced-settings-section/__tests__/index.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,11 @@ describe( 'AdvancedSettings', () => {
4646

4747
render( <AdvancedSettings /> );
4848

49-
const debugModeCheckbox = screen.getByLabelText( 'Log error messages' );
49+
const debugModeCheckbox = screen.getByLabelText( 'Log debug messages' );
5050

5151
expect( screen.getByText( 'Debug mode' ) ).toBeInTheDocument();
5252
expect(
53-
screen.getByLabelText( 'Log error messages' )
53+
screen.getByLabelText( 'Log debug messages' )
5454
).not.toBeChecked();
5555

5656
userEvent.click( debugModeCheckbox );

client/settings/advanced-settings-section/debug-mode.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ const DebugMode = () => {
1212
<CheckboxControl
1313
data-testid="logging-checkbox"
1414
label={ __(
15-
'Log error messages',
15+
'Log debug messages',
1616
'woocommerce-gateway-stripe'
1717
) }
1818
help={ __(
19-
'When enabled, payment error logs will be saved to WooCommerce > Status > Logs.',
19+
'When enabled, payment debug logs will be saved to WooCommerce > Status > Logs.',
2020
'woocommerce-gateway-stripe'
2121
) }
2222
checked={ isLoggingChecked }

includes/class-wc-stripe-logger.php

Lines changed: 159 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,30 @@
1111
*/
1212
class WC_Stripe_Logger {
1313

14-
public static $logger;
1514
const WC_LOG_FILENAME = 'woocommerce-gateway-stripe';
1615

16+
const LOG_CONTEXT = [
17+
'source' => self::WC_LOG_FILENAME,
18+
'stripe_version' => WC_STRIPE_VERSION,
19+
'stripe_api_version' => WC_Stripe_API::STRIPE_API_VERSION,
20+
];
21+
22+
/**
23+
* Log handler instance.
24+
*
25+
* @see https://developer.wordpress.org/reference/classes/wp_logger/
26+
* @see https://developer.woocommerce.com/docs/best-practices/data-management/logging/#log-handlers
27+
*
28+
* @var WC_Logger
29+
*/
30+
public static $logger;
31+
1732
/**
1833
* Utilize WC logger class
1934
*
35+
* @deprecated 9.7.0 Use the shortcut methods for each log severity level: info(), error(), etc. instead.
36+
*
2037
* @since 4.0.0
21-
* @version 4.0.0
2238
*/
2339
public static function log( $message, $start_time = null, $end_time = null ) {
2440
if ( ! self::can_log() ) {
@@ -52,13 +68,99 @@ public static function log( $message, $start_time = null, $end_time = null ) {
5268
self::$logger->debug( $log_entry, [ 'source' => self::WC_LOG_FILENAME ] );
5369
}
5470

71+
// Logs have eight different severity levels:
72+
// - emergency
73+
// - alert
74+
// - critical
75+
// - error
76+
// - warning
77+
// - notice
78+
// - info
79+
// - debug
80+
81+
/**
82+
* Creates a log entry of type emergency.
83+
*
84+
* @since 9.7.0
85+
*
86+
* @param string $message Message to send to the log file.
87+
* @param array $context Additional context to add to the log.
88+
*
89+
* @return void
90+
*/
91+
public static function emergency( $message, $context = [] ) {
92+
if ( empty( self::$logger ) ) {
93+
self::$logger = wc_get_logger();
94+
}
95+
96+
self::$logger->emergency( $message, array_merge( self::LOG_CONTEXT, $context, [ 'backtrace' => true ] ) );
97+
}
98+
99+
/**
100+
* Creates a log entry of type alert.
101+
*
102+
* @since 9.7.0
103+
*
104+
* @param string $message Message to send to the log file.
105+
* @param array $context Additional context to add to the log.
106+
*
107+
* @return void
108+
*/
109+
public static function alert( $message, $context = [] ) {
110+
if ( empty( self::$logger ) ) {
111+
self::$logger = wc_get_logger();
112+
}
113+
114+
self::$logger->alert( $message, array_merge( self::LOG_CONTEXT, $context, [ 'backtrace' => true ] ) );
115+
}
116+
117+
/**
118+
* Creates a log entry of type critical.
119+
*
120+
* @since 9.7.0
121+
*
122+
* @param string $message Message to send to the log file.
123+
* @param array $context Additional context to add to the log.
124+
*
125+
* @return void
126+
*/
127+
public static function critical( $message, $context = [] ) {
128+
if ( empty( self::$logger ) ) {
129+
self::$logger = wc_get_logger();
130+
}
131+
132+
self::$logger->critical( $message, array_merge( self::LOG_CONTEXT, $context, [ 'backtrace' => true ] ) );
133+
}
134+
55135
/**
56136
* Creates a log entry of type error.
57137
*
58-
* @param string $message To send to the log file.
138+
* @since 4.0.0
139+
*
140+
* @param string $message Message to send to the log file.
141+
* @param array $context Additional context to add to the log.
142+
*
59143
* @return void
60144
*/
61-
public static function error( $message ) {
145+
public static function error( $message, $context = [] ) {
146+
if ( empty( self::$logger ) ) {
147+
self::$logger = wc_get_logger();
148+
}
149+
150+
self::$logger->error( $message, array_merge( self::LOG_CONTEXT, $context, [ 'backtrace' => true ] ) );
151+
}
152+
153+
/**
154+
* Creates a log entry of type warning.
155+
*
156+
* @since 9.7.0
157+
*
158+
* @param string $message Message to send to the log file.
159+
* @param array $context Additional context to add to the log.
160+
*
161+
* @return void
162+
*/
163+
public static function warning( $message, $context = [] ) {
62164
if ( ! self::can_log() ) {
63165
return;
64166
}
@@ -67,16 +169,64 @@ public static function error( $message ) {
67169
self::$logger = wc_get_logger();
68170
}
69171

70-
self::$logger->error( $message, [ 'source' => self::WC_LOG_FILENAME ] );
172+
self::$logger->warning( $message, array_merge( self::LOG_CONTEXT, $context, [ 'backtrace' => true ] ) );
173+
}
174+
175+
/**
176+
* Creates a log entry of type notice.
177+
*
178+
* @since 9.7.0
179+
*
180+
* @param string $message Message to send to the log file.
181+
* @param array $context Additional context to add to the log.
182+
*
183+
* @return void
184+
*/
185+
public static function notice( $message, $context = [] ) {
186+
if ( ! self::can_log() ) {
187+
return;
188+
}
189+
190+
if ( empty( self::$logger ) ) {
191+
self::$logger = wc_get_logger();
192+
}
193+
194+
self::$logger->notice( $message, array_merge( self::LOG_CONTEXT, $context ) );
195+
}
196+
197+
/**
198+
* Creates a log entry of type info.
199+
*
200+
* @since 9.7.0
201+
*
202+
* @param string $message Message to send to the log file.
203+
* @param array $context Additional context to add to the log.
204+
*
205+
* @return void
206+
*/
207+
public static function info( $message, $context = [] ) {
208+
if ( ! self::can_log() ) {
209+
return;
210+
}
211+
212+
if ( empty( self::$logger ) ) {
213+
self::$logger = wc_get_logger();
214+
}
215+
216+
self::$logger->info( $message, array_merge( self::LOG_CONTEXT, $context ) );
71217
}
72218

73219
/**
74220
* Creates a log entry of type debug.
75221
*
76-
* @param string $message To send to the log file.
222+
* @since 4.0.0
223+
*
224+
* @param string $message Message to send to the log file.
225+
* @param array $context Additional context to add to the log.
226+
*
77227
* @return void
78228
*/
79-
public static function debug( $message ) {
229+
public static function debug( $message, $context = [] ) {
80230
if ( ! self::can_log() ) {
81231
return;
82232
}
@@ -85,19 +235,15 @@ public static function debug( $message ) {
85235
self::$logger = wc_get_logger();
86236
}
87237

88-
self::$logger->debug( $message, [ 'source' => self::WC_LOG_FILENAME ] );
238+
self::$logger->debug( $message, array_merge( self::LOG_CONTEXT, $context ) );
89239
}
90240

91241
/**
92-
* Whether we can log based on settings and filters.
242+
* Whether we can log based on the plugin settings.
93243
*
94244
* @return boolean
95245
*/
96246
public static function can_log(): bool {
97-
if ( ! class_exists( 'WC_Logger' ) ) {
98-
return false;
99-
}
100-
101247
$settings = WC_Stripe_Helper::get_stripe_settings();
102248

103249
if ( empty( $settings ) || ( isset( $settings['logging'] ) && 'yes' !== $settings['logging'] ) ) {

includes/class-wc-stripe-webhook-handler.php

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,18 +94,16 @@ public function check_for_webhook() {
9494
$event = json_decode( $request_body );
9595
$event_type = $event->type ?? 'No event type found';
9696
} catch ( Exception $e ) {
97-
WC_Stripe_Logger::error( 'Webhook body could not be retrieved: ' . $e->getMessage() );
97+
WC_Stripe_Logger::error( 'Webhook body could not be retrieved', [ 'error' => $e ] );
9898
return;
9999
}
100100

101-
WC_Stripe_Logger::debug( 'Webhook received: ' . $event_type );
102-
103101
// Validate it to make sure it is legit.
104102
$request_headers = array_change_key_case( $this->get_request_headers(), CASE_UPPER );
105103
$validation_result = $this->validate_request( $request_headers, $request_body );
106104

107105
if ( WC_Stripe_Webhook_State::VALIDATION_SUCCEEDED === $validation_result ) {
108-
WC_Stripe_Logger::debug( 'Webhook body: ' . print_r( $request_body, true ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
106+
WC_Stripe_Logger::debug( 'Webhook received (' . $event_type . ')', [ 'event' => $event ] );
109107

110108
$this->process_webhook( $request_body );
111109

@@ -114,8 +112,13 @@ public function check_for_webhook() {
114112
status_header( 200 );
115113
exit;
116114
} else {
117-
WC_Stripe_Logger::error( 'Webhook failed validation. Reason: ' . $validation_result );
118-
WC_Stripe_Logger::error( 'Webhook body: ' . print_r( $request_body, true ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
115+
WC_Stripe_Logger::error(
116+
'Webhook validation failed (' . $validation_result . ')',
117+
[
118+
'request_headers' => $request_headers,
119+
'event' => $event,
120+
]
121+
);
119122

120123
WC_Stripe_Webhook_State::set_last_webhook_failure_at( time() );
121124

readme.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,6 @@ If you get stuck, you can ask for help in the [Plugin Forum](https://wordpress.o
126126
* Add - Show payment methods sync status on the UI
127127
* Fix - No such customer error when creating a payment method with a new Stripe account
128128
* Fix - Validate create customer payload against required billing fields before sending to Stripe
129-
129+
* Update - Enhanced logging system with support for all log levels and improved context handling
130130

131131
[See changelog for full details across versions](https://raw.githubusercontent.com/woocommerce/woocommerce-gateway-stripe/trunk/changelog.txt).

0 commit comments

Comments
 (0)