| Server IP : 202.61.199.114 / Your IP : 216.73.217.139 Web Server : nginx/1.22.1 System : Linux de.arni-solutions.de 6.1.0-49-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.174-1 (2026-05-26) x86_64 User : web20 ( 1018) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /var/www/clients/client1/web17/web/ |
Upload File : |
<?php
/**
* debug-api.php – Admin-Backend für Einstellungen → Debug (Performance-Messung, Phase 2/7).
* Nur Lesen/Auswerten + Einstellungen; KEIN Eingriff in produktive Abläufe.
*
* Aktionen: get | save | stats | logs | detail | clear | export | agent-run
*/
require_once( __DIR__ . '/includes/config.inc.php' );
@ini_set( 'display_errors', '0' );
error_reporting( 0 );
ob_start();
function dbg_json( $a ) { while ( ob_get_level() > 0 ) ob_end_clean(); header( 'Content-Type: application/json; charset=utf-8' ); echo json_encode( $a ); exit(); }
function dbg_fail( $m ) { dbg_json( array( 'ok' => false, 'error' => $m ) ); }
if ( ! function_exists( 'is_admin' ) || ! is_admin() ) { http_response_code( 403 ); dbg_json( array( 'ok' => false, 'error' => 'forbidden' ) ); }
$action = $_GET['action'] ?? ( $_POST['action'] ?? '' );
$db = new MysqliDb( MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB );
function dbg_table_exists( $db ) {
$r = $db->rawQueryOne( "SHOW TABLES LIKE 'pacim_performance_log'" );
return ! empty( $r );
}
/* ---------------- Einstellungen lesen ---------------- */
if ( $action === 'get' ) {
$th = json_decode( (string) settings::get( 'perf_agent_thresholds', '' ), true ); if ( ! is_array( $th ) ) $th = array();
$cnt = dbg_table_exists( $db ) ? (int) ( $db->rawQueryOne( "SELECT COUNT(*) c FROM pacim_performance_log" )['c'] ?? 0 ) : 0;
dbg_json( array(
'ok' => true,
'enabled' => (string) settings::get( 'perf_log_enabled', '0' ) === '1',
'min_ms' => (int) settings::get( 'perf_log_min_ms', 100 ),
'max_rows' => (int) settings::get( 'perf_log_max_rows', 50000 ),
'agent_enabled' => (string) settings::get( 'perf_agent_enabled', '0' ) === '1',
'agent_key' => (string) settings::get( 'perf_agent_pushover_key', '' ),
'thresholds' => array(
'slow_ms' => isset( $th['slow_ms'] ) ? (int) $th['slow_ms'] : 2000,
'avg_ms' => isset( $th['avg_ms'] ) ? (int) $th['avg_ms'] : 1500,
'mem_mb' => isset( $th['mem_mb'] ) ? (int) $th['mem_mb'] : 192,
'cooldown_min' => isset( $th['cooldown_min'] ) ? (int) $th['cooldown_min'] : 360,
'interval_min' => isset( $th['interval_min'] ) ? (int) $th['interval_min'] : 15,
),
'log_count' => $cnt,
'push_ready' => class_exists( 'pushnotify' ) && pushnotify::configured(),
) );
}
/* ---------------- Einstellungen speichern ---------------- */
if ( $action === 'save' ) {
if ( $_SERVER['REQUEST_METHOD'] !== 'POST' ) dbg_fail( 'method' );
settings::set( 'perf_log_enabled', ! empty( $_POST['enabled'] ) ? '1' : '0' );
settings::set( 'perf_log_min_ms', (string) max( 0, (int) ( $_POST['min_ms'] ?? 100 ) ) );
settings::set( 'perf_log_max_rows', (string) max( 1000, (int) ( $_POST['max_rows'] ?? 50000 ) ) );
settings::set( 'perf_agent_enabled', ! empty( $_POST['agent_enabled'] ) ? '1' : '0' );
settings::set( 'perf_agent_pushover_key', mb_substr( trim( (string) ( $_POST['agent_key'] ?? '' ) ), 0, 64 ) );
settings::set( 'perf_agent_thresholds', json_encode( array(
'slow_ms' => max( 1, (int) ( $_POST['slow_ms'] ?? 2000 ) ),
'avg_ms' => max( 1, (int) ( $_POST['avg_ms'] ?? 1500 ) ),
'mem_mb' => max( 1, (int) ( $_POST['mem_mb'] ?? 192 ) ),
'cooldown_min' => max( 5, (int) ( $_POST['cooldown_min'] ?? 360 ) ),
'interval_min' => max( 1, (int) ( $_POST['interval_min'] ?? 15 ) ),
) ) );
dbg_json( array( 'ok' => true ) );
}
/* ---------------- Übersicht / Auswertung ---------------- */
if ( $action === 'stats' ) {
if ( ! dbg_table_exists( $db ) ) dbg_json( array( 'ok' => true, 'empty' => true ) );
$hours = (int) ( $_GET['hours'] ?? 24 ); if ( $hours < 1 || $hours > 168 ) $hours = 24;
$slowest = $db->rawQuery(
"SELECT perf_id, perf_time, perf_module, perf_action, perf_category, perf_ms, perf_rows, perf_mem, perf_context, perf_params
FROM pacim_performance_log WHERE perf_time >= (NOW() - INTERVAL ? HOUR)
ORDER BY perf_ms DESC LIMIT 25", array( $hours ) );
$byModule = $db->rawQuery(
"SELECT perf_module AS m, COUNT(*) AS hits, ROUND(AVG(perf_ms)) AS avg_ms, MAX(perf_ms) AS max_ms, ROUND(MAX(perf_mem)/1048576,1) AS max_mem_mb
FROM pacim_performance_log WHERE perf_time >= (NOW() - INTERVAL ? HOUR)
GROUP BY perf_module ORDER BY avg_ms DESC", array( $hours ) );
$byCategory = $db->rawQuery(
"SELECT COALESCE(perf_category, perf_action) AS c, perf_module AS m, COUNT(*) AS hits, ROUND(AVG(perf_ms)) AS avg_ms, MAX(perf_ms) AS max_ms
FROM pacim_performance_log WHERE perf_time >= (NOW() - INTERVAL ? HOUR)
GROUP BY perf_module, COALESCE(perf_category, perf_action) ORDER BY avg_ms DESC LIMIT 25", array( $hours ) );
$timeline = $db->rawQuery(
"SELECT DATE_FORMAT(perf_time, '%Y-%m-%d %H:00') AS h, COUNT(*) AS hits, ROUND(AVG(perf_ms)) AS avg_ms, MAX(perf_ms) AS max_ms
FROM pacim_performance_log WHERE perf_time >= (NOW() - INTERVAL 24 HOUR)
GROUP BY h ORDER BY h ASC" );
dbg_json( array( 'ok' => true, 'hours' => $hours, 'slowest' => $slowest, 'by_module' => $byModule, 'by_category' => $byCategory, 'timeline' => $timeline ) );
}
/* ---------------- Logliste ---------------- */
if ( $action === 'logs' ) {
if ( ! dbg_table_exists( $db ) ) dbg_json( array( 'ok' => true, 'list' => array() ) );
$module = trim( (string) ( $_GET['module'] ?? '' ) );
$minMs = (int) ( $_GET['min_ms'] ?? 0 );
$limit = (int) ( $_GET['limit'] ?? 100 ); if ( $limit < 1 || $limit > 500 ) $limit = 100;
$where = "perf_ms >= ?"; $params = array( $minMs );
if ( $module !== '' ) { $where .= " AND perf_module = ?"; $params[] = $module; }
$list = $db->rawQuery(
"SELECT perf_id, perf_time, perf_context, perf_module, perf_action, perf_category, perf_ms, perf_rows, ROUND(perf_mem/1048576,1) AS mem_mb, perf_status, perf_params
FROM pacim_performance_log WHERE {$where} ORDER BY perf_id DESC LIMIT " . $limit, $params );
dbg_json( array( 'ok' => true, 'list' => $list ) );
}
/* ---------------- Detail ---------------- */
if ( $action === 'detail' ) {
$id = (int) ( $_GET['id'] ?? 0 );
$r = $db->rawQueryOne( "SELECT * FROM pacim_performance_log WHERE perf_id = ?", array( $id ) );
if ( ! $r ) dbg_fail( 'not_found' );
dbg_json( array( 'ok' => true, 'entry' => $r ) );
}
/* ---------------- Logs löschen ---------------- */
if ( $action === 'clear' ) {
if ( $_SERVER['REQUEST_METHOD'] !== 'POST' ) dbg_fail( 'method' );
if ( dbg_table_exists( $db ) ) $db->rawQuery( "TRUNCATE TABLE pacim_performance_log" );
dbg_json( array( 'ok' => true ) );
}
/* ---------------- CSV-Export (keine PII) ---------------- */
if ( $action === 'export' ) {
if ( ! dbg_table_exists( $db ) ) dbg_fail( 'Keine Daten.' );
$limit = (int) ( $_GET['limit'] ?? 5000 ); if ( $limit < 1 || $limit > 100000 ) $limit = 5000;
$rows = $db->rawQuery( "SELECT perf_time, perf_context, perf_module, perf_action, perf_category, perf_ms, perf_rows, perf_mem, perf_uri, perf_status FROM pacim_performance_log ORDER BY perf_id DESC LIMIT " . $limit );
while ( ob_get_level() > 0 ) ob_end_clean();
header( 'Content-Type: text/csv; charset=utf-8' );
header( 'Content-Disposition: attachment; filename="performance_log.csv"' );
$out = fopen( 'php://output', 'w' );
fputcsv( $out, array( 'time', 'context', 'module', 'action', 'category', 'ms', 'rows', 'mem_bytes', 'uri', 'status' ), ';' );
foreach ( (array) $rows as $r ) fputcsv( $out, $r, ';' );
fclose( $out );
exit();
}
/* ---------------- Agent manuell anstoßen (respektiert Drosselung) ---------------- */
if ( $action === 'agent-run' ) {
if ( $_SERVER['REQUEST_METHOD'] !== 'POST' ) dbg_fail( 'method' );
// Drosselung für den manuellen Test zurücksetzen, damit sofort ausgewertet wird.
settings::set( 'perf_agent_last_run', '0' );
if ( class_exists( 'perflog' ) ) perflog::runAgent();
dbg_json( array( 'ok' => true, 'message' => 'Agent ausgeführt (sofern aktiviert). Meldungen laufen über die Pushover-Queue.' ) );
}
dbg_fail( 'unknown_action' );