tmp_summary = CODE_PROFILER_UPLOAD_DIR ."/$microtime." . CODE_PROFILER_TMP_SUMMARY_LOG; $this->tmp_iostats = CODE_PROFILER_UPLOAD_DIR ."/$microtime." . CODE_PROFILER_TMP_IOSTATS_LOG; $this->tmp_ticks = CODE_PROFILER_UPLOAD_DIR ."/$microtime." . CODE_PROFILER_TMP_TICKS_LOG; $this->tmp_diskio = CODE_PROFILER_UPLOAD_DIR ."/$microtime." . CODE_PROFILER_TMP_DISKIO_LOG; // Clear the temporary log because the buffer will be written // with the FILE_APPEND flag if ( file_exists( $this->tmp_ticks ) ) { unlink( $this->tmp_ticks ); } if ( version_compare( PHP_VERSION, '7.3', '<') ) { self::$metrics = 'microtime'; } else { self::$metrics = 'hrtime'; } $cp_options = get_option('code-profiler'); if ( empty( $cp_options['accuracy'] ) ) { define('CODE_PROFILER_TICKS', 1 ); } else { define('CODE_PROFILER_TICKS', (int) $cp_options['accuracy'] ); } define('CODE_PROFILER_LENGTH', 17 + strlen( (string) CODE_PROFILER_TICKS ) ); register_shutdown_function( array( $this, 'code_profiler_shutdown') ); require 'class-stream.php'; CodeProfiler_Stream::start(); register_tick_function( array( $this, 'code_profiler_tick_handler') ); } /** * Save data and check for potential PHP errors. */ public function code_profiler_shutdown() { CodeProfiler_Stream::stop(); $summary['memory'] = memory_get_peak_usage(); $summary['queries'] = get_num_queries() - 2; file_put_contents( $this->tmp_summary, json_encode( $summary ) ); // Catch potential error $e = error_get_last(); if ( isset( $e['type'] ) && $e['type'] === E_ERROR ) { $err = str_replace( "\n", ' - ', $e['message'] ); code_profiler_log_error( sprintf( /* Translators: Error message, line number and script */ esc_html__('Error: E_ERROR (%s - line %s in %s)', 'code-profiler'), esc_html( $err ), (int) $e['line'], esc_html( $e['file'] ) )); } $err_msg = esc_html__('Cannot open file for writting: %s', 'code-profiler'); $res = file_put_contents( $this->tmp_iostats, json_encode( CodeProfiler_Stream::$io_stats ) ); if ( $res === false ) { $msg = sprintf( $err_msg, $this->tmp_iostats ); code_profiler_log_error( $msg ); } $res = file_put_contents( $this->tmp_ticks, self::$tick_list, FILE_APPEND ); if ( $res === false ) { $msg = sprintf( $err_msg, $this->tmp_ticks ); code_profiler_log_error( $msg ); } $res = file_put_contents( $this->tmp_diskio, "read\t". CodeProfiler_Stream::$io_read ."\nwrite\t". CodeProfiler_Stream::$io_write ); } /** * Our tick handler. */ public function code_profiler_tick_handler() { $start = $this->time(); $backtrace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 2 ); if ( isset( $backtrace[1] ) ) { $el = $backtrace[1]; } else { $el = $backtrace[0]; } if ( empty( $el['file'] ) ) { if ( isset( $backtrace[0]['file'] ) ) { $el['file'] = $backtrace[0]['file']; } else { return; } } self::$tick_list .= "{$el['file']}\t"; if ( isset( $backtrace[0]['file'][0] ) ) { self::$tick_list .= $backtrace[0]['file']; } else { self::$tick_list .= '-'; } // Buffer can grow *very* big hence we flush it every 10MB by default if ( strlen( self::$tick_list ) > self::$buffer ) { CodeProfiler_Stream::stop(); file_put_contents( $this->tmp_ticks, self::$tick_list ."\t{$start}\t". $this->time() ."\n", FILE_APPEND ); CodeProfiler_Stream::start(); self::$tick_list = ''; } else { self::$tick_list .="\t{$start}\t". $this->time() ."\n"; } } /** * Return time */ private function time() { if ( self::$metrics == 'hrtime') { return hrtime( true ); } else { return microtime( true ); } } } new CodeProfiler_Profiler(); // ===================================================================== // EOF