From 054a6c7073112582a602a5d96d3ce8d46e608957 Mon Sep 17 00:00:00 2001 From: Hide_D Date: Sat, 5 Nov 2022 15:00:13 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=AA=A8=EB=93=A0=20API=EB=A5=BC=20?= =?UTF-8?q?=EA=B8=B0=EB=A1=9D=ED=95=98=EB=8A=94=20=EC=8B=9C=EC=8A=A4?= =?UTF-8?q?=ED=85=9C=20-=20sqlite3=EC=97=90=20=EA=B8=B0=EB=A1=9D=20-=20?= =?UTF-8?q?=EB=8A=90=EB=A0=A4=EC=A7=80=EC=A7=80=20=EC=95=8A=EA=B8=B0?= =?UTF-8?q?=EB=A5=BC...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 + f_install/sql/api_log.sql | 17 +++++ src/sammo/APIHelper.php | 134 +++++++++++++++++++++++++++++++++++++- 3 files changed, 150 insertions(+), 3 deletions(-) create mode 100644 f_install/sql/api_log.sql diff --git a/.gitignore b/.gitignore index 7ee1f598..e82650a2 100644 --- a/.gitignore +++ b/.gitignore @@ -10,8 +10,10 @@ *.log logs/*.txt +api_log.db d_log/*.txt d_log/*.zip +d_log/*.db sess_* */logs/*.txt */logs/*/*.txt diff --git a/f_install/sql/api_log.sql b/f_install/sql/api_log.sql new file mode 100644 index 00000000..4cc67f63 --- /dev/null +++ b/f_install/sql/api_log.sql @@ -0,0 +1,17 @@ +CREATE TABLE IF NOT EXISTS "api_log" ( + "id" INTEGER NOT NULL, + "user_id" INTEGER NOT NULL, + "ip" TEXT NOT NULL, + "date" TEXT NOT NULL, + "path" TEXT NOT NULL, + "arg" TEXT, + "aux" TEXT, + PRIMARY KEY("id" AUTOINCREMENT) +); +CREATE INDEX IF NOT EXISTS "by_date" ON "api_log" ( + "date" DESC +); +CREATE INDEX IF NOT EXISTS "by_user" ON "api_log" ( + "user_id" ASC, + "date" DESC +); diff --git a/src/sammo/APIHelper.php b/src/sammo/APIHelper.php index 3eaf3817..a4cf7a25 100644 --- a/src/sammo/APIHelper.php +++ b/src/sammo/APIHelper.php @@ -34,15 +34,42 @@ class APIHelper $input = []; } + if(class_exists('\\sammo\\UniqueConst')){ + $serverID = UniqueConst::$serverID; + $logPath = "{$rootPath}/logs/{$serverID}/api_log.db"; + } + else{ + $realYearMonth = date('Y_m'); + $logPath = "{$rootPath}/d_log/{$realYearMonth}_api_log.db"; + } + $logDB = FileDB::db($logPath, __DIR__.'/../../f_install/sql/api_log.sql'); + $ip = $_SERVER['REMOTE_ADDR'] ?? 'local'; + $date = date('Y-m-d H:i:s'); + //NOTE: array_merge([], {})의 상황이 가능함. $actionArgs = array_merge($input, $eParams); + $filteredArgs = $actionArgs; + try { $obj = buildAPIExecutorClass($actionPath, $rootPath, $actionArgs); $validateResult = $obj->validateArgs(); if ($validateResult !== null) { + $logDB->insert('api_log', [ + 'user_id' => 0, + 'ip' => $ip, + 'date' => $date, + 'path' => $actionPath, + 'arg' => JSON::encode($filteredArgs), + 'aux' => JSON::encode([ + 'result'=>false, + 'state'=>'validate', + 'reason'=>$validateResult + ]), + ]); Json::dieWithReason($validateResult); } + $filteredArgs = $obj->getFilteredArgs(); $sessionMode = $obj->getRequiredSessionMode(); if ($sessionMode === BaseAPI::NO_SESSION) { @@ -66,6 +93,18 @@ class APIHelper $result = $obj->launch($session, $modifiedSince, $reqEtags); if (is_string($result)) { + $logDB->insert('api_log', [ + 'user_id' => $session->userID, + 'ip' => $ip, + 'date' => $date, + 'path' => $actionPath, + 'arg' => JSON::encode($filteredArgs), + 'aux' => JSON::encode([ + 'result'=>false, + 'state'=>'launch', + 'reason'=>$validateResult + ]), + ]); Json::dieWithReason($result); } @@ -82,28 +121,117 @@ class APIHelper $lastModifiedUnixTime = Util::toInt(TimeUtil::DateTimeToSeconds($cache->lastModified, true)); $modifiedSinceUnixTime = Util::toInt(TimeUtil::DateTimeToSeconds($modifiedSince)); if($lastModifiedUnixTime === $modifiedSinceUnixTime){ + $logDB->insert('api_log', [ + 'user_id' => $session->userID, + 'ip' => $ip, + 'date' => $date, + 'path' => $actionPath, + 'arg' => JSON::encode($filteredArgs), + 'aux' => JSON::encode([ + 'result'=>true, + 'state'=>'cache_not_modified', + ]), + ]); WebUtil::dieWithNotModified(); } } if ($reqEtags !== null && $reqEtags === $cache->etag) { + $logDB->insert('api_log', [ + 'user_id' => $session->userID, + 'ip' => $ip, + 'date' => $date, + 'path' => $actionPath, + 'arg' => JSON::encode($filteredArgs), + 'aux' => JSON::encode([ + 'result'=>true, + 'state'=>'cache_not_modified', + ]), + ]); WebUtil::dieWithNotModified(); } } if ($result === null) { + $logDB->insert('api_log', [ + 'user_id' => $session->userID, + 'ip' => $ip, + 'date' => $date, + 'path' => $actionPath, + 'arg' => JSON::encode($filteredArgs), + 'aux' => JSON::encode([ + 'result'=>true, + 'state'=>'success_simple', + 'set_cache'=>$setCache, + ]), + ]); Json::die([ 'result' => true, 'reason' => 'success' ], $setCache ? 0 : Json::NO_CACHE); } + $logDB->insert('api_log', [ + 'user_id' => $session->userID, + 'ip' => $ip, + 'date' => $date, + 'path' => $actionPath, + 'arg' => JSON::encode($filteredArgs), + 'aux' => JSON::encode([ + 'result'=>true, + 'state'=>'success_complex', + 'set_cache'=>$setCache, + ]), + ]); Json::die($result, $setCache ? 0 : Json::NO_CACHE); } catch (\Exception $e) { - Json::dieWithReason($e->getMessage()."\n".$e->getTraceAsString()); + $errMsg = $e->getMessage(); + $errTrace = $e->getTraceAsString(); + $logDB->insert('api_log', [ + 'user_id' => $session->userID, + 'ip' => $ip, + 'date' => $date, + 'path' => $actionPath, + 'arg' => JSON::encode($filteredArgs), + 'aux' => JSON::encode([ + 'result'=>false, + 'state'=>'error_exception', + 'errMsg'=>$errMsg, + 'errTrace'=>$errTrace, + ]), + ]); + Json::dieWithReason("{$errMsg}\n{$errTrace}"); } catch (\Throwable $e) { logExceptionByCustomHandler($e, false); - Json::dieWithReason($e->getMessage()."\n".$e->getTraceAsString()); + $errMsg = $e->getMessage(); + $errTrace = $e->getTraceAsString(); + $logDB->insert('api_log', [ + 'user_id' => $session->userID, + 'ip' => $ip, + 'date' => $date, + 'path' => $actionPath, + 'arg' => JSON::encode($filteredArgs), + 'aux' => JSON::encode([ + 'result'=>false, + 'state'=>'error_throwable', + 'errMsg'=>$errMsg, + 'errTrace'=>$errTrace, + ]), + ]); + Json::dieWithReason("{$errMsg}\n{$errTrace}"); } catch (mixed $e) { - Json::dieWithReason(strval($e)); + $errStr = strval($e); + $logDB->insert('api_log', [ + 'user_id' => $session->userID, + 'ip' => $ip, + 'date' => $date, + 'path' => $actionPath, + 'arg' => JSON::encode($filteredArgs), + 'aux' => JSON::encode([ + 'result'=>false, + 'state'=>'error_mixed', + 'errMsg'=>$errStr, + ]), + ]); + Json::dieWithReason($errStr); } } }