PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / trunk
MainWP Dashboard: Self-hosted WordPress Management for Agencies vtrunk
6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 5.2.2 5.3 All 153 releases
← All changes | class/class-mainwp-logger.php +440 -60 5.2trunk View file →
@@ -8,8 +8,13 @@
8 8 */
9 9
10 10 namespace MainWP\Dashboard;
11 11
12 +// Exit if accessed directly.
13 +if ( ! defined( 'ABSPATH' ) ) {
14 + exit;
15 +}
16 +
12 17 /**
13 18 * Class MainWP_Logger
14 19 *
15 20 * @package MainWP\Dashboard
@@ -17,24 +22,41 @@
17 22 class MainWP_Logger { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
18 23
19 24 // phpcs:disable WordPress.WP.AlternativeFunctions -- for custom read/write logging file.
20 25
21 - const UPDATE_CHECK_LOG_PRIORITY = 10;
22 - const EXECUTION_TIME_LOG_PRIORITY = 15;
23 - const LOGS_AUTO_PURGE_LOG_PRIORITY = 16;
24 - const COST_TRACKER_LOG_PRIORITY = 20230112;
25 - const API_BACKUPS_LOG_PRIORITY = 20240130;
26 + const UPDATE_CHECK_LOG_PRIORITY = 10;
27 + const EXECUTION_TIME_LOG_PRIORITY = 15;
28 + const LOGS_AUTO_PURGE_LOG_PRIORITY = 16;
29 + const LOGS_REGULAR_SCHEDULE = 18;
30 + const DEBUG_UPDATES_SCHEDULE = 19;
31 + const COST_TRACKER_LOG_PRIORITY = 20230112;
32 + const API_BACKUPS_LOG_PRIORITY = 20240130;
33 + const CONNECT_LOG_PRIORITY = 20241001;
34 + const UPTIME_CHECK_LOG_PRIORITY = 20241017;
35 + const UPTIME_NOTICE_LOG_PRIORITY = 20241106;
36 + const SITES_CHANGES_LOG_PRIORITY = 20250417;
37 + const CACHE_METRICS_LOG_PRIORITY = 20250814;
38 + const DB_QUERIES_LOG_PRIORITY = 20250827;
39 + const UNHOOKS_LOG_PRIORITY = 20250901;
40 + const WARM_CACHE_LOG_PRIORITY = 20250915;
41 + const EXTENSION_UPDATES_CHECK_LOG_PRIORITY = 20260306;
42 + const EXECUTION_SYNC_LOG_PRIORITY = 20260316;
43 + const EXECUTION_SYNC_DETAILS_LOG_PRIORITY = 20260323;
44 + const AUTO_UPDATES_LOG_PRIORITY = 20260707;
26 45
46 +
27 47 const DISABLED = - 1;
28 48 const LOG = 0;
29 49 const WARNING = 1;
30 50 const INFO = 2;
31 51 const DEBUG = 3;
52 + const NOTICE = 4;
32 53
33 54 const LOG_COLOR = '#999999';
34 55 const DEBUG_COLOR = '#666666';
35 56 const INFO_COLOR = '#276f86';
36 - const WARNING_COLOR = '#9f3a38;';
57 + const NOTICE_COLOR = '#eb7609';
58 + const WARNING_COLOR = '#9f3a38';
37 59
38 60 /**
39 61 * Private variable to hold time start.
40 62 *
@@ -90,9 +112,16 @@
90 112 * @var string Disabled
91 113 */
92 114 private $logSpecific = 0;
93 115
116 + /**
117 + * Private varibale to hold the auto enable logging actions.
118 + *
119 + * @var array Auto enable logging.
120 + */
121 + private $autoEnableLoggingActions = array();
94 122
123 +
95 124 /**
96 125 * Private static varibale to hold the instance.
97 126 *
98 127 * @var mixed Default null
@@ -123,8 +152,10 @@
123 152 * @uses \MainWP\Dashboard\MainWP_System_Utility::get_mainwp_dir()
124 153 */
125 154 private function __construct() {
126 155
156 + add_action( 'init', array( $this, 'init' ) ); // Fix the issue where database tables do not exist.
157 +
127 158 $enabled = $this->get_log_status();
128 159 $specific = $this->get_log_specific();
129 160
130 161 $enabled = apply_filters( 'mainwp_log_status', $enabled );
@@ -130,11 +161,30 @@
130 161 $enabled = apply_filters( 'mainwp_log_status', $enabled );
131 162 $specific = apply_filters( 'mainwp_log_specific', $specific );
132 163
133 164 $this->set_log_priority( $enabled, $specific );
165 +
166 + $this->autoEnableLoggingActions = array(
167 + static::CONNECT_LOG_PRIORITY,
168 + );
169 + add_action( 'mainwp_module_log_record_inserted', array( $this, 'hook_module_log_record_inserted' ), 10, 2 );
170 + add_filter( 'mainwp_custom_log_enabled_log_priority', array( $this, 'hook_is_enabled_log_priority' ), 10, 1 );
134 171 }
135 172
136 173 /**
174 + * Method init.
175 + */
176 + public function init() {
177 + $enabled = get_option( 'mainwp_actionlogs' );
178 + if ( false === $enabled && ! get_transient( 'mainwp_transient_action_logs' ) ) {
179 + $sites_count = MainWP_DB::instance()->get_websites_count();
180 + if ( empty( $sites_count ) ) {
181 + set_transient( 'mainwp_transient_action_logs', true, 2 * WEEK_IN_SECONDS );
182 + }
183 + }
184 + }
185 +
186 + /**
137 187 * Method set_log_priority()
138 188 *
139 189 * Sets the log priority.
140 190 *
@@ -145,8 +195,28 @@
145 195 $this->logPriority = (int) $logPriority;
146 196 $this->logSpecific = (int) $spec_log; // 1 - specific log, 0 - not specific log.
147 197 }
148 198
199 +
200 + /**
201 + * Method enable_log_priority()
202 + *
203 + * Sets the log priority.
204 + *
205 + * @param mixed $logPriority Log priority value.
206 + * @param mixed $spec_log Specific log.
207 + */
208 + public function enable_log_priority( $logPriority, $spec_log = 1 ) {
209 + $spec_log = $spec_log ? 1 : 0;
210 + $logPriority = intval( $logPriority );
211 + MainWP_Utility::update_option( 'mainwp_specific_logs', $spec_log );
212 + MainWP_Utility::update_option( 'mainwp_actionlogs', $logPriority );
213 + MainWP_Utility::update_option( 'mainwp_actionlogs_enabled_timestamp', time() );
214 + $this->log_action( 'Action logs set to: ' . $this->get_log_text( $logPriority ), ( $spec_log ? $logPriority : static::LOG ), 2, true );
215 + $this->set_log_priority( $logPriority, $spec_log );
216 + }
217 +
218 +
149 219 /**
150 220 * Method get_log_status()
151 221 *
152 222 * Get log status.
@@ -154,16 +224,11 @@
154 224 * @return mixed $enabled log status.
155 225 */
156 226 public function get_log_status() {
157 227 $enabled = get_option( 'mainwp_actionlogs' );
158 -
159 228 if ( false === $enabled ) {
160 - $sites_count = MainWP_DB::instance()->get_websites_count();
161 - if ( empty( $sites_count ) ) {
229 + if ( get_transient( 'mainwp_transient_action_logs' ) ) {
162 230 $enabled = self::DEBUG;
163 - set_transient( 'mainwp_transient_action_logs', true, 2 * WEEK_IN_SECONDS );
164 - } elseif ( get_transient( 'mainwp_transient_action_logs' ) ) {
165 - $enabled = self::DEBUG;
166 231 } else {
167 232 $enabled = static::DISABLED;
168 233 }
169 234 }
@@ -189,9 +254,9 @@
189 254 *
190 255 * @param int $type Log type value.
191 256 * @param int $logcolor Log color value.
192 257 *
193 - * @return int $currentColor log color code.
258 + * @return array $currentColor log color code.
194 259 */
195 260 public function get_log_type_info( $type, $logcolor ) {
196 261 $currentColor = '';
197 262 $prefix = '';
@@ -206,8 +271,11 @@
206 271 $prefix = '[WARNING]';
207 272 } elseif ( static::LOG === $type || static::LOG === $logcolor ) {
208 273 $currentColor = static::LOG_COLOR;
209 274 $prefix = '[LOG]';
275 + } elseif ( static::NOTICE === $type || static::NOTICE === $logcolor ) {
276 + $currentColor = static::NOTICE_COLOR;
277 + $prefix = '[NOTICE]';
210 278 }
211 279 return array(
212 280 'log_color' => $currentColor,
213 281 'log_prefix' => $prefix,
@@ -261,17 +329,77 @@
261 329 * @param string $text Warning message text.
262 330 * @param int $priority priority message.
263 331 * @param int $log_color Set color: 0 - LOG, 1 - WARNING, 2 - INFO, 3- DEBUG.
264 332 * @param bool $forced forced logging.
333 + * @param int $log_type Log type.
265 334 *
266 335 * @return string Log warning message.
267 336 */
268 - public function log_action( $text, $priority, $log_color = 0, $forced = false ) {
269 - return $this->log( $text, $priority, $log_color, $forced );
337 + public function log_action( $text, $priority, $log_color = 0, $forced = false, $log_type = 0 ) {
338 + return $this->log( $text, $priority, $log_color, $forced, false, $log_type );
270 339 }
271 340
272 341
273 342 /**
343 + * Method log_events().
344 + *
345 + * @param string $event_name Event name.
346 + * @param string $text Log update check.
347 + * @param mixed $color Log color.
348 + * @param int $log_type Log type.
349 + */
350 + public function log_events( $event_name, $text = '', $color = false, $log_type = false ) {
351 + $events = is_array( $event_name ) ? $event_name : explode( '|', $event_name );
352 + if ( is_array( $events ) ) {
353 + foreach ( $events as $event ) {
354 + switch ( $event ) {
355 + case 'update-check':
356 + $this->log_action( '[Update Checks] :: ' . $text, static::UPDATE_CHECK_LOG_PRIORITY );
357 + break;
358 + case 'regular-schedule':
359 + $this->log_action( '[Regular Schedule] :: ' . $text, static::LOGS_REGULAR_SCHEDULE );
360 + break;
361 + case 'debug-updates-crons':
362 + $this->log_action( '[Debug updates crons] :: ' . $text, static::DEBUG_UPDATES_SCHEDULE );
363 + break;
364 + case 'sites-changes':
365 + $this->log_action( '[Sites Changes] :: ' . $text, static::SITES_CHANGES_LOG_PRIORITY );
366 + break;
367 + case 'cache-metrics':
368 + $this->log_action( '[MainWP Cache] :: ' . $text, static::CACHE_METRICS_LOG_PRIORITY );
369 + break;
370 + case 'db-queries':
371 + $this->log_action( '[DB Queries] :: ' . $text, static::DB_QUERIES_LOG_PRIORITY );
372 + break;
373 + case 'unhooks':
374 + $this->log_action( '[Unhooks infor] :: ' . $text, static::UNHOOKS_LOG_PRIORITY, $color );
375 + break;
376 + case 'execution-time':
377 + $this->log_action( '[Execution time] :: ' . $text, static::EXECUTION_TIME_LOG_PRIORITY, $color );
378 + break;
379 + case 'execution-sync':
380 + $this->log_action( '[Execution Sync] :: ' . $text, static::EXECUTION_SYNC_LOG_PRIORITY, $color, false, $log_type );
381 + break;
382 + case 'execution-sync-details':
383 + $this->log_action( '[Execution Sync] :: ' . $text, static::EXECUTION_SYNC_DETAILS_LOG_PRIORITY, $color, false, $log_type );
384 + break;
385 + case 'warm-cache':
386 + $this->log_action( '[Warm cache] :: ' . $text, static::WARM_CACHE_LOG_PRIORITY, $color );
387 + break;
388 + case 'extension-updates-check':
389 + $this->log_action( '[Extension Updates Check] :: ' . $text, static::EXTENSION_UPDATES_CHECK_LOG_PRIORITY, $color );
390 + break;
391 + case 'auto-updates':
392 + $this->log_action( '[Auto Updates] :: ' . $text, static::AUTO_UPDATES_LOG_PRIORITY );
393 + break;
394 + default:
395 + break;
396 + }
397 + }
398 + }
399 + }
400 +
401 + /**
274 402 * Method log_update_check().
275 403 *
276 404 * @param string $text Log update check.
277 405 */
@@ -279,8 +407,26 @@
279 407 $this->log_action( $text, static::UPDATE_CHECK_LOG_PRIORITY );
280 408 }
281 409
282 410 /**
411 + * Method log_update_check().
412 + *
413 + * @param string $text Log update check.
414 + */
415 + public function log_uptime_check( $text = '' ) {
416 + $this->log_action( $text, static::UPTIME_CHECK_LOG_PRIORITY );
417 + }
418 +
419 + /**
420 + * Method log_uptime_notice().
421 + *
422 + * @param string $text Log update check.
423 + */
424 + public function log_uptime_notice( $text = '' ) {
425 + $this->log_action( $text, static::UPTIME_NOTICE_LOG_PRIORITY );
426 + }
427 +
428 + /**
283 429 * Method debug_for_website()
284 430 *
285 431 * Grab website debug and info.
286 432 *
@@ -357,12 +503,13 @@
357 503 * @param int $priority Set priority.
358 504 * @param int $log_color Set color.
359 505 * @param bool $forced forced logging.
360 506 * @param mixed $website website object.
507 + * @param int $log_type Log type.
361 508 *
362 509 * @return bool true|false Default is False.
363 510 */
364 - private function log_to_db( $text, $priority, $log_color = 0, $forced = false, $website = false ) {
511 + private function log_to_db( $text, $priority, $log_color = 0, $forced = false, $website = false, $log_type = false ) {
365 512
366 513 if ( static::DISABLED === $this->logPriority ) {
367 514 return false;
368 515 }
@@ -380,8 +527,12 @@
380 527 }
381 528
382 529 $do_log = apply_filters( 'mainwp_log_do_to_db', $do_log, $website );
383 530
531 + if ( ! $forced && ! $do_log ) {
532 + return false;
533 + }
534 +
384 535 $text = $this->prepare_log_info( $text );
385 536
386 537 do_action( 'mainwp_before_log_data', $text, $priority, $log_color );
387 538
@@ -388,41 +539,82 @@
388 539 if ( defined( 'DOING_CRON' ) && DOING_CRON && 'CRON' !== strtoupper( substr( $text, 0, 4 ) ) ) {
389 540 $text = 'CRON :: ' . $text;
390 541 }
391 542
392 - if ( $forced || $do_log ) {
543 + /**
544 + * Current user global.
545 + *
546 + * @global string
547 + */
548 + global $current_user;
393 549
394 - /**
395 - * Current user global.
396 - *
397 - * @global string
398 - */
399 - global $current_user;
550 + $user = '';
551 + if ( ! empty( $current_user ) && ! empty( $current_user->user_login ) ) {
552 + $user = $current_user->user_login;
553 + } elseif ( defined( 'WP_CLI' ) ) {
554 + $user = 'WP_CLI';
555 + } elseif ( defined( 'DOING_CRON' ) ) {
556 + $user = 'DOING_CRON';
557 + }
400 558
401 - $user = '';
402 - if ( ! empty( $current_user ) && ! empty( $current_user->user_login ) ) {
403 - $user = $current_user->user_login;
404 - } elseif ( defined( 'WP_CLI' ) ) {
405 - $user = 'WP_CLI';
406 - } elseif ( defined( 'DOING_CRON' ) ) {
407 - $user = 'DOING_CRON';
408 - }
559 + $data = array();
409 560
410 - $data = array();
561 + $type = false !== $log_type ? (int) $log_type : (int) $priority;
411 562
412 - $data['log_content'] = $text;
413 - $data['log_user'] = $user;
414 - $data['log_type'] = $priority;
415 - $data['log_color'] = intval( $log_color );
416 - $data['log_timestamp'] = time();
563 + $data['log_content'] = $text;
564 + $data['log_user'] = $user;
565 + $data['log_type'] = $type;
417 566
418 - $data = apply_filters( 'mainwp_log_to_db_data', $data );
567 + if ( is_int( $log_color ) || ctype_digit( (string) $log_color ) ) {
568 + $data['log_color'] = (int) $log_color;
569 + } else {
570 + $hex = sanitize_hex_color( $log_color );
571 + $data['log_color'] = $hex ? $hex : '';
572 + }
419 573
420 - MainWP_DB_Common::instance()->insert_action_log( $data );
574 + $data['log_timestamp'] = time();
421 575
422 - return true;
576 + $data = apply_filters( 'mainwp_log_to_db_data', $data );
577 +
578 + MainWP_DB_Common::instance()->insert_action_log( $data );
579 +
580 + return true;
581 + }
582 +
583 + /**
584 + * Method hook_is_enabled_log_priority().
585 + *
586 + * @param int $priority Log priority.
587 + *
588 + * @return bool true|false True if enabled log for priority.
589 + */
590 + public function hook_is_enabled_log_priority( $priority ) {
591 + return $this->enabled_log_priority( $priority );
592 + }
593 +
594 + /**
595 + * Method enabled_log_priority()
596 + *
597 + * @param int $priority Set priority.
598 + *
599 + * @return bool true|false Default is False.
600 + */
601 + public function enabled_log_priority( $priority ) {
602 +
603 + if ( static::DISABLED === $this->logPriority ) {
604 + return false;
423 605 }
424 - return false;
606 +
607 + $priority = (int) apply_filters( 'mainwp_log_to_db_priority', $priority );
608 + $do_log = false;
609 + if ( 1 === $this->logSpecific ) { // 1 - specific log, 0 - not specific log.
610 + if ( $this->logPriority === $priority ) { // specific priority number saved setting.
611 + $do_log = true;
612 + }
613 + } elseif ( $this->logPriority >= $priority ) {
614 + $do_log = true;
615 + }
616 + return $do_log;
425 617 }
426 618
427 619 /**
428 620 * Method log()
@@ -433,21 +625,26 @@
433 625 * @param int $priority Set priority.
434 626 * @param int $log_color Set color.
435 627 * @param bool $forced forced logging.
436 628 * @param mixed $website Site object.
629 + * @param int $log_type Log type.
437 630 *
438 631 * @return bool true|false Default is False.
439 632 */
440 - private function log( $text, $priority, $log_color = 0, $forced = false, $website = false ) { // phpcs:ignore -- NOSONAR - complex function.
633 + private function log( $text, $priority, $log_color = 0, $forced = false, $website = false, $log_type = false ) { // phpcs:ignore -- NOSONAR - complex function.
441 634
635 + if ( in_array( $priority, $this->autoEnableLoggingActions ) && (int) $this->logPriority !== (int) $priority ) {
636 + $this->enable_log_priority( $priority, 1 );
637 + }
638 +
442 639 if ( static::DISABLED === $this->logPriority ) {
443 - return;
640 + return false;
444 641 }
445 642
446 643 $log_to_db = apply_filters( 'mainwp_logger_to_db', true, $website );
447 644
448 645 if ( $log_to_db ) {
449 - return $this->log_to_db( $text, $priority, $log_color, $forced, $website );
646 + return $this->log_to_db( $text, $priority, $log_color, $forced, $website, $log_type );
450 647 }
451 648
452 649 $text = $this->prepare_log_info( $text );
453 650
@@ -536,15 +733,29 @@
536 733 *
537 734 * @return mixed $data filtered data.
538 735 */
539 736 public function prepare_log_info( $data ) {
540 - $patterns[0] = '/user=([^\&]+)\&/';
541 - $replacement[0] = 'user=xxxxxx&';
542 - $patterns[1] = '/alt_user=([^\&]+)\&/';
543 - $replacement[1] = 'alt_user=xxxxxx&';
544 - $patterns[2] = '/\&server=([^\&]+)\&/';
545 - $replacement[2] = '&server=xxxxxx&';
546 - $data = preg_replace( $patterns, $replacement, $data );
737 + $patterns[] = '/user=([^\&]+)\&/';
738 + $replacement[] = 'user=xxxxxx&';
739 + $patterns[] = '/alt_user=([^\&]+)\&/';
740 + $replacement[] = 'alt_user=xxxxxx&';
741 + $patterns[] = '/\&server=([^\&]+)\&/';
742 + $replacement[] = '&server=xxxxxx&';
743 + $patterns[] = '/(^|[?&])data_signature=[^&]*/';
744 + $replacement[] = '$1data_signature=xxxxxx';
745 + $patterns[] = '/(^|[?&])mainwpsignature=[^&]*/';
746 + $replacement[] = '$mainwpsignature=xxxxxx';
747 + $patterns[] = '/(^|[?&])nonce=[^&]*/';
748 + $replacement[] = '$nonce=xxxxxx';
749 + $patterns[] = '/(^|[?&])req_id=[^&]*/';
750 + $replacement[] = '$req_id=xxxxxx';
751 + $patterns[] = '/(^|[?&])mainwpsignature_adv=[^&]*/';
752 + $replacement[] = '$mainwpsignature_adv=xxxxxx';
753 + $patterns[] = '/(^|[?&])wp_http_user=[^&]*/';
754 + $replacement[] = '$wp_http_user=xxxxxx';
755 + $patterns[] = '/(^|[?&])wp_http_pass=[^&]*/';
756 + $replacement[] = '$wp_http_pass=xxxxxx';
757 + $data = preg_replace( $patterns, $replacement, $data );
547 758 return $data;
548 759 }
549 760
550 761 /**
@@ -593,12 +804,126 @@
593 804 * Log the execution time value.
594 805 */
595 806 public function log_execution_time( $text = '' ) {
596 807 $exec_time = $this->get_execution_time();
597 - $this->log_action( 'execution time :: ' . ( ! empty( $text ) ? (string) $text : '<empty>' ) . ' :: [time=' . round( $exec_time, 4 ) . '](seconds)', static::EXECUTION_TIME_LOG_PRIORITY );
808 + $this->log_action( 'execution time :: ' . ( ! empty( $text ) ? (string) $text . ' :: ' : '' ) . ' [time=' . round( $exec_time, 4 ) . '](seconds)', static::EXECUTION_TIME_LOG_PRIORITY );
598 809 }
599 810
811 + /**
812 + * Method log_execution_sync().
813 + *
814 + * @param string $progress Log progress value.
815 + * @param string $text Log record text.
816 + * @param mixed $website Website data, default false.
817 + *
818 + * Log the execution sync time value.
819 + */
820 + public function log_execution_sync( $progress = '', $text = '', $website = false ) { // phpcs:ignore -- NOSONAR -complex.
600 821
822 + if ( 1 !== $this->logSpecific || ( static::EXECUTION_SYNC_LOG_PRIORITY !== $this->logPriority && static::EXECUTION_SYNC_DETAILS_LOG_PRIORITY !== $this->logPriority ) ) { // 1 - specific log, 0 - not specific log.
823 + return;
824 + }
825 +
826 + static $initialized = false;
827 +
828 + if ( 'init' === $progress && ! $initialized ) {
829 + $initialized = true;
830 + MainWP_Execution_Helper::init_http_call_track();
831 + }
832 +
833 + // If the process has ended and the sync event log is not initialized, do not log.
834 + if ( 'end' === $progress && ! $initialized ) {
835 + return;
836 + }
837 +
838 + $text = 'init' === $progress && empty( $text ) ? 'Init' : $text;
839 + $text = 'end' === $progress && empty( $text ) ? 'End' : $text;
840 +
841 + $exec_time = $this->get_execution_time();
842 + $exec_time = round( $exec_time, 4 );
843 +
844 + if ( ! empty( $text ) ) {
845 + $text = $text . ' :: ';
846 + }
847 +
848 + $id = '';
849 +
850 + if ( ! empty( $website ) ) {
851 +
852 + if ( is_int( $website ) || ctype_digit( $website ) ) {
853 + $id = (int) $website;
854 + } elseif ( is_array( $website ) && ! empty( $website['id'] ) ) {
855 + $id = $website['id'];
856 + } elseif ( is_object( $website ) && property_exists( $website, 'id' ) ) {
857 + $id = $website->id;
858 + }
859 + } else {
860 + $id = MainWP_System_Utility::get_current_wpid();
861 + }
862 +
863 + if ( ! empty( $id ) ) {
864 + $text .= '[siteid=' . $id . '] :: ';
865 + }
866 +
867 + $log = $text . '[total runtime=' . $exec_time . '](sec)';
868 +
869 + $mem = '';
870 +
871 + if ( function_exists( 'memory_get_usage' ) && is_callable( 'memory_get_usage' ) ) {
872 + $mem = round( memory_get_usage() / 1024 / 1024, 2 );
873 + } else {
874 + $mem = 'N/A';
875 + }
876 +
877 + if ( ! empty( $mem ) ) {
878 + $log .= ' :: [memory usage=' . $mem . '](MB)';
879 + }
880 +
881 + if ( 'end' === $progress ) {
882 + $dbusage = MainWP_Execution_Helper::get_queries_stats();
883 + if ( is_array( $dbusage ) ) {
884 + if ( isset( $dbusage['total_queries'] ) ) {
885 + $log .= ' :: [total queries=' . (int) $dbusage['total_queries'] . ']';
886 + }
887 + if ( isset( $dbusage['total_runtime'] ) ) {
888 + $log .= ' :: [total runtime queries=' . sprintf( '%.5f', $dbusage['total_runtime'] ) . '](sec)';
889 + }
890 + }
891 +
892 + $callstats = MainWP_Execution_Helper::get_exec_call_stats();
893 +
894 + $rows_details = array();
895 +
896 + if ( is_array( $callstats ) ) {
897 + if ( isset( $callstats['check_count'] ) ) {
898 + $log .= ' :: [total run check=' . (int) $callstats['check_count'] . ']';
899 + }
900 + if ( isset( $callstats['exec_time'] ) && is_array( $callstats['exec_time'] ) ) {
901 + foreach ( $callstats['exec_time'] as $idx => $t ) {
902 + $rows_details[] = '[check runtime=' . sprintf( '%.3f', $t ) . '](sec) :: [run desc=' . ( ! empty( $callstats['check_desc'][ $idx ] ) ? (string) $callstats['check_desc'][ $idx ] : '' ) . ']';
903 + if ( static::EXECUTION_SYNC_DETAILS_LOG_PRIORITY === $this->logPriority ) {
904 + $rows_details[] = '[run data=' . ( ! empty( $callstats['check_data'][ $idx ] ) && is_array( $callstats['check_data'][ $idx ] ) ? wp_json_encode( $callstats['check_data'][ $idx ] ) : '' ) . ']';
905 + }
906 + }
907 + }
908 + }
909 + }
910 +
911 + $log .= ' :: [ver=' . MainWP_System::get_mainwp_version() . ']';
912 +
913 + $lg_type = (int) $exec_time >= 50 ? static::NOTICE : static::INFO;
914 + $lg_type = (int) $exec_time >= 80 ? static::WARNING : $lg_type;
915 +
916 + $event_name = static::EXECUTION_SYNC_DETAILS_LOG_PRIORITY === $this->logPriority ? 'execution-sync-details' : 'execution-sync';
917 + $this->log_events( $event_name, $log, false, $lg_type );
918 +
919 + if ( ! empty( $rows_details ) ) {
920 + foreach ( $rows_details as $log_detail ) {
921 + $this->log_events( $event_name, $log_detail, false, static::LOG );
922 + }
923 + }
924 + }
925 +
601 926 /**
602 927 * Method get_execution_time().
603 928 *
604 929 * Get the execution time value.
@@ -722,32 +1047,73 @@
722 1047 * Method show_log_db()
723 1048 *
724 1049 * Grab log file and build output to screen.
725 1050 */
726 - public function show_log_db() {
1051 + public function show_log_db() { //phpcs:ignore -- NOSONAR - complexity.
727 1052
728 1053 echo '<div class="ui hidden divider"></div>';
729 1054 echo '<div class="ui divided padded relaxed list" local-datetime="' . date( 'Y-m-d H:i:s' ) . '">'; // phpcs:ignore -- local time.
730 1055
731 - $rows = MainWP_DB::instance()->query( MainWP_DB_Common::instance()->get_sql_log() );
1056 + $limit = 500;
732 1057
1058 + //phpcs:disable WordPress.Security.NonceVerification
1059 + $paged = isset( $_GET['paged'] ) ? intval( $_GET['paged'] ) : 0; //phpcs:ignore -- NOSONAR -ok.
1060 +
1061 + if ( $paged <= 0 ) {
1062 + $paged = 0;
1063 + } else {
1064 + --$paged;
1065 + }
1066 +
1067 + $params = array();
1068 +
1069 + if ( isset( $_GET['hour'] ) && ! empty( $_GET['hour'] ) ) { // phpcs:ignore -- local time.
1070 + $params['hour'] = intval( $_GET['hour'] ); // phpcs:ignore -- local time.
1071 + } else {
1072 + $params['hour'] = $limit;
1073 + }
1074 +
1075 + $order = isset( $_GET['order'] ) ? sanitize_text_field( wp_unslash( $_GET['order'] ) ) : ''; //phpcs:ignore -- NOSONAR -ok.
1076 +
1077 + $total = MainWP_DB::instance()->get_var_field( MainWP_DB_Common::instance()->get_sql_log( $paged, $order, array( 'count' => true ) ) );
1078 +
1079 + $rows = MainWP_DB::instance()->query( MainWP_DB_Common::instance()->get_sql_log( $paged, $order, $params ) );
1080 +
1081 + $count = $rows ? MainWP_DB::num_rows( $rows ) : 0;
1082 +
1083 + $show_info = '';
1084 +
1085 + if ( isset( $_GET['hour'] ) ) {
1086 + $show_info = $count . ' latest items from a total of ' . $total;
1087 + } elseif ( isset( $_GET['paged'] ) ) { //phpcs:ignore -- NOSONAR -ok.
1088 + $from = $limit * $paged;
1089 + $show_info = $count . ' items, from ' . $from . ' - ' . ( $from + $limit ) . ' of ' . $total . ' total.';
1090 + }
1091 +
1092 + if ( ! empty( $show_info ) ) {
1093 + echo '<p><strong>' . esc_html__( 'Showing ', 'mainwp' ) . ':</strong> ' . $show_info; //phpcs:ignore -- NOSONAR ok.
1094 + }
1095 + //phpcs:enable WordPress.Security.NonceVerification
1096 +
733 1097 $start_wrapper = '<span class="ui mini label mainwp-action-log-show-more">Click to See Response</span><div class="mainwp-action-log-site-response" style="display: none;">';
734 1098 $end_wrapper = '</div>';
735 1099
736 1100 while ( $rows && ( $row = MainWP_DB::fetch_object( $rows ) ) ) {
737 1101 $line = $row->log_content;
738 - if ( 120 * 1024 < strlen( $line ) ) {
739 - $line = '[Data row too long]';
1102 + if ( strlen( $line ) > 120 * KB_IN_BYTES ) {
1103 + $size_kb = round( strlen( $line ) / KB_IN_BYTES, 1 );
1104 + $line = sprintf( '[Data row too long] :: [size=%s KB]', $size_kb );
740 1105 }
741 1106
742 - $time = gmdate( $this->logDateFormat, $row->log_timestamp );
1107 + $time = gmdate( $this->logDateFormat, MainWP_Utility::get_timestamp( $row->log_timestamp ) );
743 1108
744 - $showInfo = $this->get_log_type_info( $row->log_type, $row->log_color );
1109 + $showInfo = $this->get_log_type_info( (int) $row->log_type, $row->log_color );
1110 +
745 1111 $currentColor = $showInfo['log_color'];
746 1112
747 1113 $prefix = $time . ' ' . $showInfo['log_prefix'];
748 1114
749 - $line = htmlentities( $line );
1115 + $line = nl2br( htmlentities( $line ) );
750 1116
751 1117 if ( false !== strpos( $line, '[data-start]' ) ) {
752 1118 $line = str_replace( '[data-start]', $start_wrapper, $line );
753 1119 $line = str_replace( '[data-end]', $end_wrapper, $line );
@@ -752,9 +1118,9 @@
752 1118 $line = str_replace( '[data-start]', $start_wrapper, $line );
753 1119 $line = str_replace( '[data-end]', $end_wrapper, $line );
754 1120 }
755 1121
756 - echo '<div class="item" style="color:' . esc_html( $currentColor ) . '"><div class="mainwpactionlogsline">';
1122 + echo '<div class="item" style="color:' . esc_attr( $currentColor ) . '"><div class="mainwpactionlogsline">';
757 1123
758 1124 echo $prefix . ' ' . $line; // phpcs:ignore WordPress.Security.EscapeOutput
759 1125
760 1126 echo '</div></div>';
@@ -859,6 +1225,20 @@
859 1225 </div>
860 1226 <?php
861 1227
862 1228 fclose( $fh );
1229 + }
1230 +
1231 + /**
1232 + * Method hook_module_log_record_inserted()
1233 + *
1234 + * @param int $record_id Log id.
1235 + * @param array $record Log data.
1236 + *
1237 + * @return void
1238 + */
1239 + public function hook_module_log_record_inserted( $record_id = false, $record = false ) {
1240 + if ( $record_id && is_array( $record ) && isset( $record['connector'] ) && isset( $record['action'] ) && isset( $record['item'] ) && isset( $record['context'] ) ) {
1241 + $this->log_events( 'sites-changes', 'Logging info :: [site_id=' . ( isset( $record['site_id'] ) ? $record['site_id'] : 0 ) . '] :: [log_id=' . $record_id . '] :: [log_type_id=' . ( isset( $record['log_type_id'] ) ? $record['log_type_id'] : 0 ) . '] :: [item=' . $record['item'] . '] :: [connector=' . $record['connector'] . '] :: [context=' . $record['context'] . '] :: [action=' . $record['action'] . ']' );
1242 + }
863 1243 }
864 1244 }