PluginProbe
Code Profiler – WordPress Performance Profiling and Debugging Made Easy / 1.9.6
Code Profiler – WordPress Performance Profiling and Debugging Made Easy v1.9.6
1.9.6 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 All 41 releases
← All changes | lib/class-profiler.php +99 -24 1.6.21.9.6 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,16 +17,20 @@
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;
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;
32 + private $tmp_rerun;
29 33
30 34 /**
31 35 * Initialize
32 36 */
@@ -37,25 +41,59 @@
37 41 $this->tmp_summary = CODE_PROFILER_UPLOAD_DIR ."/$microtime." .
38 42 CODE_PROFILER_TMP_SUMMARY_LOG;
39 43 $this->tmp_iostats = CODE_PROFILER_UPLOAD_DIR ."/$microtime." .
40 44 CODE_PROFILER_TMP_IOSTATS_LOG;
41 - $this->tmp_ticks = CODE_PROFILER_UPLOAD_DIR ."/$microtime." .
42 - CODE_PROFILER_TMP_TICKS_LOG;
45 + $this->tmp_calls = CODE_PROFILER_UPLOAD_DIR ."/$microtime." .
46 + CODE_PROFILER_TMP_CALLS_LOG;
43 47 $this->tmp_diskio = CODE_PROFILER_UPLOAD_DIR ."/$microtime." .
44 48 CODE_PROFILER_TMP_DISKIO_LOG;
45 49 $this->tmp_connections = CODE_PROFILER_UPLOAD_DIR ."/$microtime." .
46 50 CODE_PROFILER_TMP_CONNECTIONS_LOG;
51 + $this->tmp_rerun = CODE_PROFILER_UPLOAD_DIR ."/$microtime." .
52 + CODE_PROFILER_TMP_RERUN_LOG;
47 53
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 );
54 + if ( function_exists('hrtime') ) {
55 + // PHP >=7.3
56 + self::$metrics = 'hrtime';
57 + } else {
58 + self::$metrics = 'microtime';
52 59 }
53 60
54 - if ( version_compare( PHP_VERSION, '7.3', '<') ) {
55 - self::$metrics = 'microtime';
56 - } else {
57 - self::$metrics = 'hrtime';
61 + // Select theme (stylesheet::template)
62 + if (! empty( $_SERVER['HTTP_THEME'] ) ) {
63 +
64 + $theme = explode('::', $_SERVER['HTTP_THEME'] );
65 + if (! empty( $theme[1] ) ) {
66 + define('CODE_PROFILER_STYLESHEET', sanitize_file_name( $theme[0] ) );
67 + define('CODE_PROFILER_TEMPLATE', sanitize_file_name( $theme[1] ) );
68 +
69 + if ( is_file( WP_CONTENT_DIR .'/themes/'. CODE_PROFILER_STYLESHEET .'/style.css' ) ) {
70 +
71 + add_filter('pre_option_template', function () {
72 + return CODE_PROFILER_TEMPLATE;
73 + }, 1000 );
74 +
75 + add_filter('pre_option_stylesheet', function () {
76 + return CODE_PROFILER_STYLESHEET;
77 + }, 1000 );
78 +
79 + code_profiler_log_debug(
80 + sprintf(
81 + // We cannot load translation here.
82 + 'Setting theme to %s',
83 + CODE_PROFILER_STYLESHEET
84 + )
85 + );
86 + } else {
87 + code_profiler_log_error(
88 + sprintf(
89 + // We cannot load translation here.
90 + 'Unable to switch theme, %s not found',
91 + CODE_PROFILER_STYLESHEET
92 + )
93 + );
94 + }
95 + }
58 96 }
59 97
60 98 $cp_options = get_option('code-profiler');
61 99 if ( empty( $cp_options['accuracy'] ) ) {
@@ -64,13 +102,44 @@
64 102 define('CODE_PROFILER_TICKS', (int) $cp_options['accuracy'] );
65 103 }
66 104 define('CODE_PROFILER_LENGTH', 17 + strlen( (string) CODE_PROFILER_TICKS ) );
67 105
106 + if ( empty( $cp_options['buffer'] ) ||
107 + ! preg_match('/^(?:[1-9]|10)$/', $cp_options['buffer'] ) ) {
108 +
109 + $recommended = code_profiler_suggested_memory();
110 + self::$buffer = (int) $recommended * 1000000;
111 + } else {
112 + self::$buffer = $cp_options['buffer'] * 1000000;
113 + }
114 + code_profiler_log_debug(
115 + sprintf(
116 + // We cannot load translation here.
117 + 'Setting size of memory buffer to %sMB',
118 + self::$buffer / 1000000
119 + )
120 + );
121 +
122 + // File & folder exclusions
123 + if ( isset( $cp_options['exclusions'] ) ) {
124 + self::$exclusions = json_decode( $cp_options['exclusions'] );
125 + }
126 +
68 127 add_filter('pre_http_request', [ $this, 'pre_http_request'], 10000, 3 );
69 128 add_action('http_api_debug', [ $this, 'http_api_debug'], 10000, 5 );
70 - register_shutdown_function( array( $this, 'code_profiler_shutdown') );
129 + register_shutdown_function( [ $this, 'code_profiler_shutdown'] );
130 + code_profiler_log_debug(
131 + // We cannot load translation here.
132 + 'Starting profiler'
133 + );
134 + require 'class-stream.php';
71 135
72 - require 'class-stream.php';
136 + // Clear the temporary log because the buffer will be appended to it
137 + if ( file_exists( $this->tmp_calls ) ) {
138 + unlink( $this->tmp_calls );
139 + }
140 + self::$fh = fopen( $this->tmp_calls, 'wb');
141 +
73 142 CodeProfiler_Stream::start();
74 143 register_tick_function( array( $this, 'code_profiler_tick_handler') );
75 144 }
76 145
@@ -80,10 +149,19 @@
80 149 public function code_profiler_shutdown() {
81 150
82 151 CodeProfiler_Stream::stop();
83 152
84 - $summary['memory'] = memory_get_peak_usage();
85 - $summary['queries'] = get_num_queries() - 2;
153 + fclose( self::$fh );
154 +
155 + // Summary file (metadata)
156 + $summary = [];
157 + if ( is_file( $this->tmp_rerun ) ) {
158 + $summary['rerun'] = json_decode( file_get_contents( $this->tmp_rerun ), true );
159 + unlink( $this->tmp_rerun );
160 + }
161 + $summary['memory'] = memory_get_peak_usage();
162 + $summary['queries'] = get_num_queries() - 2;
163 + $summary['precision'] = CODE_PROFILER_TICKS;
86 164 file_put_contents( $this->tmp_summary, json_encode( $summary ) );
87 165
88 166 // Catch potential error
89 167 $e = error_get_last();
@@ -103,11 +181,11 @@
103 181 if ( $res === false ) {
104 182 $msg = sprintf( $err_msg, $this->tmp_iostats );
105 183 code_profiler_log_error( $msg );
106 184 }
107 - $res = file_put_contents( $this->tmp_ticks, self::$tick_list, FILE_APPEND );
185 + $res = file_put_contents( $this->tmp_calls, self::$tick_list, FILE_APPEND );
108 186 if ( $res === false ) {
109 - $msg = sprintf( $err_msg, $this->tmp_ticks );
187 + $msg = sprintf( $err_msg, $this->tmp_calls );
110 188 code_profiler_log_error( $msg );
111 189 }
112 190 $res = file_put_contents(
113 191 $this->tmp_diskio, "read\t". CodeProfiler_Stream::$io_read ."\nwrite\t".
@@ -145,17 +223,14 @@
145 223 self::$tick_list .= $backtrace[0]['file'];
146 224 } else {
147 225 self::$tick_list .= '-';
148 226 }
227 + $backtrace = null;
149 228
150 229 // Buffer can grow *very* big hence we flush it every 10MB by default
151 230 if ( strlen( self::$tick_list ) > self::$buffer ) {
152 231 CodeProfiler_Stream::stop();
153 - file_put_contents(
154 - $this->tmp_ticks,
155 - self::$tick_list ."\t{$start}\t". $this->time() ."\n",
156 - FILE_APPEND
157 - );
232 + fwrite( self::$fh, self::$tick_list ."\t{$start}\t". $this->time() ."\n" );
158 233 CodeProfiler_Stream::start();
159 234 self::$tick_list = '';
160 235
161 236 } else {