Преглед изворни кода

updated Debug - pagination for long files

Piotr Labudda пре 8 година
родитељ
комит
850ae5a021
1 измењених фајлова са 160 додато и 49 уклоњено
  1. 160 49
      SE/se-lib/Route/Debug.php

+ 160 - 49
SE/se-lib/Route/Debug.php

@@ -396,7 +396,14 @@ class Route_Debug extends RouteBase {
 		$logName = $this->validateParamLogName($logName);
 		$logPath = "{$this->logPathPrefix}se-{$type}-{$logName}.log";
 		if (!file_exists($logPath)) throw new Exception("Log file not exists");
-		$content = file_get_contents($logPath);
+
+		// $content = file_get_contents($logPath);
+		// $contentLines = explode("\n", $content);
+		V::exec("head -100 '{$logPath}'", $contentLines, $ret);
+		$hasMoreRows = ( count($contentLines) >= 100 );
+		if ($hasMoreRows) array_pop($contentLines);
+		if ($hasMoreRows) UI::alert('info', "pobierz więcej..." . "cnt(".count($contentLines).")");
+
 		$lastTime = '';
 		UI::table([
 			'cols' => [
@@ -409,7 +416,7 @@ class Route_Debug extends RouteBase {
 			'cols_help' => [
 				'trace' => "Cick to show trace"
 			],
-			'rows' => array_map(
+			'rows' => array_merge( array_map(
 				function ($line) use (&$lastTime) {
 					if (empty($line)) return [];
 					$dbg = @json_decode($line, $assoc = true);
@@ -419,57 +426,62 @@ class Route_Debug extends RouteBase {
 							'msg' => "Error Processing Request - Parse json error: " . json_last_error()
 						];
 					}
-					$timeDiff = (!$lastTime)
-					? ''
-					: V::milisecondsStringDiff($dbg['date'], $lastTime); // TODO: $dbg['date'] - $lastTime;
+					$ret = $this->viewDebugRow($dbg, $lastTime);
 					$lastTime = $dbg['date'];
-					$trace = htmlspecialchars($dbg['trace']);
-					$trace = str_replace("\n", "\n<br>", $trace);
-					if ('#' === substr($trace, 0, 1)) $trace = "<br>{$trace}";
-					$trace = preg_replace('/<br>#(\d+\W+)([a-zA-Z0-9-_:\.\/]*):/', '#${1}<a href="http://localhost:9876/?project=se&file=${2}" target="_blank">${2}</a>:', $trace);
-					$trace = str_replace("\n<br>", "\n", $trace);
-					return [
-						'date' => '<nobr>' . substr($dbg['date'], 11) . '</nobr>',
-						'diff' => '<nobr>' . $timeDiff . '</nobr>',
-						'@style[date]' => "width:1%",
-						'type' => $dbg['type'],
-						'@style[type]' => "width:1%",
-						'@style[msg]' => "min-width:540px; max-width:700px",
-						'@style[trace]' => "min-width:120px",
-						'msg' => UI::h('div', [], [
-							UI::h('details', [], [
-								UI::h('summary', [], [
-									( ( $dbg['msg'] && 'sql' !== $dbg['msg'] ) ? "{$dbg['msg']} " : '' ),
-									UI::h('span', [ 'style' => "color:silver" ], str_replace(array('\n', '\t'), ' ', substr(htmlspecialchars(json_encode($dbg['log'])), 0, 100)) . ' ...'),
-									" (rozwiń)"
-								]),
-								UI::h('pre', [ 'style' => "font-size:x-small" ], htmlspecialchars( ('sql' == $dbg['type'] && is_string($dbg['log'])) ? $dbg['log'] : var_export($dbg['log'], true) )),
-							]),
-							// UI::h('div', [
-							// 	'title' => htmlspecialchars( ('sql' == $dbg['type'] && is_string($dbg['log'])) ? $dbg['log'] : var_export($dbg['log'], true) ),
-							// 	'onClick' => "return p5DBG__showLogTrace(this, event, '600px')",
-							// 	'style' => "cursor:pointer"
-							// ], str_replace(array('\n', '\t'), ' ', substr(htmlspecialchars(json_encode($dbg['log'])), 0, 100)) . ' ...')
-						]),
-						'trace' => UI::h('div', [], [
-							UI::h('details', [], [
-								UI::h('summary', [], "trace: (rozwiń)"),
-								UI::h('pre', [ 'style' => "font-size:x-small" ], $trace),
-								UI::h('div', [
-									'title' => htmlspecialchars($dbg['trace']),
-									'onClick' => "return p5DBG__showLogTrace(this, event)",
-									'style' => "cursor:pointer"
-								], ('Exception' == $dbg['type'])
-									? "Code: {$dbg['log']['code']}, File: {$dbg['log']['file']}"
-									: '...'
-								),
-							]),
-						]),
-					];
+					return $ret;
 				},
-				explode("\n", $content)
+				$contentLines
+			),
+				($hasMoreRows)
+				?	[[	'msg' => UI::hButtonAjax("Pobierz więcej danych ...", 'fetchMoreDbgLines', [
+							'class' => "btn btn-xs btn-primary",
+		                    'href' => $this->getLink('fetchMoreDbgLinesAjax'),
+		                    'data' => [
+		                            'logPath' => $logPath,
+		                            'from' => 100,
+		                            'limit' => 100,
+		                    ],
+						]),
+					]]
+				:	[]
 			),
 		]);
+		UI::hButtonAjaxOnResponse('fetchMoreDbgLines', /* payload, n */ "
+			console.log('fetchMoreDbgLines: payload, n', payload, n)
+			var cols = [
+				'lp',
+				'date',
+				'diff',
+				'type',
+				'msg',
+				'trace',
+			];
+
+			var outHtml = ''
+			var rows = (payload && payload.body && payload.body.rows && payload.body.rows.length > 0) ? payload.body.rows : []
+			if (rows) {
+				rows.forEach(function (row) {
+					outHtml += '<tr>'
+					outHtml += cols.map(function (col) {
+						var colStyleField = '@style['+col+']'
+						if ('lp' === col) row[colStyleField] = [ row[colStyleField], 'color:#ccc;' ].join(';')
+						return '<td style=\"padding:2px' + ( colStyleField in row ? ';' + row[colStyleField] : '' ) + '\">' + row[col] + '</td>'
+					}).join('')
+					outHtml += '</tr>'
+				})
+			} else {
+				outHtml += '<tr><td colspan=\"4\"></td><td colspan=\"2\">' + 'Brak danych' + '</td></tr>'
+			}
+
+			var fetchMoreLink = (payload && payload.body && payload.body.fetchMoreLink && payload.body.fetchMoreLink.length > 0) ? payload.body.fetchMoreLink : ''
+			if (fetchMoreLink) {
+				outHtml += '<tr><td colspan=\"4\"></td><td colspan=\"2\">' + fetchMoreLink + '</td></tr>'
+			}
+
+			console.log('rows', rows)
+			console.log('outHtml', outHtml)
+			jQuery(n).parent().parent().replaceWith(outHtml)
+		");
 		echo UI::h('script', [], "
 			function p5DBG__showLogTrace(n, e, maxWidth) {
 				var maxWidth = maxWidth || null
@@ -493,6 +505,105 @@ class Route_Debug extends RouteBase {
 		");
 	}
 
+	public function viewDebugRow($dbg, $lastTime) {
+		$timeDiff = (!$lastTime)
+		? ''
+		: V::milisecondsStringDiff($dbg['date'], $lastTime); // TODO: $dbg['date'] - $lastTime;
+		$trace = htmlspecialchars($dbg['trace']);
+		$trace = str_replace("\n", "\n<br>", $trace);
+		if ('#' === substr($trace, 0, 1)) $trace = "<br>{$trace}";
+		$trace = preg_replace('/<br>#(\d+\W+)([a-zA-Z0-9-_:\.\/]*):/', '#${1}<a href="http://localhost:9876/?project=se&file=${2}" target="_blank">${2}</a>:', $trace);
+		$trace = str_replace("\n<br>", "\n", $trace);
+		return [
+			'date' => '<nobr>' . substr($dbg['date'], 11) . '</nobr>',
+			'diff' => '<nobr>' . $timeDiff . '</nobr>',
+			'@style[date]' => "width:1%",
+			'type' => $dbg['type'],
+			'@style[type]' => "width:1%",
+			'@style[msg]' => "min-width:540px; max-width:700px",
+			'@style[trace]' => "min-width:120px",
+			'msg' => UI::h('div', [], [
+				UI::h('details', [], [
+					UI::h('summary', [], [
+						( ( $dbg['msg'] && 'sql' !== $dbg['msg'] ) ? "{$dbg['msg']} " : '' ),
+						UI::h('span', [ 'style' => "color:silver" ], str_replace(array('\n', '\t'), ' ', substr(htmlspecialchars(json_encode($dbg['log'])), 0, 100)) . ' ...'),
+						" (rozwiń)"
+					]),
+					UI::h('pre', [ 'style' => "font-size:x-small" ], htmlspecialchars( ('sql' == $dbg['type'] && is_string($dbg['log'])) ? $dbg['log'] : var_export($dbg['log'], true) )),
+				]),
+				// UI::h('div', [
+				// 	'title' => htmlspecialchars( ('sql' == $dbg['type'] && is_string($dbg['log'])) ? $dbg['log'] : var_export($dbg['log'], true) ),
+				// 	'onClick' => "return p5DBG__showLogTrace(this, event, '600px')",
+				// 	'style' => "cursor:pointer"
+				// ], str_replace(array('\n', '\t'), ' ', substr(htmlspecialchars(json_encode($dbg['log'])), 0, 100)) . ' ...')
+			]),
+			'trace' => UI::h('div', [], [
+				UI::h('details', [], [
+					UI::h('summary', [], "trace: (rozwiń)"),
+					UI::h('pre', [ 'style' => "font-size:x-small" ], $trace),
+					UI::h('div', [
+						'title' => htmlspecialchars($dbg['trace']),
+						'onClick' => "return p5DBG__showLogTrace(this, event)",
+						'style' => "cursor:pointer"
+					], ('Exception' == $dbg['type'])
+						? "Code: {$dbg['log']['code']}, File: {$dbg['log']['file']}"
+						: '...'
+					),
+				]),
+			]),
+		];
+	}
+
+	public function fetchMoreDbgLinesAjaxAction() {
+		Lib::loadClass('Response');
+		Response::sendTryCatchJson([$this, 'fetchMoreDbgLinesAjax'], $_REQUEST);
+	}
+	public function fetchMoreDbgLinesAjax($args) {
+		$logPath = V::get('logPath', '', $args);
+		if (!$logPath) throw new Exception("Missing logPath");
+		$from = V::get('from', 0, $args, 'int');
+		$limit = V::get('limit', 100, $args, 'int');
+
+		// $content = file_get_contents($logPath);
+		// $contentLines = explode("\n", $content);
+		V::exec("tail -n +{$from} '{$logPath}' | head -" . ($limit + 1) . " ", $contentLines, $ret);
+		$hasMoreRows = ( count($contentLines) > $limit );
+		if ($hasMoreRows) array_pop($contentLines);
+		$lastTime = null;
+		$lp = $from;
+		return [
+			'msg' => "TODO: ... ret({$ret}) lines(".count($contentLines).") ",
+			'type' => "error",
+			'body' => [
+				'rows' => array_map(function ($line) use (&$lastTime, &$lp) {
+					$dbg = @json_decode($line, $assoc = true);
+					if (null == $dbg && 0 !== json_last_error()) {
+						return [
+							'type' => 'decode json error',
+							'msg' => "Error Processing Request - Parse json error: " . json_last_error()
+						];
+					}
+					$ret = $this->viewDebugRow($dbg, $lastTime);
+					$ret['lp'] = $lp++;
+					$lastTime = $dbg['date'];
+					return $ret;
+				}, $contentLines),
+				'fetchMoreLink' =>
+				($hasMoreRows)
+				?	UI::hButtonAjax("Pobierz więcej danych ...", 'fetchMoreDbgLines', [
+						'class' => "btn btn-xs btn-primary",
+	                    'href' => $this->getLink('fetchMoreDbgLinesAjax'),
+	                    'data' => [
+	                            'logPath' => $logPath,
+	                            'from' => $from + $limit,
+	                            'limit' => $limit,
+	                    ],
+					])
+				:	null,
+			]
+		];
+	}
+
 	public function activateDebugAction() {
 		DBG::activate();
 		$this->defaultView();