| @@ -6,9 +6,9 @@ | ||
| 6 | 6 | | | | / _ \ / _` |/ _ \ | |_) | '__/ _ \| |_| | |/ _ \ '__| | |
| 7 | 7 | | | |__| (_) | (_| | __/ | __/| | | (_) | _| | | __/ | | |
| 8 | 8 | | \____\___/ \__,_|\___| |_| |_| \___/|_| |_|_|\___|_| | |
| 9 | 9 | | | |
| 10 | - | (c) Jerome Bruandet ~ https://code-profiler.com/ | | |
| 10 | + | (c) Jerome Bruandet ~ https://nintechnet.com/codeprofiler/ | | |
| 11 | 11 | +=====================================================================+ |
| 12 | 12 | */ |
| 13 | 13 | |
| 14 | 14 | if (! defined('ABSPATH') ) { die('Forbidden'); } |
| @@ -19,14 +19,17 @@ | ||
| 19 | 19 | |
| 20 | 20 | static $tick_list; |
| 21 | 21 | static $buffer; |
| 22 | 22 | static $metrics; |
| 23 | + static $fh; | |
| 23 | 24 | static $connections_list = []; |
| 24 | 25 | static $connections_start; |
| 26 | + static $exclusions = []; | |
| 25 | 27 | private $tmp_iostats; |
| 26 | 28 | private $tmp_summary; |
| 27 | 29 | private $tmp_diskio; |
| 28 | - private $tmp_ticks; | |
| 30 | + private $tmp_calls; | |
| 31 | + private $tmp_connections; | |
| 29 | 32 | |
| 30 | 33 | /** |
| 31 | 34 | * Initialize |
| 32 | 35 | */ |
| @@ -37,21 +40,15 @@ | ||
| 37 | 40 | $this->tmp_summary = CODE_PROFILER_UPLOAD_DIR ."/$microtime." . |
| 38 | 41 | CODE_PROFILER_TMP_SUMMARY_LOG; |
| 39 | 42 | $this->tmp_iostats = CODE_PROFILER_UPLOAD_DIR ."/$microtime." . |
| 40 | 43 | CODE_PROFILER_TMP_IOSTATS_LOG; |
| 41 | - $this->tmp_ticks = CODE_PROFILER_UPLOAD_DIR ."/$microtime." . | |
| 42 | - CODE_PROFILER_TMP_TICKS_LOG; | |
| 44 | + $this->tmp_calls = CODE_PROFILER_UPLOAD_DIR ."/$microtime." . | |
| 45 | + CODE_PROFILER_TMP_CALLS_LOG; | |
| 43 | 46 | $this->tmp_diskio = CODE_PROFILER_UPLOAD_DIR ."/$microtime." . |
| 44 | 47 | CODE_PROFILER_TMP_DISKIO_LOG; |
| 45 | 48 | $this->tmp_connections = CODE_PROFILER_UPLOAD_DIR ."/$microtime." . |
| 46 | 49 | CODE_PROFILER_TMP_CONNECTIONS_LOG; |
| 47 | 50 | |
| 48 | - // Clear the temporary log because the buffer will be written | |
| 49 | - // with the FILE_APPEND flag | |
| 50 | - if ( file_exists( $this->tmp_ticks ) ) { | |
| 51 | - unlink( $this->tmp_ticks ); | |
| 52 | - } | |
| 53 | - | |
| 54 | 51 | if ( function_exists('hrtime') ) { |
| 55 | 52 | // PHP >=7.3 |
| 56 | 53 | self::$metrics = 'hrtime'; |
| 57 | 54 | } else { |
| @@ -57,8 +54,43 @@ | ||
| 57 | 54 | } else { |
| 58 | 55 | self::$metrics = 'microtime'; |
| 59 | 56 | } |
| 60 | 57 | |
| 58 | + // Select theme (stylesheet::template) | |
| 59 | + if (! empty( $_SERVER['HTTP_THEME'] ) ) { | |
| 60 | + | |
| 61 | + $theme = explode('::', $_SERVER['HTTP_THEME'] ); | |
| 62 | + if (! empty( $theme[1] ) ) { | |
| 63 | + define('CODE_PROFILER_STYLESHEET', sanitize_file_name( $theme[0] ) ); | |
| 64 | + define('CODE_PROFILER_TEMPLATE', sanitize_file_name( $theme[1] ) ); | |
| 65 | + | |
| 66 | + if ( is_file( WP_CONTENT_DIR .'/themes/'. CODE_PROFILER_STYLESHEET .'/style.css' ) ) { | |
| 67 | + | |
| 68 | + add_filter('pre_option_template', function () { | |
| 69 | + return CODE_PROFILER_TEMPLATE; | |
| 70 | + }, 1000 ); | |
| 71 | + | |
| 72 | + add_filter('pre_option_stylesheet', function () { | |
| 73 | + return CODE_PROFILER_STYLESHEET; | |
| 74 | + }, 1000 ); | |
| 75 | + | |
| 76 | + code_profiler_log_debug( | |
| 77 | + sprintf( | |
| 78 | + esc_html__('Setting theme to %s', 'code-profiler'), | |
| 79 | + CODE_PROFILER_STYLESHEET | |
| 80 | + ) | |
| 81 | + ); | |
| 82 | + } else { | |
| 83 | + code_profiler_log_error( | |
| 84 | + sprintf( | |
| 85 | + esc_html__('Unable to switch theme, %s not found', 'code-profiler'), | |
| 86 | + CODE_PROFILER_STYLESHEET | |
| 87 | + ) | |
| 88 | + ); | |
| 89 | + } | |
| 90 | + } | |
| 91 | + } | |
| 92 | + | |
| 61 | 93 | $cp_options = get_option('code-profiler'); |
| 62 | 94 | if ( empty( $cp_options['accuracy'] ) ) { |
| 63 | 95 | define('CODE_PROFILER_TICKS', 1 ); |
| 64 | 96 | } else { |
| @@ -80,8 +112,13 @@ | ||
| 80 | 112 | self::$buffer / 1000000 |
| 81 | 113 | ) |
| 82 | 114 | ); |
| 83 | 115 | |
| 116 | + // File & folder exclusions | |
| 117 | + if ( isset( $cp_options['exclusions'] ) ) { | |
| 118 | + self::$exclusions = json_decode( $cp_options['exclusions'] ); | |
| 119 | + } | |
| 120 | + | |
| 84 | 121 | add_filter('pre_http_request', [ $this, 'pre_http_request'], 10000, 3 ); |
| 85 | 122 | add_action('http_api_debug', [ $this, 'http_api_debug'], 10000, 5 ); |
| 86 | 123 | register_shutdown_function( [ $this, 'code_profiler_shutdown'] ); |
| 87 | 124 | code_profiler_log_debug( |
| @@ -87,8 +124,15 @@ | ||
| 87 | 124 | code_profiler_log_debug( |
| 88 | 125 | esc_html__('Starting profiler', 'code-profiler') |
| 89 | 126 | ); |
| 90 | 127 | require 'class-stream.php'; |
| 128 | + | |
| 129 | + // Clear the temporary log because the buffer will be appended to it | |
| 130 | + if ( file_exists( $this->tmp_calls ) ) { | |
| 131 | + unlink( $this->tmp_calls ); | |
| 132 | + } | |
| 133 | + self::$fh = fopen( $this->tmp_calls, 'wb'); | |
| 134 | + | |
| 91 | 135 | CodeProfiler_Stream::start(); |
| 92 | 136 | register_tick_function( array( $this, 'code_profiler_tick_handler') ); |
| 93 | 137 | } |
| 94 | 138 | |
| @@ -98,10 +142,13 @@ | ||
| 98 | 142 | public function code_profiler_shutdown() { |
| 99 | 143 | |
| 100 | 144 | CodeProfiler_Stream::stop(); |
| 101 | 145 | |
| 102 | - $summary['memory'] = memory_get_peak_usage(); | |
| 103 | - $summary['queries'] = get_num_queries() - 2; | |
| 146 | + fclose( self::$fh ); | |
| 147 | + | |
| 148 | + $summary['memory'] = memory_get_peak_usage(); | |
| 149 | + $summary['queries'] = get_num_queries() - 2; | |
| 150 | + $summary['precision'] = CODE_PROFILER_TICKS; | |
| 104 | 151 | file_put_contents( $this->tmp_summary, json_encode( $summary ) ); |
| 105 | 152 | |
| 106 | 153 | // Catch potential error |
| 107 | 154 | $e = error_get_last(); |
| @@ -121,11 +168,11 @@ | ||
| 121 | 168 | if ( $res === false ) { |
| 122 | 169 | $msg = sprintf( $err_msg, $this->tmp_iostats ); |
| 123 | 170 | code_profiler_log_error( $msg ); |
| 124 | 171 | } |
| 125 | - $res = file_put_contents( $this->tmp_ticks, self::$tick_list, FILE_APPEND ); | |
| 172 | + $res = file_put_contents( $this->tmp_calls, self::$tick_list, FILE_APPEND ); | |
| 126 | 173 | if ( $res === false ) { |
| 127 | - $msg = sprintf( $err_msg, $this->tmp_ticks ); | |
| 174 | + $msg = sprintf( $err_msg, $this->tmp_calls ); | |
| 128 | 175 | code_profiler_log_error( $msg ); |
| 129 | 176 | } |
| 130 | 177 | $res = file_put_contents( |
| 131 | 178 | $this->tmp_diskio, "read\t". CodeProfiler_Stream::$io_read ."\nwrite\t". |
| @@ -168,13 +215,9 @@ | ||
| 168 | 215 | |
| 169 | 216 | // Buffer can grow *very* big hence we flush it every 10MB by default |
| 170 | 217 | if ( strlen( self::$tick_list ) > self::$buffer ) { |
| 171 | 218 | CodeProfiler_Stream::stop(); |
| 172 | - file_put_contents( | |
| 173 | - $this->tmp_ticks, | |
| 174 | - self::$tick_list ."\t{$start}\t". $this->time() ."\n", | |
| 175 | - FILE_APPEND | |
| 176 | - ); | |
| 219 | + fwrite( self::$fh, self::$tick_list ."\t{$start}\t". $this->time() ."\n" ); | |
| 177 | 220 | CodeProfiler_Stream::start(); |
| 178 | 221 | self::$tick_list = ''; |
| 179 | 222 | |
| 180 | 223 | } else { |