dolibarr.netdiag/api/applog.php
Eduard Wisch 914101ba30
All checks were successful
Deploy netdiag / deploy (push) Successful in 14s
API-Endpoint applog.php — Debug-Log der mobilen App empfangen [deploy]
Die App erfasst Fehler/Meldungen und schiebt sie per POST hierher; sie
landen in llx_netdiag_applog und sind serverseitig auswertbar — ohne Kabel.
- api/applog.php: JWT-Auth (wie alle Endpoints), Batch-Insert, legt die
  Tabelle bei Bedarf an (Modul kann schon vorher installiert gewesen sein)
- sql/llx_netdiag_applog.sql + .key.sql: Tabelle fuer saubere Neuinstallation

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 17:39:31 +02:00

99 lines
3.3 KiB
PHP

<?php
/* Copyright (C) 2026 Eduard Wisch <data@data-it-solution.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* \file netdiag/api/applog.php
* \ingroup netdiag
* \brief API-Endpunkt: Debug-Log der mobilen App entgegennehmen.
*
* Die App schickt erfasste Fehler/Meldungen per POST hierher; sie landen
* in llx_netdiag_applog und sind so serverseitig auswertbar — ohne Kabel
* und ohne Logcat. Authentifizierung über das normale App-JWT.
*/
require_once __DIR__.'/netdiag_api.lib.php';
netdiag_api_bootstrap();
/**
* @var Conf $conf
* @var DoliDB $db
*/
$user = netdiag_api_authenticate($db);
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
netdiag_api_error('Nur POST erlaubt', 405);
}
$body = netdiag_api_read_body();
$entries = (isset($body['entries']) && is_array($body['entries'])) ? $body['entries'] : array();
if (empty($entries)) {
netdiag_api_respond(array('ok' => true, 'stored' => 0));
}
$appVersion = isset($body['appVersion']) ? mb_substr((string) $body['appVersion'], 0, 32) : '';
$device = isset($body['device']) ? mb_substr((string) $body['device'], 0, 128) : '';
$prefix = $db->prefix();
// Tabelle bei Bedarf anlegen — das Modul kann in Prod schon vor diesem
// Feature installiert worden sein, dann lief die sql/-Datei nie.
$db->query(
"CREATE TABLE IF NOT EXISTS ".$prefix."netdiag_applog("
." rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL,"
." entity integer DEFAULT 1 NOT NULL,"
." fk_user integer,"
." app_version varchar(32),"
." device varchar(128),"
." level varchar(8),"
." message text,"
." date_log datetime,"
." date_creation datetime NOT NULL,"
." INDEX idx_netdiag_applog_creation(date_creation)"
.") ENGINE=innodb"
);
// Schutz gegen überlange Requests
$entries = array_slice($entries, 0, 500);
$now = $db->idate(dol_now());
$stored = 0;
$db->begin();
foreach ($entries as $e) {
if (!is_array($e)) {
continue;
}
$level = isset($e['level']) ? mb_substr((string) $e['level'], 0, 8) : 'info';
$msg = isset($e['msg']) ? mb_substr((string) $e['msg'], 0, 2000) : '';
// Client-Zeitstempel in ms -> Sekunden -> DB-Datetime
$ts = isset($e['ts']) ? (int) $e['ts'] : 0;
$dateLog = $ts > 0 ? $db->idate((int) ($ts / 1000)) : $now;
$sql = "INSERT INTO ".$prefix."netdiag_applog"
." (entity, fk_user, app_version, device, level, message, date_log, date_creation)"
." VALUES (".((int) $conf->entity).", ".((int) $user->id).","
." '".$db->escape($appVersion)."', '".$db->escape($device)."',"
." '".$db->escape($level)."', '".$db->escape($msg)."',"
." '".$db->escape($dateLog)."', '".$db->escape($now)."')";
if ($db->query($sql)) {
$stored++;
}
}
$db->commit();
netdiag_api_respond(array('ok' => true, 'stored' => $stored));