PluginProbe
Code Profiler – WordPress Performance Profiling and Debugging Made Easy / 1.5.2
Code Profiler – WordPress Performance Profiling and Debugging Made Easy v1.5.2
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
code-profiler / lib / class-profiler.php

class-profiler.php in Code Profiler – WordPress Performance Profiling and Debugging Made Easy 1.5.2, at lib/class-profiler.php

175 lines 4.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 +=====================================================================+
4 | ____ _ ____ __ _ _ |
5 | / ___|___ __| | ___ | _ \ _ __ ___ / _(_) | ___ _ __ |
6 | | | / _ \ / _` |/ _ \ | |_) | '__/ _ \| |_| | |/ _ \ '__| |
7 | | |__| (_) | (_| | __/ | __/| | | (_) | _| | | __/ | |
8 | \____\___/ \__,_|\___| |_| |_| \___/|_| |_|_|\___|_| |
9 | |
10 | (c) Jerome Bruandet ~ https://code-profiler.com/ |
11 +=====================================================================+
12 */
13
14 if (! defined('ABSPATH') ) { die('Forbidden'); }
15
16 // =====================================================================
17
18 class CodeProfiler_Profiler {
19
20 static $tick_list;
21 static $buffer = 10000000;
22 static $metrics;
23 private $tmp_iostats;
24 private $tmp_summary;
25 private $tmp_diskio;
26 private $tmp_ticks;
27
28 /**
29 * Initialize
30 */
31 public function __construct() {
32
33 $microtime = sanitize_file_name( $_REQUEST['CODE_PROFILER_ON'] );
34
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;
43
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 );
48 }
49
50 if ( version_compare( PHP_VERSION, '7.3', '<') ) {
51 self::$metrics = 'microtime';
52 } else {
53 self::$metrics = 'hrtime';
54 }
55
56 $cp_options = get_option('code-profiler');
57 if ( empty( $cp_options['accuracy'] ) ) {
58 define('CODE_PROFILER_TICKS', 1 );
59 } else {
60 define('CODE_PROFILER_TICKS', (int) $cp_options['accuracy'] );
61 }
62 define('CODE_PROFILER_LENGTH', 17 + strlen( (string) CODE_PROFILER_TICKS ) );
63
64 register_shutdown_function( array( $this, 'code_profiler_shutdown') );
65
66 require 'class-stream.php';
67 CodeProfiler_Stream::start();
68 register_tick_function( array( $this, 'code_profiler_tick_handler') );
69 }
70
71 /**
72 * Save data and check for potential PHP errors.
73 */
74 public function code_profiler_shutdown() {
75
76 CodeProfiler_Stream::stop();
77
78 $summary['memory'] = memory_get_peak_usage();
79 $summary['queries'] = get_num_queries() - 2;
80 file_put_contents( $this->tmp_summary, json_encode( $summary ) );
81
82 // Catch potential error
83 $e = error_get_last();
84 if ( isset( $e['type'] ) && $e['type'] === E_ERROR ) {
85 $err = str_replace( "\n", ' - ', $e['message'] );
86 code_profiler_log_error( sprintf(
87 /* Translators: Error message, line number and script */
88 esc_html__('Error: E_ERROR (%s - line %s in %s)', 'code-profiler'),
89 esc_html( $err ),
90 (int) $e['line'],
91 esc_html( $e['file'] )
92 ));
93 }
94
95 $err_msg = esc_html__('Cannot open file for writting: %s', 'code-profiler');
96 $res = file_put_contents( $this->tmp_iostats, json_encode( CodeProfiler_Stream::$io_stats ) );
97 if ( $res === false ) {
98 $msg = sprintf( $err_msg, $this->tmp_iostats );
99 code_profiler_log_error( $msg );
100 }
101 $res = file_put_contents( $this->tmp_ticks, self::$tick_list, FILE_APPEND );
102 if ( $res === false ) {
103 $msg = sprintf( $err_msg, $this->tmp_ticks );
104 code_profiler_log_error( $msg );
105 }
106 $res = file_put_contents(
107 $this->tmp_diskio, "read\t". CodeProfiler_Stream::$io_read ."\nwrite\t".
108 CodeProfiler_Stream::$io_write
109 );
110 }
111
112 /**
113 * Our tick handler.
114 */
115 public function code_profiler_tick_handler() {
116
117 $start = $this->time();
118
119 $backtrace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 2 );
120 if ( isset( $backtrace[1] ) ) {
121 $el = $backtrace[1];
122 } else {
123 $el = $backtrace[0];
124 }
125
126 if ( empty( $el['file'] ) ) {
127 if ( isset( $backtrace[0]['file'] ) ) {
128 $el['file'] = $backtrace[0]['file'];
129 } else {
130 return;
131 }
132 }
133
134 self::$tick_list .= "{$el['file']}\t";
135 if ( isset( $backtrace[0]['file'][0] ) ) {
136 self::$tick_list .= $backtrace[0]['file'];
137 } else {
138 self::$tick_list .= '-';
139 }
140
141 // Buffer can grow *very* big hence we flush it every 10MB by default
142 if ( strlen( self::$tick_list ) > self::$buffer ) {
143 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 );
149 CodeProfiler_Stream::start();
150 self::$tick_list = '';
151
152 } else {
153 self::$tick_list .="\t{$start}\t". $this->time() ."\n";
154 }
155 }
156
157
158 /**
159 * Return time
160 */
161 private function time() {
162
163 if ( self::$metrics == 'hrtime') {
164 return hrtime( true );
165 } else {
166 return microtime( true );
167 }
168 }
169 }
170
171 new CodeProfiler_Profiler();
172
173 // =====================================================================
174 // EOF
175