1: <?php
2: /**
3: * Rundiz Profiler
4: *
5: * @license http://opensource.org/licenses/MIT
6: */
7:
8:
9: namespace Rundiz\Profiler;
10:
11: /**
12: * Console logger class.
13: *
14: * This class works as logger things for profiling.
15: *
16: * @package Rundiz\Profiler
17: * @author Vee W.
18: * @access protected Do not access to this class directly by using new \Rundiz\Profiler\Console. Please access this class via Profiler class instead. See $Profiler->Console.
19: */
20: class Console extends \Rundiz\Profiler\ProfilerBase
21: {
22:
23:
24: /**
25: * profiler class for call back to the caller class.
26: *
27: * @var \Rundiz\Profiler\Profiler
28: */
29: protected $Profiler;
30:
31:
32: /**
33: * class constructor
34: *
35: * @param \Rundiz\Profiler\Profiler $profiler
36: */
37: public function __construct(\Rundiz\Profiler\Profiler $profiler) {
38: $this->Profiler = $profiler;
39: }// __construct
40:
41:
42: /**
43: * Database profiling log.
44: *
45: * @param string $data SQL query statement. for example: SELECT id FROM people;.
46: * @param double $time_start `microtime(true)` at before start the query.
47: * @param integer $memory_start `memory_get_usage()` at before start the query. If this was not set then it will be showing current running memory usage not total memory usage for this process.
48: */
49: public function database($data, $time_start, $memory_start = null)
50: {
51: if (!array_key_exists('Database', $this->Profiler->log_sections)) {
52: return ;
53: }
54:
55: if (!is_string($data)) {
56: return ;
57: }
58:
59: if (!is_float($time_start)) {
60: $time_start = $this->Profiler->getMicrotime();
61: }
62:
63: if (!is_int($memory_start)) {
64: $memory_start = null;
65: }
66:
67: $backtrace = debug_backtrace();
68: $trace_items = [];
69: if (is_array($backtrace)) {
70: foreach ($backtrace as $items) {
71: if (is_array($items) && array_key_exists('file', $items) && array_key_exists('line', $items)) {
72: $trace_items[] = ['file' => $items['file'], 'line' => $items['line']];
73: }
74: }
75: }
76: unset($backtrace, $items);
77:
78: $section_database = $this->Profiler->log_sections['Database'];
79: $section_database_data = [];
80: $section_database_data[] = [
81: 'data' => $data,
82: 'memory_start' => $memory_start,
83: 'memory' => memory_get_usage(),// @deprecated [rundizprofiler] and will be removed in the future
84: 'memory_end' => memory_get_usage(),
85: 'time_start' => $time_start,
86: 'time_end' => $this->Profiler->getMicrotime(),
87: 'call_trace' => $trace_items,
88: ];
89: $section_database = array_merge($section_database, $section_database_data);
90:
91: $this->Profiler->log_sections['Database'] = $section_database;
92: unset($section_database, $section_database_data, $trace_items);
93:
94: //$this->writeLogSections('Database', $data, $file, $line);
95: }// database
96:
97:
98: /**
99: * write normal logs.
100: *
101: * @param string $logtype accept debug, info, notice, warning, error, critical, alert, emergency. referrer: http://www.php-fig.org/psr/psr-3/
102: * @param mixed $data log data.
103: * @param string $file path to file where it calls logger. (optional).
104: * @param integer $line number of line in that file that calls logger. (optional).
105: */
106: public function log($logtype, $data, $file = '', $line = '')
107: {
108: $data = [
109: 'logtype' => $logtype,
110: 'data' => $data,
111: ];
112:
113: $this->writeLogSections('Logs', $data, $file, $line);
114: }// log
115:
116:
117: /**
118: * write memory usage logs.
119: *
120: * @param mixed $data log data.
121: * @param string $file path to file where it calls logger. (optional).
122: * @param integer $line number of line in that file that calls logger. (optional).
123: * @param string|null $matchKey The key to be match at the beginning and end for calculate total time or memory only for this key. (optional). The key must be unique in this section.
124: */
125: public function memoryUsage($data, $file = '', $line = '', $matchKey = null)
126: {
127: $this->writeLogSections('Memory Usage', $data, $file, $line, $matchKey);
128: }// memoryUsage
129:
130:
131: /**
132: * register log sections.<br>
133: * it is very important! you have to call this before other methods in this class or all log_sections data will be erased.
134: *
135: * @param array $sections register log sections by order. suggest: array('Logs', 'Time Load', 'Memory Usage', 'Database', 'Files', 'Session', 'Get', 'Post')
136: */
137: public function registerLogSections(array $sections)
138: {
139: if (!empty($this->log_sections)) {
140: return false;
141: }
142:
143: foreach ($sections as $section) {
144: $this->Profiler->log_sections[$section] = [];
145: }
146:
147: return true;
148: }// registerLogSections
149:
150:
151: /**
152: * Write time load logs.
153: *
154: * To calculate total time load only for specification functional, use `$matchKey`.<br>
155: * Example:
156: * <pre>
157: * $Profiler->Console->timeload('Before run sleep.', '', '', 'run_sleep');
158: * sleep(3);
159: * $Profiler->Console->timeload('After run sleep.', '', '', 'run_sleep');
160: * </pre>
161: * The `$matchKey` must be unique from others.
162: *
163: * @param mixed $data Log data.
164: * @param string $file Path to file where it calls logger. (optional).
165: * @param integer $line Number of line in that file that calls logger. (optional).
166: * @param string|null $matchKey The key to be match at the beginning and end for calculate total time or memory only for this key. (optional). The key must be unique in this section.
167: */
168: public function timeload($data, $file = '', $line = '', $matchKey = null)
169: {
170: $this->writeLogSections('Time Load', $data, $file, $line, $matchKey);
171: }// timeload
172:
173:
174: /**
175: * Write other sections logs.
176: *
177: * @param string $section The section name.
178: * @param mixed $data Log data. This can be any type.
179: * @param string $file Path to file where it calls logger. (optional).
180: * @param integer $line Number of line in that file that calls logger. (optional).
181: * @param string|null $matchKey The key to be match at the beginning and end for calculate total time or memory only for this key. (optional). The key must be unique (for start and end) in each section.
182: */
183: public function writeLogSections($section, $data, $file = '', $line = '', $matchKey = null)
184: {
185: if (!is_array($this->Profiler->log_sections)) {
186: $this->Profiler->log_sections = [];
187: }
188:
189: if (!array_key_exists($section, $this->Profiler->log_sections)) {
190: // if section is not exists in the key means it was not registered, get out of this function.
191: return ;
192: }
193:
194: if (!is_string($matchKey)) {
195: $matchKey = null;
196: }
197:
198: if ($section == 'Logs') {
199: if (is_array($data) && array_key_exists('logtype', $data) && array_key_exists('data', $data)) {
200: $logtype = $data['logtype'];
201: $data = $data['data'];
202: }
203: }
204:
205: $section_data_array = [
206: 'data' => $data,
207: 'file' => $file,
208: 'line' => $line,
209: ];
210: if ($matchKey !== null) {
211: $section_data_array['matchKey'] = $matchKey;
212: }
213: if ($section == 'Time Load') {
214: $section_data_array['time'] = $this->Profiler->getMicrotime();
215: }
216: if ($section == 'Memory Usage') {
217: $section_data_array['memory'] = memory_get_usage();
218: }
219:
220: if (isset($logtype)) {
221: $section_data_array['logtype'] = $logtype;
222: }
223:
224: $this->Profiler->log_sections[$section][] = $section_data_array;
225: unset($section_data_array);
226: }// writeLogSections
227:
228:
229: }