App Logs - what ITFlow itself does and runs into: cron runs, mail * going out and coming in, payment providers, the API, errors. Listed by * level - errors, warnings, info and debug, each counted for the filters * picked - searched, and filtered by category and date. Each entry opens a * quick look with all of it and what happened around then * (modals/app_log/app_log.php). What is shown can be exported * (export_app_logs) or cleared (clear_app_logs). The work is in * functions/app_log.php. */ // Default Column Sortby Filter $sort = "app_log_id"; $order = "DESC"; require_once "includes/inc_all_admin.php"; // Tab title - the file is named for the table, the page for what it holds $page_title = 'App Logs'; // Only these sort - an unknown column would take the page down $sortable_columns = [ 'app_log_id' => "app_log_id $order", 'app_log_created_at' => "app_log_created_at $order, app_log_id $order", 'app_log_type' => "FIELD(app_log_type, 'error', 'warning', 'info', 'debug') " . ($order === 'ASC' ? 'DESC' : 'ASC') . ", app_log_id DESC", 'app_log_category' => "app_log_category IS NULL, app_log_category $order, app_log_id DESC", ]; if (!isset($sortable_columns[$sort])) { $sort = 'app_log_id'; } $views = appLogViews(); $view = isset($_GET['view']) && is_string($_GET['view']) && isset($views[$_GET['view']]) ? $_GET['view'] : ''; $category_filter = is_string($_GET['category'] ?? null) ? trim($_GET['category']) : ''; $filter_src = array_merge($_GET, ['dtf' => $dtf, 'dtt' => $dtt, 'view' => $view, 'category' => $category_filter]); $sql = mysqli_query($mysqli, "SELECT SQL_CALC_FOUND_ROWS app_log_id, app_log_category, app_log_type, app_log_details, app_log_created_at FROM app_logs WHERE " . appLogFiltersSql($filter_src) . " ORDER BY {$sortable_columns[$sort]} LIMIT $record_from, $record_to"); $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()")); // Each level counted for the rest of the filters $count_sql = []; foreach ($views as $definition) { $count_sql[] = 'COALESCE(SUM(' . ($definition['where'] === '' ? '1' : $definition['where']) . '), 0)'; } $counts = array_combine(array_keys($views), array_map('intval', mysqli_fetch_row(mysqli_query($mysqli, "SELECT " . implode(', ', $count_sql) . " FROM app_logs WHERE " . appLogFiltersSql(array_merge($filter_src, ['view' => ''])))))); // Nothing logs at debug as it comes - its view shows once something does if (!$counts['debug'] && $view !== 'debug') { unset($views['debug']); } $categories = appLogCategories(); $any_filter = $q !== '' || $category_filter !== '' || $dtf !== '1970-01-01' || $dtt !== '2099-12-31'; $retention = appLogRetention(); $sort_link = function ($column, $label) use ($url_query_strings_sort, $sort, $disp, $order_icon) { return '' . $label . ($sort === $column ? " $order_icon" : '') . ''; }; // A view keeps the filters, and starts from its first page $view_url = function ($key) { $query = $_GET; unset($query['page'], $query['open']); $query['view'] = $key; return '?' . http_build_query(array_filter($query, function ($value) { return $value !== '' && $value !== null && $value !== []; })); }; // The page with just this category - from a category in the list $category_url = function ($category) { $query = $_GET; unset($query['page'], $query['open']); $query['category'] = $category; return '?' . http_build_query($query); }; $filters_url = function ($modal) use ($dtf, $dtt, $view, $category_filter) { return buildExportModalUrl($modal, ['q'], ['dtf' => $dtf, 'dtt' => $dtt, 'view' => $view, 'category' => $category_filter]); }; ?>
| = $sort_link('app_log_created_at', 'When') ?> | = $sort_link('app_log_type', 'Level') ?> | = $sort_link('app_log_category', 'Category') ?> | Details | |
|---|---|---|---|---|
|
= escapeHtml(date('M j, Y g:i A', strtotime($row['app_log_created_at']))) ?>
= escapeHtml(timeAgo($row['app_log_created_at'])) ?>
|
= appLogLevelPill($row['app_log_type']) ?> | = escapeHtml($category) ?> - |
= escapeHtml($short) ?>
|