PluginProbe
Code Profiler – WordPress Performance Profiling and Debugging Made Easy / 1.7.4
Code Profiler – WordPress Performance Profiling and Debugging Made Easy v1.7.4
1.9.5 1.9.4 1.9.3 trunk 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.5 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.6 1.6.1 1.6.10 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 All 40 releases
← All changes | lib/class-profiler.php +123 -29 1.61.7.4 View file →
@@ -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'); }
@@ -17,14 +17,19 @@
17 17
18 18 class CodeProfiler_Profiler {
19 19
20 20 static $tick_list;
21 - static $buffer = 10000000;
21 + static $buffer;
22 22 static $metrics;
23 + static $fh;
24 + static $connections_list = [];
25 + static $connections_start;
26 + static $exclusions = [];
23 27 private $tmp_iostats;
24 28 private $tmp_summary;
25 29 private $tmp_diskio;
26 - private $tmp_ticks;
30 + private $tmp_calls;
31 + private $tmp_connections;
27 32
28 33 /**
29 34 * Initialize
30 35 */
@@ -31,27 +36,59 @@
31 36 public function __construct() {
32 37
33 38 $microtime = sanitize_file_name( $_REQUEST['CODE_PROFILER_ON'] );
34 39
35 - $this->tmp_summary = CODE_PROFILER_UPLOAD_DIR ."/$microtime." .
36 - CODE_PROFILER_TMP_SUMMARY_LOG;
37 - $this->tmp_iostats = CODE_PROFILER_UPLOAD_DIR ."/$microtime." .
38 - CODE_PROFILER_TMP_IOSTATS_LOG;
39 - $this->tmp_ticks = CODE_PROFILER_UPLOAD_DIR ."/$microtime." .
40 - CODE_PROFILER_TMP_TICKS_LOG;
41 - $this->tmp_diskio = CODE_PROFILER_UPLOAD_DIR ."/$microtime." .
42 - CODE_PROFILER_TMP_DISKIO_LOG;
40 + $this->tmp_summary = CODE_PROFILER_UPLOAD_DIR ."/$microtime." .
41 + CODE_PROFILER_TMP_SUMMARY_LOG;
42 + $this->tmp_iostats = CODE_PROFILER_UPLOAD_DIR ."/$microtime." .
43 + CODE_PROFILER_TMP_IOSTATS_LOG;
44 + $this->tmp_calls = CODE_PROFILER_UPLOAD_DIR ."/$microtime." .
45 + CODE_PROFILER_TMP_CALLS_LOG;
46 + $this->tmp_diskio = CODE_PROFILER_UPLOAD_DIR ."/$microtime." .
47 + CODE_PROFILER_TMP_DISKIO_LOG;
48 + $this->tmp_connections = CODE_PROFILER_UPLOAD_DIR ."/$microtime." .
49 + CODE_PROFILER_TMP_CONNECTIONS_LOG;
43 50
44 - // Clear the temporary log because the buffer will be written
45 - // with the FILE_APPEND flag
46 - if ( file_exists( $this->tmp_ticks ) ) {
47 - unlink( $this->tmp_ticks );
51 + if ( function_exists('hrtime') ) {
52 + // PHP >=7.3
53 + self::$metrics = 'hrtime';
54 + } else {
55 + self::$metrics = 'microtime';
48 56 }
49 57
50 - if ( version_compare( PHP_VERSION, '7.3', '<') ) {
51 - self::$metrics = 'microtime';
52 - } else {
53 - self::$metrics = 'hrtime';
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 + }
54 91 }
55 92
56 93 $cp_options = get_option('code-profiler');
57 94 if ( empty( $cp_options['accuracy'] ) ) {
@@ -60,11 +97,42 @@
60 97 define('CODE_PROFILER_TICKS', (int) $cp_options['accuracy'] );
61 98 }
62 99 define('CODE_PROFILER_LENGTH', 17 + strlen( (string) CODE_PROFILER_TICKS ) );
63 100
64 - register_shutdown_function( array( $this, 'code_profiler_shutdown') );
101 + if ( empty( $cp_options['buffer'] ) ||
102 + ! preg_match('/^(?:[1-9]|10)$/', $cp_options['buffer'] ) ) {
65 103
104 + $recommended = code_profiler_suggested_memory();
105 + self::$buffer = (int) $recommended * 1000000;
106 + } else {
107 + self::$buffer = $cp_options['buffer'] * 1000000;
108 + }
109 + code_profiler_log_debug(
110 + sprintf(
111 + esc_html__('Setting size of memory buffer to %sMB', 'code-profiler'),
112 + self::$buffer / 1000000
113 + )
114 + );
115 +
116 + // File & folder exclusions
117 + if ( isset( $cp_options['exclusions'] ) ) {
118 + self::$exclusions = json_decode( $cp_options['exclusions'] );
119 + }
120 +
121 + add_filter('pre_http_request', [ $this, 'pre_http_request'], 10000, 3 );
122 + add_action('http_api_debug', [ $this, 'http_api_debug'], 10000, 5 );
123 + register_shutdown_function( [ $this, 'code_profiler_shutdown'] );
124 + code_profiler_log_debug(
125 + esc_html__('Starting profiler', 'code-profiler')
126 + );
66 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 +
67 135 CodeProfiler_Stream::start();
68 136 register_tick_function( array( $this, 'code_profiler_tick_handler') );
69 137 }
70 138
@@ -74,10 +142,13 @@
74 142 public function code_profiler_shutdown() {
75 143
76 144 CodeProfiler_Stream::stop();
77 145
78 - $summary['memory'] = memory_get_peak_usage();
79 - $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;
80 151 file_put_contents( $this->tmp_summary, json_encode( $summary ) );
81 152
82 153 // Catch potential error
83 154 $e = error_get_last();
@@ -97,11 +168,11 @@
97 168 if ( $res === false ) {
98 169 $msg = sprintf( $err_msg, $this->tmp_iostats );
99 170 code_profiler_log_error( $msg );
100 171 }
101 - $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 );
102 173 if ( $res === false ) {
103 - $msg = sprintf( $err_msg, $this->tmp_ticks );
174 + $msg = sprintf( $err_msg, $this->tmp_calls );
104 175 code_profiler_log_error( $msg );
105 176 }
106 177 $res = file_put_contents(
107 178 $this->tmp_diskio, "read\t". CodeProfiler_Stream::$io_read ."\nwrite\t".
@@ -106,8 +177,11 @@
106 177 $res = file_put_contents(
107 178 $this->tmp_diskio, "read\t". CodeProfiler_Stream::$io_read ."\nwrite\t".
108 179 CodeProfiler_Stream::$io_write
109 180 );
181 + if (! empty( self::$connections_list ) ) {
182 + file_put_contents( $this->tmp_connections, json_encode( self::$connections_list) );
183 + }
110 184 }
111 185
112 186 /**
113 187 * Our tick handler.
@@ -136,17 +210,14 @@
136 210 self::$tick_list .= $backtrace[0]['file'];
137 211 } else {
138 212 self::$tick_list .= '-';
139 213 }
214 + $backtrace = null;
140 215
141 216 // Buffer can grow *very* big hence we flush it every 10MB by default
142 217 if ( strlen( self::$tick_list ) > self::$buffer ) {
143 218 CodeProfiler_Stream::stop();
144 - file_put_contents(
145 - $this->tmp_ticks,
146 - self::$tick_list ."\t{$start}\t". $this->time() ."\n",
147 - FILE_APPEND
148 - );
219 + fwrite( self::$fh, self::$tick_list ."\t{$start}\t". $this->time() ."\n" );
149 220 CodeProfiler_Stream::start();
150 221 self::$tick_list = '';
151 222
152 223 } else {
@@ -153,8 +224,31 @@
153 224 self::$tick_list .="\t{$start}\t". $this->time() ."\n";
154 225 }
155 226 }
156 227
228 +
229 + /**
230 + * HTTP API request.
231 + */
232 + public function pre_http_request( $preempt, $r, $url ) {
233 +
234 + if ( empty( $url ) ) {
235 + return false;
236 + }
237 + $backtrace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
238 + self::$connections_start = $this->time();
239 + self::$connections_list[ self::$connections_start ]['bt'] = $backtrace;
240 + return false;
241 + }
242 +
243 +
244 + /**
245 + * HTTP API response.
246 + */
247 + public function http_api_debug( $response, $context, $class, $parsed_args, $url ) {
248 +
249 + self::$connections_list[ self::$connections_start ]['stop'] = $this->time();
250 + }
157 251
158 252 /**
159 253 * Return time
160 254 */