nhance/app/Controllers/TraceableController.php
2025-07-09 10:21:06 +05:30

127 lines
3.4 KiB
PHP

<?php
class DeepLogger
{
private $logFile;
private static $currentUuid;
private static $callDepth = 0;
public function __construct($logFile = 'function_calls.log')
{
$this->logFile = $logFile;
}
public function wrap($instance)
{
$handler = $this;
$class = new ReflectionClass($instance);
foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
if ($method->isConstructor() || $method->isStatic()) continue;
$methodName = $method->getName();
$instance->$methodName = function(...$args) use ($handler, $instance, $methodName) {
return $handler->logCall($instance, $methodName, $args);
};
}
return $instance;
}
public function logCall($instance, $method, $args)
{
$isRootCall = (self::$callDepth === 0);
if ($isRootCall) {
self::$currentUuid = $this->generateUuid();
}
self::$callDepth++;
$reflection = new ReflectionMethod($instance, $method);
// Log IN
$this->writeLog([
'timestamp' => date('Y-m-d H:i:s'),
'uuid' => self::$currentUuid,
'direction' => 'IN',
'function' => get_class($instance) . '::' . $method,
'line' => $reflection->getStartLine(),
'params' => $this->getParameterValues($reflection, $args)
]);
try {
$result = $reflection->invokeArgs($instance, $args);
// Log OUT
$this->writeLog([
'timestamp' => date('Y-m-d H:i:s'),
'uuid' => self::$currentUuid,
'direction' => 'OUT',
'function' => get_class($instance) . '::' . $method,
'line' => $reflection->getEndLine(),
'result' => $result
]);
return $result;
} finally {
self::$callDepth--;
if ($isRootCall) {
self::$currentUuid = null;
}
}
}
private function getParameterValues($reflection, $args)
{
$params = [];
foreach ($reflection->getParameters() as $i => $param) {
$params[$param->name] = $args[$i] ?? ($param->isDefaultValueAvailable()
? $param->getDefaultValue()
: null);
}
return $params;
}
private function writeLog($data)
{
file_put_contents($this->logFile, json_encode($data) . PHP_EOL, FILE_APPEND);
}
private function generateUuid()
{
return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
mt_rand(0, 0xffff), mt_rand(0, 0xffff),
mt_rand(0, 0xffff),
mt_rand(0, 0x0fff) | 0x4000,
mt_rand(0, 0x3fff) | 0x8000,
mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
);
}
}
class TestBusinessController
{
public function a($a = 10)
{
$r = $this->b(50, $a);
return json_encode(['a' => $r]);
}
public function b($x, $y)
{
$r = $this->c($x + $y);
return $r;
}
public function c($x)
{
return $x * 2;
}
}
// Usage:
$logger = new DeepLogger();
$controller = new TestBusinessController();
$loggedController = $logger->wrap($controller);
// This will now log all calls (a, b, and c)
echo $loggedController->a(10);