From d0b9b31421cfe729f14d732f4f8b122d208b84ab Mon Sep 17 00:00:00 2001 From: eeliu <27064129+eeliu@users.noreply.github.com> Date: Mon, 24 Jan 2022 16:20:19 +0800 Subject: [PATCH 01/13] Dev (#47) * add generator plugin InstancePlugins. (#44) * fix next node is unknown when laravel call remote with guzzle. (#46) Co-authored-by: Evelyn <41946743+EyelynSu@users.noreply.github.com> From eab2b282b3c4abcfb0044209f93ab3cfbcd191ed Mon Sep 17 00:00:00 2001 From: eeliu <27064129+eeliu@users.noreply.github.com> Date: Wed, 25 May 2022 09:55:13 +0800 Subject: [PATCH 02/13] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 38 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/custom.md | 10 ++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 ++++++++++++ 3 files changed, 68 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/custom.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..dd84ea7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md new file mode 100644 index 0000000..48d5f81 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/custom.md @@ -0,0 +1,10 @@ +--- +name: Custom issue template +about: Describe this issue template's purpose here. +title: '' +labels: '' +assignees: '' + +--- + + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..bbcbbe7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. From 677fddba093b7e67528a22adf5d251b3ebdc40e5 Mon Sep 17 00:00:00 2001 From: eeliu <27064129+eeliu@users.noreply.github.com> Date: Wed, 25 May 2022 09:56:17 +0800 Subject: [PATCH 03/13] Create dependency-review.yml --- .github/workflows/dependency-review.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/dependency-review.yml diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 0000000..8966511 --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,20 @@ +# Dependency Review Action +# +# This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging. +# +# Source repository: https://github.com/actions/dependency-review-action +# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement +name: 'Dependency Review' +on: [pull_request] + +permissions: + contents: read + +jobs: + dependency-review: + runs-on: ubuntu-latest + steps: + - name: 'Checkout Repository' + uses: actions/checkout@v3 + - name: 'Dependency Review' + uses: actions/dependency-review-action@v1 From 2cf68b39705c5441343c823412e753c1caf5213a Mon Sep 17 00:00:00 2001 From: eeliu <27064129+eeliu@users.noreply.github.com> Date: Sat, 28 Oct 2023 04:18:03 +0000 Subject: [PATCH 04/13] refactor(aop): new api for aop * remove setting.ini --- .devcontainer/devcontainer.json | 15 + v2.0.1.md => Changes.md | 0 Readme.md | 4 + auto_pinpointed.php | 31 +- composer.json | 4 +- lib/Pinpoint/Common/ClassFile.php | 77 ++-- lib/Pinpoint/Common/CodeVisitor.php | 157 +++---- .../Common/GenOriginClassTemplateHelper.php | 291 +++++++++++++ .../Common/GenProxiedClassFileHelper.php | 306 -------------- ...er.php => GenProxyClassTemplateHelper.php} | 383 +++++++++--------- lib/Pinpoint/Common/JoinClass.php | 58 +++ lib/Pinpoint/Common/Monitor.php | 39 ++ lib/Pinpoint/Common/NpCoderVisitor.php | 124 ------ lib/Pinpoint/Common/OriginFileVisitor.php | 31 +- lib/Pinpoint/Common/PerRequest.php | 34 ++ lib/Pinpoint/Common/PinpointDriver.php | 100 ++--- lib/Pinpoint/Common/PluginParser.php | 38 +- lib/Pinpoint/Common/RenderAopClass.php | 33 +- lib/Pinpoint/Common/Utils.php | 93 ++--- lib/Pinpoint/Plugins/PerRequestPlugins.php | 37 +- .../Plugins/Sys/PDO/ProfilerPDOStatement.php | 1 - lib/Pinpoint/test/Bear.php | 14 + .../test/Cache/Pinpoint/test/Bear.php | 35 ++ lib/Pinpoint/test/Cache/Pinpoint/test/Foo.php | 46 --- .../Cache/Pinpoint/test/Proxied_TestClass.php | 72 ---- .../Cache/Pinpoint/test/Proxied_TestTrait.php | 15 - .../test/Cache/Pinpoint/test/ProxyBear.php | 14 + .../test/Cache/Pinpoint/test/TestClass.php | 142 ------- .../test/Cache/Pinpoint/test/TestTrait.php | 24 -- lib/Pinpoint/test/ClassParseTest.php | 131 +++--- .../test/Comparison/Pinpoint/test/Bear.php | 35 ++ .../test/Comparison/Pinpoint/test/Foo.php | 46 --- .../Pinpoint/test/Proxied_TestClass.php | 72 ---- .../Pinpoint/test/Proxied_TestTrait.php | 15 - .../Comparison/Pinpoint/test/ProxyBear.php | 14 + .../Comparison/Pinpoint/test/TestClass.php | 142 ------- .../Comparison/Pinpoint/test/TestTrait.php | 24 -- lib/Pinpoint/test/OriginFileVisitor_test.php | 48 +++ lib/Pinpoint/test/OutputMonitor.php | 21 + lib/Pinpoint/test/bootstrap.php | 2 +- lib/Pinpoint/test/php_parse.php | 2 +- test.php | 70 ++++ 42 files changed, 1247 insertions(+), 1593 deletions(-) create mode 100644 .devcontainer/devcontainer.json rename v2.0.1.md => Changes.md (100%) create mode 100644 lib/Pinpoint/Common/GenOriginClassTemplateHelper.php delete mode 100644 lib/Pinpoint/Common/GenProxiedClassFileHelper.php rename lib/Pinpoint/Common/{GenOriginClassFileHelper.php => GenProxyClassTemplateHelper.php} (52%) create mode 100644 lib/Pinpoint/Common/JoinClass.php create mode 100644 lib/Pinpoint/Common/Monitor.php delete mode 100644 lib/Pinpoint/Common/NpCoderVisitor.php create mode 100644 lib/Pinpoint/Common/PerRequest.php create mode 100644 lib/Pinpoint/test/Bear.php create mode 100644 lib/Pinpoint/test/Cache/Pinpoint/test/Bear.php delete mode 100644 lib/Pinpoint/test/Cache/Pinpoint/test/Foo.php delete mode 100644 lib/Pinpoint/test/Cache/Pinpoint/test/Proxied_TestClass.php delete mode 100644 lib/Pinpoint/test/Cache/Pinpoint/test/Proxied_TestTrait.php create mode 100644 lib/Pinpoint/test/Cache/Pinpoint/test/ProxyBear.php delete mode 100644 lib/Pinpoint/test/Cache/Pinpoint/test/TestClass.php delete mode 100644 lib/Pinpoint/test/Cache/Pinpoint/test/TestTrait.php create mode 100644 lib/Pinpoint/test/Comparison/Pinpoint/test/Bear.php delete mode 100644 lib/Pinpoint/test/Comparison/Pinpoint/test/Foo.php delete mode 100644 lib/Pinpoint/test/Comparison/Pinpoint/test/Proxied_TestClass.php delete mode 100644 lib/Pinpoint/test/Comparison/Pinpoint/test/Proxied_TestTrait.php create mode 100644 lib/Pinpoint/test/Comparison/Pinpoint/test/ProxyBear.php delete mode 100644 lib/Pinpoint/test/Comparison/Pinpoint/test/TestClass.php delete mode 100644 lib/Pinpoint/test/Comparison/Pinpoint/test/TestTrait.php create mode 100644 lib/Pinpoint/test/OriginFileVisitor_test.php create mode 100644 lib/Pinpoint/test/OutputMonitor.php create mode 100644 test.php diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..f3b8c7a --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,15 @@ +{ + "name": "pinpont-php-aop", + "image": "mcr.microsoft.com/devcontainers/php:7.4", + "remoteUser": "vscode", + "customizations": { + "vscode": { + "extensions": [ + "streetsidesoftware.code-spell-checker", + "recca0120.vscode-phpunit", + "donjayamanne.githistory", + "adam-bender.commit-message-editor" + ] + } + } +} \ No newline at end of file diff --git a/v2.0.1.md b/Changes.md similarity index 100% rename from v2.0.1.md rename to Changes.md diff --git a/Readme.md b/Readme.md index a68b703..2ffbd35 100644 --- a/Readme.md +++ b/Readme.md @@ -1,5 +1,9 @@ [![Build](https://github.com/pinpoint-apm/pinpoint-php-aop/workflows/Build/badge.svg?branch=master)](https://github.com/pinpoint-apm/pinpoint-php-aop/actions) [![LICENSE](https://img.shields.io/github/license/pinpoint-apm/pinpoint-php-aop)](LICENSE) +## Issues + +https://github.com/pinpoint-apm/pinpoint-c-agent/labels/php-aop + ## How to Use ### Import from packagist diff --git a/auto_pinpointed.php b/auto_pinpointed.php index 442901e..d77b2c9 100644 --- a/auto_pinpointed.php +++ b/auto_pinpointed.php @@ -1,16 +1,27 @@ -start(); diff --git a/composer.json b/composer.json index 485f22b..4da4723 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,7 @@ "authors": [ { "name": "eeliu", - "email": "eeliu2009@gmail.com" + "email": "liu.mingyi@navercorp.com" } ], "autoload": { @@ -22,4 +22,4 @@ "php": ">=7", "nikic/php-parser": "^4.1" } -} +} \ No newline at end of file diff --git a/lib/Pinpoint/Common/ClassFile.php b/lib/Pinpoint/Common/ClassFile.php index d700f0e..089125f 100644 --- a/lib/Pinpoint/Common/ClassFile.php +++ b/lib/Pinpoint/Common/ClassFile.php @@ -1,4 +1,6 @@ -prefix = $prefix; + $this->newNamePrefix = $_newNamePrefix; $this->_astPrinter = new PrettyPrinter\Standard(); } - public function getNode() - { - return $this->node; - } + // public function getNode() + // { + // return $this->node; + // } - public function handleEnterNamespaceNode(&$node) + public function handleEnterNamespaceNode($node) { assert($node instanceof Node\Stmt\Namespace_); $this->namespace = trim($node->name->toString()); } - public function handleEnterClassNode(&$node) + public function handleEnterClassNode($node) { assert($node instanceof Node\Stmt\Class_); - if($this->namespace) - { - $this->className = trim($this->namespace.'\\'.$node->name->toString()); - }else{ + if ($this->namespace) { + $this->className = trim($this->namespace . '\\' . $node->name->toString()); + } else { $this->className = trim($node->name->toString()); } } @@ -99,8 +101,8 @@ public function handleEnterClassNode(&$node) public function handleEnterTraitNode(&$node) { assert($node instanceof Node\Stmt\Trait_); - if($this->namespace) - $this->traitName = trim($this->namespace.'\\'.$node->name->toString()); + if ($this->namespace) + $this->traitName = trim($this->namespace . '\\' . $node->name->toString()); else $this->traitName = trim($node->name->toString()); } @@ -109,34 +111,37 @@ public function handleClassEnterMethodNode(&$node) { assert($node instanceof Node\Stmt\ClassMethod); $this->funcName = $node->name->toString(); - $this->classMethod =$this->className.'::'.$this->funcName; + $this->classMethod = $this->className . '::' . $this->funcName; $this->hasRet = false; } - abstract function handleLeaveMethodNode(&$node); - public function markHasReturn(&$node) { - if(isset($node->expr)) - { + if (isset($node->expr)) { $this->hasRet = true; } } - public function markHasYield(&$node) + public function markHasYield() { $this->hasRet = true; } - public function fileNodeDoneCB(&$node, $loaderName) + public function done() { - $fullPath = AOP_CACHE_DIR.'/'.str_replace('\\','/',$loaderName).'.php'; - $context= $this->_astPrinter->prettyPrintFile($node); - RenderAopClass::getInstance()->insertMapping($loaderName,$fullPath); - Utils::saveObj($context,$fullPath); + $fullPath = AOP_CACHE_DIR . '/' . str_replace('\\', '/', $this->className) . '.php'; + $context = $this->_astPrinter->prettyPrintFile($this->newAstNode); + RenderAopClass::getInstance()->insertMapping($this->className, $fullPath); + Utils::saveObj($context, $fullPath); } - abstract function handleAfterTravers(&$nodes); - abstract function handleLeaveNamespace(&$nodes); - abstract function handlerUseNode(&$node); + abstract function handleAfterTraverse($nodes); + abstract function handleLeaveNamespace($nodes); + abstract function handlerUseNode($node); + abstract function handleMagicConstNode($node); + abstract function handleLeaveMethodNode($node); + abstract function handleEnterClassConstFetch($node); + abstract function handleEnterNew($node); + abstract function handleEnterFuncCall($node); + abstract function handleLeaveClassNode($node); } diff --git a/lib/Pinpoint/Common/CodeVisitor.php b/lib/Pinpoint/Common/CodeVisitor.php index e185195..ea84622 100644 --- a/lib/Pinpoint/Common/CodeVisitor.php +++ b/lib/Pinpoint/Common/CodeVisitor.php @@ -1,4 +1,6 @@ -originClassFile = $originClassFile; - $this->proxiedClassFile = $proxiedClassFile; + $this->visitors = $_visitors; } public function enterNode(Node $node) { - if($node instanceof Node\Stmt\Namespace_) - { - $this->curNamespace = $node->name->toString(); - /// set namespace - $this->originClassFile->handleEnterNamespaceNode($node); - $this->proxiedClassFile->handleEnterNamespaceNode($node); - } - elseif ($node instanceof Node\Stmt\Use_){ - $this->proxiedClassFile->handlerUseNode($node); - $this->originClassFile->handlerUseNode($node); - } - elseif ($node instanceof Node\Stmt\Class_){ - if(empty($node->name->toString())){ + if ($node instanceof Node\Stmt\Namespace_) { + foreach ($this->visitors as $visitor) { + assert($visitor instanceof ClassFile); + $visitor->handleEnterNamespaceNode($node); + } + } elseif ($node instanceof Node\Stmt\Use_) { + foreach ($this->visitors as $visitor) { + $visitor->handlerUseNode($node); + } + } elseif ($node instanceof Node\Stmt\Class_) { + if (empty($node->name->toString())) { throw new \Exception("can't AOP an anonymous class"); } - $this->curName = empty($this->curNamespace) ? ($node->name->toString()):($this->curNamespace.'\\'.$node->name->toString()); - $this->originClassFile->handleEnterClassNode($node); - $this->proxiedClassFile->handleEnterClassNode($node); - } - elseif( $node instanceof Node\Stmt\Trait_){ - if(empty($node->name->toString())){ + + // $this->className = empty($this->classNamespace) ? ($node->name->toString()) : ($this->classNamespace . '\\' . $node->name->toString()); + + foreach ($this->visitors as $visitor) { + $visitor->handleEnterClassNode($node); + } + } elseif ($node instanceof Node\Stmt\Trait_) { + if (empty($node->name->toString())) { throw new \Exception("can't AOP an anonymous trait"); } - $this->curName = empty($this->curNamespace) ? ($node->name->toString()):($this->curNamespace.'\\'.$node->name->toString()); + // $this->className = empty($this->classNamespace) ? ($node->name->toString()) : ($this->classNamespace . '\\' . $node->name->toString()); - $this->proxiedClassFile->handleEnterTraitNode($node); - $this->originClassFile->handleEnterTraitNode($node); - }elseif ($node instanceof Node\Stmt\ClassMethod) - { - $this->originClassFile->handleClassEnterMethodNode($node); - $this->proxiedClassFile->handleClassEnterMethodNode($node); - } - elseif ( $node instanceof Node\Stmt\Return_) - { - $this->originClassFile->markHasReturn($node); - } - elseif ($node instanceof Node\Expr\Yield_){ - $this->originClassFile->markHasYield($node); - } - elseif ($node instanceof Node\Expr\ClassConstFetch){ - return $this->proxiedClassFile->handleEnterClassConstFetch($node); - }elseif ($node instanceof Node\Expr\New_){ - return $this->proxiedClassFile->handleEnterNew_($node); - }elseif ($node instanceof Node\Expr\FuncCall){ - return $this->proxiedClassFile->handleEnterFuncCall($node); + foreach ($this->visitors as $visitor) { + $visitor->handleEnterTraitNode($node); + } + } elseif ($node instanceof Node\Stmt\ClassMethod) { + foreach ($this->visitors as $visitor) { + $visitor->handleClassEnterMethodNode($node); + } + } elseif ($node instanceof Node\Stmt\Return_) { + foreach ($this->visitors as $visitor) { + $visitor->markHasReturn($node); + } + } elseif ($node instanceof Node\Expr\Yield_) { + foreach ($this->visitors as $visitor) { + $visitor->markHasYield(); + } + } elseif ($node instanceof Node\Expr\ClassConstFetch) { + foreach ($this->visitors as $visitor) { + $visitor->handleEnterClassConstFetch($node); + } + } elseif ($node instanceof Node\Expr\New_) { + foreach ($this->visitors as $visitor) { + $visitor->handleEnterNew($node); + } + } elseif ($node instanceof Node\Expr\FuncCall) { + foreach ($this->visitors as $visitor) { + $visitor->handleEnterFuncCall($node); + } } } public function leaveNode(Node $node) { - if ($node instanceof Node\Stmt\ClassMethod){ - $this->originClassFile->handleLeaveMethodNode($node); - $this->proxiedClassFile->handleLeaveMethodNode($node); - }elseif ($node instanceof Node\Name\FullyQualified){ - } - elseif ($node instanceof Node\Scalar\MagicConst){ - return $this->proxiedClassFile->handleMagicConstNode($node); - }elseif ($node instanceof Node\Stmt\Namespace_){ - return $this->proxiedClassFile->handleLeaveNamespace($node); - } - elseif ($node instanceof Node\Stmt\Class_) { - $this->proxiedClassFile->handleLeaveClassNode($node); - }elseif ($node instanceof Node\Stmt\Trait_){ + if ($node instanceof Node\Stmt\ClassMethod) { + foreach ($this->visitors as $visitor) { + $visitor->handleLeaveMethodNode($node); + } + } elseif ($node instanceof Node\Scalar\MagicConst) { + foreach ($this->visitors as $visitor) { + $visitor->handleMagicConstNode($node); + } + } elseif ($node instanceof Node\Stmt\Namespace_) { + foreach ($this->visitors as $visitor) { + $visitor->handleLeaveNamespace($node); + } + } elseif ($node instanceof Node\Stmt\Class_) { + foreach ($this->visitors as $visitor) { + $visitor->handleLeaveClassNode($node); + } + } elseif ($node instanceof Node\Stmt\Trait_) { - $this->proxiedClassFile->handleLeaveTraitNode($node); + foreach ($this->visitors as $visitor) { + $visitor->handleLeaveTraitNode($node); + } } - elseif ($node instanceof Node\Stmt\UseUse){ - return $node; - } + return $node; } public function afterTraverse(array $nodes) { - $node = $this->proxiedClassFile->handleAfterTravers($nodes); - - $this->proxiedClassFile->fileNodeDoneCB($node,$this->proxiedClassFile->myLoaderName); - - $node = $this->originClassFile->handleAfterTravers($nodes); - - $this->originClassFile->fileNodeDoneCB($node,$this->originClassFile->fileName); - + foreach ($this->visitors as $visitor) { + $visitor->handleAfterTraverse($nodes); + $visitor->done(); + } } - } diff --git a/lib/Pinpoint/Common/GenOriginClassTemplateHelper.php b/lib/Pinpoint/Common/GenOriginClassTemplateHelper.php new file mode 100644 index 0000000..b360cc1 --- /dev/null +++ b/lib/Pinpoint/Common/GenOriginClassTemplateHelper.php @@ -0,0 +1,291 @@ +name); + + $this->originClassFileDir = dirname($path); + $this->originClassFilePath = $path; + // $this->joinClass = $joinClass; + $this->classAliasSet = $joinClass->classAlias; + $this->funcAlias = $joinClass->funcAlias; + $this->methodJoint = $joinClass->methodJoinPoints; + } + + private function getRealNp($node) + { + + if ($node instanceof Node\Name\FullyQualified) // Use directly access + { + return $node->toString(); + } elseif ($node instanceof Node\Expr\Variable) { //#16 support new a variable + return $node->name; + } elseif ($node instanceof Node\Name) { // Use namespace suggestion + $prefixNm = $node->getFirst(); + if (isset($this->suffix_use[$prefixNm])) { + $namePrefix = $this->suffix_use[$prefixNm]; + $nm = $namePrefix . "\\" . $node->toString(); + return $nm; + } else { + return $node->toString(); + } + } + } + + + public function renderClassName($node, $filer) + { + $classFullName = $this->getRealNp($node); + + if (isset($filer[$classFullName])) { + $newName = $filer[$classFullName]; + return new Node\Name\FullyQualified($newName); + } + return $node; + } + + public function renderFunName(&$node, $filer) + { + $classFullName = $node->toString(); + if (isset($filer[$classFullName])) { + $newName = $filer[$classFullName]; + return new Node\Name\FullyQualified($newName); + } + return $node; + } + + public function handleEnterFuncCall($node) + { + assert($node instanceof Node\Expr\FuncCall); + if ($node->name instanceof Node\Expr\Variable) { + // not support anonymous function + } else { + $node->name = $this->renderFunName($node->name, $this->funcAlias); + } + return $node; + } + + + public function handleEnterNew($node) + { + assert($node instanceof Node\Expr\New_); + $node->class = $this->renderClassName($node->class, $this->classAliasSet); + return $node; + } + + public function handleEnterClassConstFetch($node) + { + assert($node instanceof Node\Expr\ClassConstFetch); + $node->class = $this->renderClassName($node->class, $this->classAliasSet); + return $node; + } + + + /** rename the class Proxied_foo + * @param $node + */ + public function handleLeaveClassNode($node) + { + assert($node instanceof Node\Stmt\Class_); + $className = $this->newNamePrefix . $node->name->toString(); + + $node->name = new Node\Identifier($className); + + $this->className = empty($this->namespace) ? ($className) : $this->namespace . '\\' . $className; + $this->myLoaderName = $this->className; + + if ($node->flags & Node\Stmt\Class_::MODIFIER_FINAL) { + /// remove FINAL flag + $node->flags = $node->flags & (~(Node\Stmt\Class_::MODIFIER_FINAL)); + } + } + + /** + * rename trait Foo{} => trait Proxy_Foo{} + * @param $node + */ + public function handleLeaveTraitNode(&$node) + { + assert($node instanceof Node\Stmt\Trait_); + $className = $this->newNamePrefix . $node->name->toString(); + + $node->name = new Node\Identifier($className); + + $this->traitName = empty($this->namespace) ? ($className) : ($this->namespace . '\\' . $className); + $this->myLoaderName = $this->traitName; + } + + + public function handleLeaveMethodNode($node) + { + $func = trim($node->name->toString()); + if (!array_key_exists($func, $this->methodJoint)) { + return; + } + + assert($node instanceof Node\Stmt\ClassMethod); + if ($node->flags & Node\Stmt\Class_::MODIFIER_PRIVATE) { + // unset private + $node->flags = $node->flags & (~Node\Stmt\Class_::MODIFIER_PRIVATE); + + // set protect + $node->flags = $node->flags | (Node\Stmt\Class_::MODIFIER_PROTECTED); + } + + if ($node->flags & Node\Stmt\Class_::MODIFIER_FINAL) { + $node->flags = $node->flags & (~Node\Stmt\Class_::MODIFIER_FINAL); + } + } + + /** + * @obsoleted + * convert \Exception to Exception + * try to use namespace cover + * @param $node + * @return Node\Name + */ + public function handleFullyQualifiedNode(&$node) + { + assert($node instanceof Node\Name\FullyQualified); + $name = $node->toString(); + if (isset($this->classAliasSet[$name])) { + return new Node\Name\FullyQualified($this->classAliasSet[$name]); + } else { + return $node; + } + } + + public function handleMagicConstNode($node) + { + switch ($node->getName()) { + case '__FILE__': + return new Node\Scalar\String_($this->originClassFilePath); + case '__DIR__': + return new Node\Scalar\String_($this->originClassFileDir); + case '__FUNCTION__': + return new Node\Scalar\String_($this->classMethod); + case '__CLASS__': + return new Node\Scalar\String_($this->className); + case '__METHOD__': + return new Node\Scalar\String_($this->classMethod); + case '__NAMESPACE__': + return new Node\Scalar\String_($this->namespace); + case '__LINE__': + return new Node\Scalar\LNumber($node->getAttribute('startLine')); + default: + break; + } + return $node; + } + + + public function handleLeaveNamespace($nodes) + { + return $nodes; + } + + + function handlerUseUseNode(&$node) + { + assert($node instanceof Node\Stmt\UseUse); + + // parse use A\B\C as ABC; + // here , A\B\C is hidden by ABC + // so re-add ABC + if ($node->alias) { + $namespaceAlias = $node->alias->name; + $hiddenClassAlias = []; + $newName = trim($node->name->toString(), "\ \\"); + foreach ($this->classAliasSet as $clName => $classAlias) { + if (strpos($clName, $newName) === 0) { + $classNewName = str_replace($newName, $namespaceAlias, $clName); + $hiddenClassAlias[$classNewName] = $classAlias; + } + } + if (!empty($hiddenClassAlias)) { + $this->classAliasSet += $hiddenClassAlias; + } + return; + } + + // parse use A/B/C, but the nm_ is A/B/C/D + $suffixNm = $node->name->getLast(); + if (!$node->name->isUnqualified()) { + $this->suffix_use[$suffixNm] = $node->name->slice(0, -1)->toString(); + } + } + + function handleAfterTraverse($nodes) + { + $this->newAstNode = $nodes; + } + + function handlerUseNode($node) + { + //rename the nodes + assert($node instanceof Node\Stmt\Use_); + $type = $node->type; + if ($type == Node\Stmt\Use_::TYPE_CONSTANT) { + return; + } + + // replace the exactly match + // use A/B/C; -> Plugins/A/B/C + foreach ($node->uses as &$uses) { + $fullName = trim($uses->name->toString(), "\ \\"); + + if ($type == Node\Stmt\Use_::TYPE_FUNCTION) { + // use function Math\{add, subtract}; + if (array_key_exists($fullName, $this->funcAlias)) { + $newName = new Node\Name($this->funcAlias[$fullName]); + $uses->name = $newName; + } + } else { + // use ABC\Math; + if (array_key_exists($fullName, $this->classAliasSet)) { + $newName = new Node\Name($this->classAliasSet[$fullName]); + $uses->name = $newName; + } + } + } + } +} diff --git a/lib/Pinpoint/Common/GenProxiedClassFileHelper.php b/lib/Pinpoint/Common/GenProxiedClassFileHelper.php deleted file mode 100644 index c485d29..0000000 --- a/lib/Pinpoint/Common/GenProxiedClassFileHelper.php +++ /dev/null @@ -1,306 +0,0 @@ -orgDir = dirname($fullFile); - $this->mAopFuncInfo = $aopFuncInfo; - $this->orgFile = $fullFile; - if(!empty($naming)){ - $this->t_covertCls = $naming['classCall']; - $this->t_covertFuns = $naming['funCall']; - } - } - - private function getRealNp($node) - { - - if($node instanceof Node\Name\FullyQualified) // Use directly access - { - return $node->toString(); - }elseif ($node instanceof Node\Expr\Variable){ //#16 support new a variable - return $node->name; - }elseif($node instanceof Node\Name){ // Use namespace suggestion - $prefixNm = $node->getFirst(); - if(isset($this->suffix_use[$prefixNm])){ - $prefix = $this->suffix_use[$prefixNm]; - $nm = $prefix."\\".$node->toString(); - return $nm; - } - else{ - return $node->toString(); - } - } - } - - - public function renderClassName(&$node,$filer) - { - $classFullName = $this->getRealNp($node); - - if(isset( $filer[$classFullName])) - { - $newName = $filer[$classFullName]; - return new Node\Name\FullyQualified($newName); - } - return $node; - - } - - public function renderFunName(&$node,$filer) - { - $classFullName = $node->toString(); - if(isset( $filer[$classFullName])) - { - $newName =$filer[$classFullName]; - return new Node\Name\FullyQualified($newName); - } - return $node; - } - - public function handleEnterFuncCall(&$node) - { - assert($node instanceof Node\Expr\FuncCall); - if($node->name instanceof Node\Expr\Variable){ - // not support anonymous function - }else{ - $node->name = $this->renderFunName($node->name,$this->t_covertFuns); - } - return $node; - } - - - public function handleEnterNew_(&$node) - { - assert($node instanceof Node\Expr\New_); - $node->class = $this->renderClassName($node->class,$this->t_covertCls); - return $node; - } - - public function handleEnterClassConstFetch(&$node) - { - assert($node instanceof Node\Expr\ClassConstFetch); - $node->class = $this->renderClassName($node->class,$this->t_covertCls); - return $node; - } - - - /** rename the class Proxied_foo - * @param $node - */ - public function handleLeaveClassNode(&$node) - { - assert($node instanceof Node\Stmt\Class_); - $className = $this->prefix.$node->name->toString(); - - $node->name = new Node\Identifier($className); - - $this->className = empty($this->namespace) ? ($className): $this->namespace.'\\'.$className; - $this->myLoaderName = $this->className; - - if($node->flags & Node\Stmt\Class_::MODIFIER_FINAL) - { - /// remove FINAL flag - $node->flags = $node->flags & ( ~(Node\Stmt\Class_::MODIFIER_FINAL) ); - } - } - - /** - * rename trait Foo{} => trait Proxed_Foo{} - * @param $node - */ - public function handleLeaveTraitNode(&$node) - { - assert($node instanceof Node\Stmt\Trait_); - $className =$this->prefix.$node->name->toString(); - - $node->name = new Node\Identifier($className); - - $this->traitName = empty($this->namespace) ? ($className):($this->namespace.'\\'.$className); - $this->myLoaderName = $this->traitName; - } - - - public function handleLeaveMethodNode(&$node) - { - $func = trim( $node->name->toString()); - if(!array_key_exists($func,$this->mAopFuncInfo)) - { - return ; - } - - assert($node instanceof Node\Stmt\ClassMethod); - if($node->flags & Node\Stmt\Class_::MODIFIER_PRIVATE) - { - // unset private - $node->flags = $node->flags &(~Node\Stmt\Class_::MODIFIER_PRIVATE); - - // set protect - $node->flags = $node->flags | (Node\Stmt\Class_::MODIFIER_PROTECTED); - } - - if($node->flags & Node\Stmt\Class_::MODIFIER_FINAL) - { - $node->flags = $node->flags &(~Node\Stmt\Class_::MODIFIER_FINAL); - } - - } - - /** - * @obsoleted - * convert \Exception to Exception - * try to use namespace cover - * @param $node - * @return Node\Name - */ - public function handleFullyQualifiedNode(&$node) - { - assert($node instanceof Node\Name\FullyQualified); - $name = $node->toString(); - if( isset($this->t_covertCls[$name]) ) { - return new Node\Name\FullyQualified($this->t_covertCls[$name]); - }else{ - return $node; - } - } - - public function addRequiredFile($fullName) - { - - } - - public function handleMagicConstNode(&$node) - { - switch ($node->getName()) - { - case '__FILE__': - return new Node\Scalar\String_($this->orgFile); - case '__DIR__': - return new Node\Scalar\String_($this->orgDir); - case '__FUNCTION__': - return new Node\Scalar\String_($this->classMethod); - case '__CLASS__': - return new Node\Scalar\String_($this->className); - case '__METHOD__': - return new Node\Scalar\String_($this->classMethod); - case '__NAMESPACE__': - return new Node\Scalar\String_($this->namespace); - case '__LINE__': - return new Node\Scalar\LNumber($node->getAttribute('startLine')); - default: - break; - } - return $node; - } - - - public function handleLeaveNamespace(&$nodes) - { - return $nodes; - } - - public function handleAfterTravers(&$nodes) - { - return $nodes; - } - - function handlerUseUseNode(&$node) - { - assert($node instanceof Node\Stmt\UseUse); - - // parse use A/B/C as ABC; - if($node->alias){ - $aliasNm = $node->alias->name; - $appendCl =[]; - $name = trim($node->name->toString(),"\ \\"); - foreach ($this->t_covertCls as $clName =>$value) - { - if(strpos($clName,$name) === 0) - { - $np = str_replace($name ,$aliasNm,$clName); - $appendCl[$np] = $value; - } - } - if(!empty($appendCl)) - { - $this->t_covertCls += $appendCl; - } - return ; - } - - // parse use A/B/C, but the nm_ is A/B/C/D - $suffixNm = $node->name->getLast(); - if(!$node->name->isUnqualified()){ - $this->suffix_use[$suffixNm] =$node->name->slice(0,-1)->toString(); - } - - } - - function handlerUseNode(&$node) - { - //rename the nodes - assert($node instanceof Node\Stmt\Use_); - $type = $node->type; - if($type == Node\Stmt\Use_::TYPE_CONSTANT){ - return ; - } - - // replace the exactly match - // use A/B/C; -> Plugins/A/B/C - foreach ($node->uses as &$uses) - { - $fullName = trim($uses->name->toString(),"\ \\"); - if($type == Node\Stmt\Use_::TYPE_FUNCTION){ - if(isset($this->t_covertFuns[$fullName])){ - $newName = new Node\Name($this->t_covertFuns[$fullName]); - $uses->name = $newName; - } - } - else{ // normal and unknow - if(isset($this->t_covertCls[$fullName])){ - $newName = new Node\Name($this->t_covertCls[$fullName]); - $uses->name = $newName; - } - } - } - - } -} diff --git a/lib/Pinpoint/Common/GenOriginClassFileHelper.php b/lib/Pinpoint/Common/GenProxyClassTemplateHelper.php similarity index 52% rename from lib/Pinpoint/Common/GenOriginClassFileHelper.php rename to lib/Pinpoint/Common/GenProxyClassTemplateHelper.php index 66cfd2e..c5e77d2 100644 --- a/lib/Pinpoint/Common/GenOriginClassFileHelper.php +++ b/lib/Pinpoint/Common/GenProxyClassTemplateHelper.php @@ -1,4 +1,6 @@ -factory= new BuilderFactory(); - $this->mAopFunInfoAr = $aopFuncInfo; - $this->mClassNode = null; - $this->mTraitNode = null; + $this->factory = new BuilderFactory(); + $this->methodJoinPoints = $joinClass->methodJoinPoints; } - public function handleEnterNamespaceNode(&$node) + public function handleEnterNamespaceNode($node) { parent::handleEnterNamespaceNode($node); - } - public function handleEnterClassNode(&$node) + public function handleEnterClassNode($node) { assert($node instanceof Node\Stmt\Class_); parent::handleEnterClassNode($node); - $extendClass = $this->prefix.$node->name->toString(); + $extendClass = $this->newNamePrefix . $node->name->toString(); $this->mClassNode = $this->factory->class(trim($node->name->toString()))->extend($extendClass); - if(!empty($this->namespace)) - { - // if the proxied_class has namespace, add into use + if (!empty($this->namespace)) { + // if the proxy_class has namespace, add into use // if not, just ignore it . support for yii1 - $fullName = $this->namespace.'\\'.$extendClass; - $this->useBlockAr[] = array($fullName,null); + $fullName = $this->namespace . '\\' . $extendClass; + $this->useBlockAr[] = array($fullName, null); } - switch($node->flags) { + switch ($node->flags) { case Node\Stmt\Class_::MODIFIER_FINAL: $this->mClassNode->makeFinal(); break; case Node\Stmt\Class_::MODIFIER_ABSTRACT: $this->mClassNode->makeAbstract(); break; - default: + default: break; } - $this->handleMethodNodeLeaveFunc = 'handleClassLeaveMethodNode'; - $this->handleEndTraversFunc = 'handleAfterTraversClass'; + $this->handleLeaveMethodCb = array($this, 'handleClassLeaveMethodNode'); + $this->handleEndTraverseCb = array($this, 'handleAfterTraverseClass'); } public function handleEnterTraitNode(&$node) @@ -97,9 +94,9 @@ public function handleEnterTraitNode(&$node) assert($node instanceof Node\Stmt\Trait_); parent::handleEnterTraitNode($node); $this->mTraitNode = $this->factory->trait(trim($node->name->toString())); - $this->extendTraitName = $this->prefix.$node->name->toString(); - $this->handleMethodNodeLeaveFunc = 'handleTraitLeaveMethodNode'; - $this->handleEndTraversFunc = 'handleAfterTraversTrait'; + $this->extendTraitName = $this->newNamePrefix . $node->name->toString(); + $this->handleLeaveMethodCb = array($this, 'handleTraitLeaveMethodNode'); + $this->handleEndTraverseCb = array($this, 'handleAfterTraverseTrait'); } public static function convertParamsName2Arg($params) @@ -108,39 +105,27 @@ public static function convertParamsName2Arg($params) $args = []; - foreach ($params as $param) - { + foreach ($params as $param) { assert($param instanceof Node\Param); - $args [] = new Node\Arg($param->var); + $args[] = new Node\Arg($param->var); } return $args; } - public function handleClassLeaveMethodNode(&$node,&$info) + public function handleClassLeaveMethodNode($node, $monitorClassFullName) { - /// todo this func looks ugly - assert($node instanceof Node\Stmt\ClassMethod); - list($mode, $namespace, $className) = $info; - - $namespace = rtrim($namespace,"\\"); - $np = empty($namespace) ? "\\".$className : $namespace. '\\' . $className; - $np_ar = [$np,null]; - if( !static::itemInArray($this->useBlockAr,$np_ar)){ - $this->useBlockAr[] = $np_ar; - } - - // foo_1 - $thisFuncName = $node->name->toString(); + // 1. make a new method overriding parent's + $originMethodName = $node->name->toString(); $funcVar = new Node\Arg(new Node\Scalar\MagicConst\Method()); - // public function funcName(){} - $thisMethod = $this->factory->method($thisFuncName); + $thisMethod = $this->factory->method($originMethodName); + // 1.1 public/protect/private/ if ($node->flags & Node\Stmt\Class_::MODIFIER_PUBLIC) { $thisMethod->makePublic(); } @@ -154,7 +139,7 @@ public function handleClassLeaveMethodNode(&$node,&$info) $thisMethod->makeAbstract(); } - if($node->flags & Node\Stmt\Class_::MODIFIER_FINAL){ + if ($node->flags & Node\Stmt\Class_::MODIFIER_FINAL) { $thisMethod->makeFinal(); } @@ -162,115 +147,118 @@ public function handleClassLeaveMethodNode(&$node,&$info) $thisMethod->makeProtected(); } + //1.2 gen $this-> if ($node->flags & Node\Stmt\Class_::MODIFIER_STATIC) { $thisMethod->makeStatic(); $selfVar = new Node\Arg(new Node\Expr\ConstFetch(new Node\Name('null'))); - }else{ + } else { $selfVar = new Node\Arg(new Node\Expr\Variable('this')); } - $pluginArgs = array_merge([$funcVar,$selfVar],GenOriginClassFileHelper::convertParamsName2Arg($node->params)); + $methodParams = array_merge([$funcVar, $selfVar], GenProxyClassTemplateHelper::convertParamsName2Arg($node->params)); $thisMethod->addParams($node->params); - if($node->returnType){ + if ($node->returnType) { $thisMethod->setReturnType($node->returnType); } - $varName = $className.'_'.$thisFuncName.'_var'; - $retName = $className.'_'.$thisFuncName.'_ret'; + $varName = '_pinpoint_' . $originMethodName . '_var'; + $retName = '_pinpoint_' . $originMethodName . '_ret'; - /// $var = new CommonPlugins(__FUNCTION__,self,$p); - $newPluginsStm = new Node\Stmt\Expression(new Node\Expr\Assign(new Node\Expr\Variable($varName), - $this->factory->new($className, $pluginArgs))); + /// $_pinpoint_method_var = new pinpoint\Plugins\CommonPlugins(__FUNCTION__,self,$p); + $newPluginsStm = new Node\Stmt\Expression(new Node\Expr\Assign( + new Node\Expr\Variable($varName), + $this->factory->new(new Node\Name\FullyQualified($monitorClassFullName) , $methodParams) + )); $thisMethod->addStmt($newPluginsStm); // $var = null; - $newVar = new Node\Stmt\Expression(new Node\Expr\Assign(new Node\Expr\Variable($retName), - new Node\Expr\ConstFetch(new Node\Name('null')))); + $newVar = new Node\Stmt\Expression(new Node\Expr\Assign( + new Node\Expr\Variable($retName), + new Node\Expr\ConstFetch(new Node\Name('null')) + )); $thisMethod->addStmt($newVar); $tryBlock = []; $catchNode = []; - if ($mode & PluginParser::BEFORE) - { - // $var->onBefore(); - $tryBlock[] = new Node\Stmt\Expression( - $this->factory->methodCall(new Node\Expr\Variable($varName), "onBefore")); - } + // $plugin->onBefore(); + $tryBlock[] = new Node\Stmt\Expression( + $this->factory->methodCall(new Node\Expr\Variable($varName), "onBefore") + ); if ($this->hasRet) { - /// $ret = paraent::$thisFuncName(); + /// $ret = paraent::$originMethodName(); $tryBlock[] = new Node\Stmt\Expression(new Node\Expr\Assign( new Node\Expr\Variable($retName), - new Node\Expr\StaticCall(new Node\Name("parent"), - new Node\Identifier($thisFuncName), - GenOriginClassFileHelper::convertParamsName2Arg($node->params)))); + new Node\Expr\StaticCall( + new Node\Name("parent"), + new Node\Identifier($originMethodName), + GenProxyClassTemplateHelper::convertParamsName2Arg($node->params) + ) + )); /// $var->onEnd($ret); - if($mode & PluginParser::END) - { - $tryBlock[] = new Node\Stmt\Expression( - $this->factory->methodCall( - new Node\Expr\Variable($varName), - "onEnd", - [new Node\Expr\Variable($retName)] - ) - ); - } + $tryBlock[] = new Node\Stmt\Expression( + $this->factory->methodCall( + new Node\Expr\Variable($varName), + "onEnd", + [new Node\Expr\Variable($retName)] + ) + ); /// return $var; $tryBlock[] = new Node\Stmt\Return_(new Node\Expr\Variable($retName)); - } else { - /// paraent::$thisFuncName(); + /// paraent::$originMethodName(); $tryBlock[] = new Node\Stmt\Expression($this->factory->staticCall( - new Node\Name("parent") - , new Node\Identifier($thisFuncName), - GenOriginClassFileHelper::convertParamsName2Arg($node->params))); + new Node\Name("parent"), + new Node\Identifier($originMethodName), + GenProxyClassTemplateHelper::convertParamsName2Arg($node->params) + )); /// $var->onEnd($ret); - if($mode & PluginParser::END) - { - $tryBlock[] = new Node\Stmt\Expression( - $this->factory->methodCall( - new Node\Expr\Variable($varName), - "onEnd", - [new Node\Expr\Variable($retName)] - ) - ); - } + $tryBlock[] = new Node\Stmt\Expression( + $this->factory->methodCall( + new Node\Expr\Variable($varName), + "onEnd", + [new Node\Expr\Variable($retName)] + ) + ); } $expArgs = []; - $expArgs[] = new Node\Arg(new Node\Expr\Variable('e')) ; + $expArgs[] = new Node\Arg(new Node\Expr\Variable('e')); - if ($mode & PluginParser::EXCEPTION) { - - $catchBlock[] = new Node\Stmt\Expression( - $this->factory->methodCall(new Node\Expr\Variable($varName), - "onException",$expArgs)); - } + $catchBlock[] = new Node\Stmt\Expression( + $this->factory->methodCall( + new Node\Expr\Variable($varName), + "onException", + $expArgs + ) + ); $catchBlock[] = new Node\Stmt\Throw_(new Node\Expr\Variable("e")); - $catchNode[] = new Node\Stmt\Catch_([new Node\Name('\Exception')], + $catchNode[] = new Node\Stmt\Catch_( + [new Node\Name('\Exception')], new Node\Expr\Variable('e'), - $catchBlock); + $catchBlock + ); - $tryCatchFinallyNode = new Node\Stmt\TryCatch($tryBlock,$catchNode); + $tryCatchFinallyNode = new Node\Stmt\TryCatch($tryBlock, $catchNode); $thisMethod->addStmt($tryCatchFinallyNode); $this->mClassNode->addStmt($thisMethod); } - public static function itemInArray($ar,$v) + public static function itemInArray($ar, $v) { - $new = array_filter($ar,function ($a) use($v){ - if($a == $v){ + $new = array_filter($ar, function ($a) use ($v) { + if ($a == $v) { return $a; } }); @@ -278,9 +266,9 @@ public static function itemInArray($ar,$v) return !empty($new); } - public function handleTraitLeaveMethodNode(&$node,&$info) + public function handleTraitLeaveMethodNode($node, $info) { - /// todo this func looks ugly + /// todo this methodName looks ugly /// - check use , add use Proxied_Foo { } /// - insert alias use Proxied_Foo::xxx as Foo_xxxx @@ -291,24 +279,24 @@ public function handleTraitLeaveMethodNode(&$node,&$info) list($mode, $namespace, $className) = $info; // foo_1 - $thisFuncName = $node->name->toString(); + $originMethodName = $node->name->toString(); - $np = empty($namespace) ? $className : $namespace. '\\' . $className; - $np_ar = [$np,null]; + $np = empty($namespace) ? $className : $namespace . '\\' . $className; + $np_ar = [$np, null]; // use CommonPlugins\Plugins; - if(!static::itemInArray($this->useBlockAr,$np_ar)){ + if (!static::itemInArray($this->useBlockAr, $np_ar)) { $this->useBlockAr[] = $np_ar; } - // $this->extendTraitName::$thisFuncName as $this->extendTraitName_$thisFuncName; - $this->trailUseAsArray[] = $thisFuncName; - $extendMethodName = $this->extendTraitName.'_'.$thisFuncName; + // $this->extendTraitName::$originMethodName as $this->extendTraitName_$originMethodName; + $this->trailUseAsArray[] = $originMethodName; + $extendMethodName = $this->extendTraitName . '_' . $originMethodName; $funcVar = new Node\Arg(new Node\Scalar\MagicConst\Method()); // public function funcName(){} - $thisMethod = $this->factory->method($thisFuncName); + $thisMethod = $this->factory->method($originMethodName); if ($node->flags & Node\Stmt\Class_::MODIFIER_PUBLIC) { $thisMethod->makePublic(); @@ -323,7 +311,7 @@ public function handleTraitLeaveMethodNode(&$node,&$info) $thisMethod->makeAbstract(); } - if($node->flags & Node\Stmt\Class_::MODIFIER_FINAL){ + if ($node->flags & Node\Stmt\Class_::MODIFIER_FINAL) { $thisMethod->makeFinal(); } @@ -334,51 +322,55 @@ public function handleTraitLeaveMethodNode(&$node,&$info) if ($node->flags & Node\Stmt\Class_::MODIFIER_STATIC) { $thisMethod->makeStatic(); $selfVar = new Node\Arg(new Node\Expr\ConstFetch(new Node\Name('null'))); - }else{ + } else { $selfVar = new Node\Arg(new Node\Expr\Variable('this')); } - $pluginArgs = array_merge([$funcVar,$selfVar],GenOriginClassFileHelper::convertParamsName2Arg($node->params)); + $methodParams = array_merge([$funcVar, $selfVar], GenProxyClassTemplateHelper::convertParamsName2Arg($node->params)); $thisMethod->addParams($node->params); - if($node->returnType){ + if ($node->returnType) { $thisMethod->setReturnType($node->returnType); } - $varName = $className.'_'.$thisFuncName.'_var'; - $retName = $className.'_'.$thisFuncName.'_ret'; + $varName = $className . '_' . $originMethodName . '_var'; + $retName = $className . '_' . $originMethodName . '_ret'; /// $var = new CommonPlugins(__FUNCTION__,self,$p); - $newPluginsStm = new Node\Stmt\Expression(new Node\Expr\Assign(new Node\Expr\Variable($varName), - $this->factory->new($className, $pluginArgs))); + $newPluginsStm = new Node\Stmt\Expression(new Node\Expr\Assign( + new Node\Expr\Variable($varName), + $this->factory->new($className, $methodParams) + )); $thisMethod->addStmt($newPluginsStm); // $var = null; - $newVar = new Node\Stmt\Expression(new Node\Expr\Assign(new Node\Expr\Variable($retName), - new Node\Expr\ConstFetch(new Node\Name('null')))); + $newVar = new Node\Stmt\Expression(new Node\Expr\Assign( + new Node\Expr\Variable($retName), + new Node\Expr\ConstFetch(new Node\Name('null')) + )); $thisMethod->addStmt($newVar); $tryBlock = []; $catchNode = []; - if ($mode & PluginParser::BEFORE) - { - // $var->onBefore(); - $tryBlock[] = new Node\Stmt\Expression( - $this->factory->methodCall(new Node\Expr\Variable($varName), "onBefore")); - } + // $plugin->onBefore(); + $tryBlock[] = new Node\Stmt\Expression( + $this->factory->methodCall(new Node\Expr\Variable($varName), "onBefore") + ); if ($this->hasRet) { - /// $ret = $this->Proxied_xxx(&...$args); + /// $ret = $this->method(&...$args); $tryBlock[] = new Node\Stmt\Expression(new Node\Expr\Assign( new Node\Expr\Variable($retName), - new Node\Expr\MethodCall(new Node\Expr\Variable("this"), + new Node\Expr\MethodCall( + new Node\Expr\Variable("this"), new Node\Identifier($extendMethodName), - GenOriginClassFileHelper::convertParamsName2Arg($node->params)))); + GenProxyClassTemplateHelper::convertParamsName2Arg($node->params) + ) + )); /// $var->onEnd($ret); - if($mode & PluginParser::END) - { + if ($mode & PluginParser::END) { $tryBlock[] = new Node\Stmt\Expression( $this->factory->methodCall( new Node\Expr\Variable($varName), @@ -390,16 +382,16 @@ public function handleTraitLeaveMethodNode(&$node,&$info) /// return $var; $tryBlock[] = new Node\Stmt\Return_(new Node\Expr\Variable($retName)); - } else { - /// $this->>$thisFuncName(); - $tryBlock[] = new Node\Stmt\Expression( new Node\Expr\MethodCall(new Node\Expr\Variable("this"), - new Node\Identifier($extendMethodName), - GenOriginClassFileHelper::convertParamsName2Arg($node->params))); + /// $this->>$originMethodName(); + $tryBlock[] = new Node\Stmt\Expression(new Node\Expr\MethodCall( + new Node\Expr\Variable("this"), + new Node\Identifier($extendMethodName), + GenProxyClassTemplateHelper::convertParamsName2Arg($node->params) + )); /// $var->onEnd($ret); - if($mode & PluginParser::END) - { + if ($mode & PluginParser::END) { $tryBlock[] = new Node\Stmt\Expression( $this->factory->methodCall( new Node\Expr\Variable($varName), @@ -411,58 +403,64 @@ public function handleTraitLeaveMethodNode(&$node,&$info) } $expArgs = []; - $expArgs[] = new Node\Arg(new Node\Expr\Variable('e')) ; + $expArgs[] = new Node\Arg(new Node\Expr\Variable('e')); if ($mode & PluginParser::EXCEPTION) { $catchBlock[] = new Node\Stmt\Expression( - $this->factory->methodCall(new Node\Expr\Variable($varName), - "onException",$expArgs)); - + $this->factory->methodCall( + new Node\Expr\Variable($varName), + "onException", + $expArgs + ) + ); } $catchBlock[] = new Node\Stmt\Throw_(new Node\Expr\Variable("e")); - $catchNode[] = new Node\Stmt\Catch_([new Node\Name('\Exception')], + $catchNode[] = new Node\Stmt\Catch_( + [new Node\Name('\Exception')], new Node\Expr\Variable('e'), - $catchBlock); + $catchBlock + ); - $tryCatchFinallyNode = new Node\Stmt\TryCatch($tryBlock,$catchNode); + $tryCatchFinallyNode = new Node\Stmt\TryCatch($tryBlock, $catchNode); $thisMethod->addStmt($tryCatchFinallyNode); $this->mTraitNode->addStmt($thisMethod); - } - public function handleLeaveMethodNode(&$node) + public function handleLeaveMethodNode($node) { - $func = trim( $node->name->toString()); - if(array_key_exists($func,$this->mAopFunInfoAr)) - { - call_user_func_array([$this,$this->handleMethodNodeLeaveFunc],[&$node,&$this->mAopFunInfoAr[$func]]); - unset( $this->mAopFunInfoAr[$func] ); + $methodName = trim($node->name->toString()); + if (array_key_exists($methodName, $this->methodJoinPoints)) { + call_user_func_array( + $this->handleLeaveMethodCb, + [ + $node, + $this->methodJoinPoints[$methodName] + ] + ); } } - public function handleAfterTraversClass(&$nodes,&$mFuncAr) + public function handleAfterTraverseClass() { $useNodes = []; $this->fileName = $this->className; $this->useBlockArToNodes($useNodes); - if( !empty($this->namespace)) - { + if (!empty($this->namespace)) { $this->fileNode = $this->factory->namespace($this->namespace); - if(count($useNodes) > 0){ + if (count($useNodes) > 0) { $this->fileNode->addStmts($useNodes); } $this->fileNode->addStmt($this->mClassNode); return array($this->fileNode->getNode()); - }else{ - $this->fileNode = [] ;//$this->factory->namespace($this->namespace); - foreach ($useNodes as $node) - { + } else { + $this->fileNode = []; //$this->factory->namespace($this->namespace); + foreach ($useNodes as $node) { $this->fileNode[] = $node->getNode(); } $this->fileNode[] = $this->mClassNode->getNode(); @@ -473,11 +471,11 @@ public function handleAfterTraversClass(&$nodes,&$mFuncAr) private function useBlockArToNodes(&$stmNode) { - foreach ($this->useBlockAr as $var){ + foreach ($this->useBlockAr as $var) { - if(isset($var[1])){ // the second must be alias : use class as foo + if (isset($var[1])) { // the second must be alias : use class as foo $node = $this->factory->use($var[0])->as($var[1]); - }else {//== 1 + } else { //== 1 $node = $this->factory->use($var[0]); } @@ -485,18 +483,17 @@ private function useBlockArToNodes(&$stmNode) } } - public function handleAfterTraversTrait(&$nodes,&$mFuncAr) + public function handleAfterTraverseTrait() { $useNodes = []; $this->useBlockArToNodes($useNodes); // use Proxied_Foo{} - $useTraitNode =$this->factory->useTrait($this->extendTraitName); + $useTraitNode = $this->factory->useTrait($this->extendTraitName); - foreach ($this->trailUseAsArray as $alias) - { - // $extendMethodName::thisfuncName as $this->extendTraitName.'_'.$thisFuncName; - $useTraitNode->with($this->factory->traitUseAdaptation($this->extendTraitName,$alias)->as($this->extendTraitName.'_'.$alias)); + foreach ($this->trailUseAsArray as $alias) { + // $extendMethodName::thisfuncName as $this->extendTraitName.'_'.$originMethodName; + $useTraitNode->with($this->factory->traitUseAdaptation($this->extendTraitName, $alias)->as($this->extendTraitName . '_' . $alias)); } $this->mTraitNode->addStmt($useTraitNode); @@ -510,24 +507,40 @@ public function handleAfterTraversTrait(&$nodes,&$mFuncAr) return array($this->fileNode->getNode()); } - public function handleAfterTravers(&$nodes) + public function handleAfterTraverse($nodes) { - return call_user_func_array([$this,$this->handleEndTraversFunc],[&$nodes,&$this->mAopFunInfoAr]); + $this->newAstNode = call_user_func_array($this->handleEndTraverseCb, []); } - function handleLeaveNamespace(&$nodes) + function handleLeaveNamespace($nodes) { // do nothing } - function handlerUseNode(&$node) + function handleEnterClassConstFetch($node) + { + } + function handleEnterNew($node) + { + } + function handleEnterFuncCall($node) + { + } + + function handlerUseNode($node) { assert($node instanceof Node\Stmt\Use_); - foreach ($node->uses as $uses) - { -// $this->useBlockAr[$uses->name->toString()] = $uses->alias ? $uses->alias->name : null; - $this->useBlockAr[] = array($uses->name->toString(),$uses->alias ? $uses->alias->name : null); + foreach ($node->uses as $uses) { + $this->useBlockAr[] = array($uses->name->toString(), $uses->alias ? $uses->alias->name : null); } + } + + + function handleMagicConstNode($node) + { + } + + function handleLeaveClassNode($node){ } } diff --git a/lib/Pinpoint/Common/JoinClass.php b/lib/Pinpoint/Common/JoinClass.php new file mode 100644 index 0000000..052c732 --- /dev/null +++ b/lib/Pinpoint/Common/JoinClass.php @@ -0,0 +1,58 @@ +name = $_name; + } + + public function getMethodJoinPoints() + { + return $this->methodJoinPoints; + } + + public function addJoinPoint(string $method, string $monitor) + { + if (method_exists($this->name, $method) == false) { + throw new \Exception("no '$method' in '$this->name'"); + } + + $this->methodJoinPoints[$method] = $monitor; + } + + public function addClassNameAlias(string $olderName, string $newName) + { + $this->classAlias[$olderName] = $newName; + } + + public function addFunctionAlias(string $olderName, string $newName) + { + $this->funcAlias[$olderName] = $newName; + } +} diff --git a/lib/Pinpoint/Common/Monitor.php b/lib/Pinpoint/Common/Monitor.php new file mode 100644 index 0000000..2e59b51 --- /dev/null +++ b/lib/Pinpoint/Common/Monitor.php @@ -0,0 +1,39 @@ +monitor_name = $name; + $this->who = $who; + $this->args = &$args; + } + + abstract function onBefore(); + + abstract function onEnd(&$ret); + + abstract function onException($e); +} diff --git a/lib/Pinpoint/Common/NpCoderVisitor.php b/lib/Pinpoint/Common/NpCoderVisitor.php deleted file mode 100644 index 4e989f6..0000000 --- a/lib/Pinpoint/Common/NpCoderVisitor.php +++ /dev/null @@ -1,124 +0,0 @@ -proxiedClassFile = $proxiedClassFile; - } - - public function enterNode(Node $node) - { - if($node instanceof Node\Stmt\Namespace_) - { - $this->curNamespace = $node->name->toString(); - /// set namespace - $this->proxiedClassFile->handleEnterNamespaceNode($node); - }elseif ($node instanceof Node\Stmt\UseUse){ - $this->proxiedClassFile->handlerUseUseNode($node); - } - elseif ($node instanceof Node\Stmt\Use_){ - $this->proxiedClassFile->handlerUseNode($node); - } - elseif ($node instanceof Node\Stmt\Class_){ - if(empty($node->name->toString())){ - return $node; - // throw new \Exception("can't AOP an anonymous class"); - } - $this->curName = empty($this->curNamespace) ? ($node->name->toString()):($this->curNamespace.'\\'.$node->name->toString()); - $this->proxiedClassFile->handleEnterClassNode($node); - } - elseif( $node instanceof Node\Stmt\Trait_){ - if(empty($node->name->toString())){ - return $node; - //throw new \Exception("can't AOP an anonymous trait"); - } - $this->curName = empty($this->curNamespace) ? ($node->name->toString()):($this->curNamespace.'\\'.$node->name->toString()); - - $this->proxiedClassFile->handleEnterTraitNode($node); - }elseif ($node instanceof Node\Stmt\ClassMethod) - { - $this->proxiedClassFile->handleClassEnterMethodNode($node); - } - elseif ($node instanceof Node\Expr\ClassConstFetch){ - return $this->proxiedClassFile->handleEnterClassConstFetch($node); - } - elseif ($node instanceof Node\Name\FullyQualified) { - return $this->proxiedClassFile->handleFullyQualifiedNode($node); - }elseif ($node instanceof Node\Expr\New_) { - return $this->proxiedClassFile->handleEnterNew_($node); - }elseif ($node instanceof Node\Expr\FuncCall){ - return $this->proxiedClassFile->handleEnterFuncCall($node); - } - - return $node; - } - - - public function leaveNode(Node $node) - { - if ($node instanceof Node\Stmt\ClassMethod){ - $this->proxiedClassFile->handleLeaveMethodNode($node); - }elseif ($node instanceof Node\Name\FullyQualified){ - } - elseif ($node instanceof Node\Scalar\MagicConst){ - return $this->proxiedClassFile->handleMagicConstNode($node); - }elseif ($node instanceof Node\Stmt\Namespace_){ - return $this->proxiedClassFile->handleLeaveNamespace($node); - } - elseif ($node instanceof Node\Stmt\Class_) { - $this->proxiedClassFile->handleLeaveClassNode($node); - }elseif ($node instanceof Node\Stmt\Trait_){ - - $this->proxiedClassFile->handleLeaveTraitNode($node); - } - elseif ($node instanceof Node\Stmt\UseUse){ - - return $node; - } - } - - public function afterTraverse(array $nodes) - { - $node = $this->proxiedClassFile->handleAfterTravers($nodes); - - $this->proxiedClassFile->fileNodeDoneCB($node,$this->proxiedClassFile->myLoaderName); - - } - -} diff --git a/lib/Pinpoint/Common/OriginFileVisitor.php b/lib/Pinpoint/Common/OriginFileVisitor.php index b63922c..0aa6f47 100644 --- a/lib/Pinpoint/Common/OriginFileVisitor.php +++ b/lib/Pinpoint/Common/OriginFileVisitor.php @@ -1,4 +1,6 @@ -phpFileParser = (new ParserFactory())->create(ParserFactory::ONLY_PHP7); } - public function runAllVisitor(string $fullPath,array $aopFuncInfo=[], array $naming=[]) + public function runAllVisitor(string $fullPath, JoinClass $joinClass) { - if(!file_exists($fullPath)) - { - throw new \Exception("$fullPath not found"); - } - - $this->traverser->addVisitor($this->getVisitor($fullPath,$aopFuncInfo,$naming)); + $this->traverser->addVisitor($this->getVisitor($joinClass)); $code = file_get_contents($fullPath); $stmts = $this->phpFileParser->parse($code); $this->traverser->traverse($stmts); } - private function getVisitor(string& $fullPath,array& $aopFuncInfo=[], array& $naming=[]) + private function getVisitor(JoinClass $joinClass) { - if(empty($aopFuncInfo)){ - $proxyClassFile = new GenProxiedClassFileHelper($fullPath,"",$naming); - $codeVisitor = new NpCoderVisitor($proxyClassFile); - }else{ - $proxyClassFile = new GenProxiedClassFileHelper($fullPath,CLASS_PREFIX,$naming,$aopFuncInfo); - $originClassFile = new GenOriginClassFileHelper($aopFuncInfo,CLASS_PREFIX); - $codeVisitor = new CodeVisitor($originClassFile ,$proxyClassFile); + $classPrefix = ""; + $visitors = []; + if (!empty($joinClass->getMethodJoinPoints())) { + $classPrefix = CLASS_PREFIX; + $visitors[] = new GenProxyClassTemplateHelper($joinClass, $classPrefix); } + + $visitors[] = new GenOriginClassTemplateHelper($joinClass, $classPrefix); + $codeVisitor = new CodeVisitor($visitors); return $codeVisitor; } - } diff --git a/lib/Pinpoint/Common/PerRequest.php b/lib/Pinpoint/Common/PerRequest.php new file mode 100644 index 0000000..93ed95c --- /dev/null +++ b/lib/Pinpoint/Common/PerRequest.php @@ -0,0 +1,34 @@ +reqInst = new $userPerRequestClass(); + assertInstanceOf('I_PerRequest', $this->reqInst); + } else { + $this->reqInst = new PerRequestDefault(); + } } - private static function getAutoGenFiles() + public function getRequestInst() { - $files = []; - - foreach (static::$autoGenDirs as $dir) - { - if(is_dir($dir)) - { - Utils::scanDir($dir,"/Plugin.php$/",$files); - } - } - - return $files; + return $this->reqInst; } public function start() { + $joinedClass = $this->reqInst->joinedClass(); + if (empty($joinedClass)) { + return; + } RenderAopClass::getInstance(); /// checking the cached file exist, if exist load it - if(Utils::checkCacheReady()) - { + if (Utils::checkCacheReady()) { RenderAopClass::getInstance()->createFrom(Utils::loadCachedClass()); RenderAopClassLoader::start(); - return ; + return; } - VendorAdaptorClassLoader::enable(); - $pluFiles = static::getAutoGenFiles(); - foreach ($pluFiles as $file) - { - new PluginParser($file,$this->clAr); - } - /// there hidden a duplicated visit, class locates in @hook and appendFiles. - /// while, it's safe to visit a class/file in appendfiles and @hook order - $naming = []; - if(file_exists($this->settingIni)) - { - $nConf = new NamingConf($this->settingIni); - $naming = $nConf->getConf(); - - if(isset($naming['appendFiles'])) - { - foreach ($naming['appendFiles'] as $class) - { - $fullPath = Utils::findFile($class); - if(!$fullPath) - continue; - $visitor = new OriginFileVisitor(); - $visitor->runAllVisitor($fullPath,[],$naming); - } - } - } - - - foreach ($this->clAr as $class => $aopFuncInfo) - { - if(empty($class)) + foreach ($joinedClass as $fullClassName => $junction) { + if (empty($fullClassName)) continue; - $fullPath = Utils::findFile($class); - if(!$fullPath ) - continue; - $visitor = new OriginFileVisitor(); - if(isset($naming['ignoreFiles']) && in_array($class,$naming['ignoreFiles'])){ - $visitor->runAllVisitor($fullPath,$aopFuncInfo); - }else{ - $visitor->runAllVisitor($fullPath,$aopFuncInfo,$naming); - } + $fullPath = Utils::findFile($fullClassName); + // Please DO NOT CHEAT ME + assertFileExists($fullPath, "'$fullPath' must exist"); + assertInstanceOf("\Pinpoint\Common\Pinpoint\JoinClass", $junction); + + $visitor = new OriginFileVisitor(); + $visitor->runAllVisitor($fullPath, $junction); } // save render aop class into index file - Utils::saveCachedClass(RenderAopClass::getInstance()->getLoadeMap()); + Utils::saveCachedClass(RenderAopClass::getInstance()->getJointClassMap()); // enable RenderAop class loader RenderAopClassLoader::start(); } @@ -125,7 +96,8 @@ public function start() * @param callable $start * @param callable $tail */ - public function addClassFinderHelper(callable $start, callable $tail){ - Utils::addLoaderPatch($start,$tail); + public function addClassFinderHelper(callable $start, callable $tail) + { + Utils::addLoaderPatch($start, $tail); } } diff --git a/lib/Pinpoint/Common/PluginParser.php b/lib/Pinpoint/Common/PluginParser.php index 6966c99..842baf8 100644 --- a/lib/Pinpoint/Common/PluginParser.php +++ b/lib/Pinpoint/Common/PluginParser.php @@ -1,4 +1,6 @@ -className = $className; } - public function __construct($classFile,&$clArray) + public function __construct($classFile, &$clArray) { assert(file_exists($classFile)); $this->pluginsFile = $classFile; @@ -91,7 +93,7 @@ public function __construct($classFile,&$clArray) public function run() { - // todo , need add php5? php7 include php5 ? + // note: not support php5 $parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7); $nodes = $parser->parse(file_get_contents($this->pluginsFile)); @@ -104,25 +106,21 @@ public function run() public function insertFunc($funcName, $mode) { - $split = stripos ($funcName,'::'); - $clsFullName = substr($funcName,0,$split); - $methodName = substr($funcName,$split+2); + $split = stripos($funcName, '::'); + $clsFullName = substr($funcName, 0, $split); + $methodName = substr($funcName, $split + 2); /// not Internal func - if(!array_key_exists($clsFullName,$this->clArray)) - { + if (!array_key_exists($clsFullName, $this->clArray)) { // Cl = APP\Foo // func = open - $this->clArray[$clsFullName] = array( $methodName => - array($mode,$this->namespace,$this->className)); - }elseif (!array_key_exists($methodName,$this->clArray[$clsFullName])) - { - $this->clArray[$clsFullName][$methodName]= array($mode,$this->namespace,$this->className); - } - else { + $this->clArray[$clsFullName] = array($methodName => + array($mode, $this->namespace, $this->className)); + } elseif (!array_key_exists($methodName, $this->clArray[$clsFullName])) { + $this->clArray[$clsFullName][$methodName] = array($mode, $this->namespace, $this->className); + } else { // when user tears the plugins, that only works on $mode $this->clArray[$clsFullName][$methodName][0] |= $mode; } } - } diff --git a/lib/Pinpoint/Common/RenderAopClass.php b/lib/Pinpoint/Common/RenderAopClass.php index 2f27a8b..40fb757 100644 --- a/lib/Pinpoint/Common/RenderAopClass.php +++ b/lib/Pinpoint/Common/RenderAopClass.php @@ -1,4 +1,6 @@ -classLoaderMap = $clsMap; } - public function findFile($classFullName):string + public function findFile($classFullName): string { - if(is_callable($this->clsLoadUserFilterCB)){ - if( call_user_func($this->clsLoadUserFilterCB,$classFullName) == true ){ + if (is_callable($this->clsLoadUserFilterCB)) { + if (call_user_func($this->clsLoadUserFilterCB, $classFullName) == true) { return ''; } } - if(isset($this->classLoaderMap[$classFullName])) - { + if (isset($this->classLoaderMap[$classFullName])) { return $this->classLoaderMap[$classFullName]; } return ''; } - public function insertMapping($cl,$file) + public function insertMapping($cl, $file) { $this->classLoaderMap[$cl] = $file; } - public function getLoadeMap():array + public function getJointClassMap(): array { return $this->classLoaderMap; } - public function setUserFilter(callable $filter){ + public function setUserFilter(callable $filter) + { $this->clsLoadUserFilterCB = $filter; } -} \ No newline at end of file +} diff --git a/lib/Pinpoint/Common/Utils.php b/lib/Pinpoint/Common/Utils.php index 4201e19..c6ef9cf 100644 --- a/lib/Pinpoint/Common/Utils.php +++ b/lib/Pinpoint/Common/Utils.php @@ -1,4 +1,6 @@ -findFile($class); - if($address){ + if (is_array($loader) && $loader[0] instanceof VendorAdaptorClassLoader) { + $address = $loader[0]->findFile($className); + if ($address) { return realpath($address); } } // keep peace with unknown loader -// else{ -// throw new \Exception("unknown loader"); -// } } - if(is_callable(static::$loaderPatch[1])){ - $files = call_user_func(static::$loaderPatch[1],$class); - if ($files){ + if (is_callable(static::$endClassLoaderCb)) { + $files = call_user_func(static::$endClassLoaderCb, $className); + if ($files) { return $files; } } - + return ''; } public static function parseUserFunc($str) { - preg_match_all('#(?<=@hook:).*#', $str,$matched); + preg_match_all('#(?<=@hook:).*#', $str, $matched); - if($matched){ + if ($matched) { $func = []; - foreach ($matched[0] as $str){ - $func =array_merge($func , preg_split("# |\|#",$str,-1,PREG_SPLIT_NO_EMPTY)); + foreach ($matched[0] as $str) { + $func = array_merge($func, preg_split("# |\|#", $str, -1, PREG_SPLIT_NO_EMPTY)); } return $func; } @@ -100,36 +101,36 @@ public static function saveObj(&$context, $fullPath) } - public static function scanDir($dir,$pattern,&$tree) + public static function scanDir($dir, $pattern, &$tree) { - foreach (glob($dir.'/*') as $loc) - { - if(is_dir($loc)){ - static::scanDir($loc,$pattern,$tree); - }elseif (preg_match($pattern,$loc)){ - $tree[]=realpath($loc); + foreach (glob($dir . '/*') as $loc) { + if (is_dir($loc)) { + static::scanDir($loc, $pattern, $tree); + } elseif (preg_match($pattern, $loc)) { + $tree[] = realpath($loc); } } } - public static function checkCacheReady():bool { + public static function checkCacheReady(): bool + { return (defined('PINPOINT_USE_CACHE') && - stristr(PINPOINT_USE_CACHE,"YES") !== false ) && - file_exists(static::U_INDEX_FILE_PATH); + stristr(PINPOINT_USE_CACHE, "YES") !== false) && + file_exists(static::U_INDEX_FILE_PATH); } - public static function loadCachedClass():array { - if(file_exists(static::U_INDEX_FILE_PATH)){ + public static function loadCachedClass(): array + { + if (file_exists(static::U_INDEX_FILE_PATH)) { return unserialize(file_get_contents(static::U_INDEX_FILE_PATH)); - }else{ + } else { return null; } } - public static function saveCachedClass(array $class){ + public static function saveCachedClass(array $class) + { $context = serialize($class); - static::saveObj($context,static::U_INDEX_FILE_PATH); + static::saveObj($context, static::U_INDEX_FILE_PATH); } - - -} \ No newline at end of file +} diff --git a/lib/Pinpoint/Plugins/PerRequestPlugins.php b/lib/Pinpoint/Plugins/PerRequestPlugins.php index 945c874..10fb442 100644 --- a/lib/Pinpoint/Plugins/PerRequestPlugins.php +++ b/lib/Pinpoint/Plugins/PerRequestPlugins.php @@ -1,4 +1,5 @@ isLimit; } - public static function instance() - { - if (static::$_instance == null) { - static::$_instance = new static(); - } - return static::$_instance; - } - protected function __construct() { - if(defined('PP_REPORT_MEMORY_USAGE') && PP_REPORT_MEMORY_USAGE === '1') { + if (defined('PP_REPORT_MEMORY_USAGE') && PP_REPORT_MEMORY_USAGE === '1') { $this->mem_start = memory_get_usage(); } pinpoint_start_trace(); pinpoint_add_clue(PP_SERVER_TYPE, PP_PHP); // Handle web request and CLI request - pinpoint_add_clue(PP_INTERCEPTOR_NAME, "PHP Request: ". php_sapi_name()); + pinpoint_add_clue(PP_INTERCEPTOR_NAME, "PHP Request: " . php_sapi_name()); - if(isset($_SERVER['REQUEST_URI'])) { + if (isset($_SERVER['REQUEST_URI'])) { pinpoint_add_clue(PP_REQ_URI, $_SERVER['REQUEST_URI']); - } elseif(isset($_SERVER['argv'])) { + } elseif (isset($_SERVER['argv'])) { pinpoint_add_clue(PP_REQ_URI, implode(" ", $_SERVER['argv'])); } - if(isset($_SERVER['REMOTE_ADDR'])) { + if (isset($_SERVER['REMOTE_ADDR'])) { pinpoint_add_clue(PP_REQ_CLIENT, $_SERVER["REMOTE_ADDR"]); } - if(isset($_SERVER['HTTP_HOST'])) { + if (isset($_SERVER['HTTP_HOST'])) { pinpoint_add_clue(PP_REQ_SERVER, $_SERVER["HTTP_HOST"]); - } elseif(($hostname = gethostname()) !== false) { - if(($pid = getmypid()) !== false) { + } elseif (($hostname = gethostname()) !== false) { + if (($pid = getmypid()) !== false) { $hostname .= sprintf("[pid:%d]", $pid); } pinpoint_add_clue(PP_REQ_SERVER, $hostname); @@ -141,7 +133,7 @@ public function __destruct() { // reset limit $this->isLimit = false; - if(defined('PP_REPORT_MEMORY_USAGE') && PP_REPORT_MEMORY_USAGE === '1') { + if (defined('PP_REPORT_MEMORY_USAGE') && PP_REPORT_MEMORY_USAGE === '1') { $memory_usage = (memory_get_peak_usage() - $this->mem_start) / 1024; pinpoint_add_clues(PP_MEMORY_USAGE, "$memory_usage KB"); } @@ -149,9 +141,10 @@ public function __destruct() //https://github.com/pinpoint-apm/pinpoint-c-agent/commit/851d4ea275c5220a61fdd699e9ca9a7e31321264 if (is_int($http_response_code = http_response_code())) { pinpoint_add_clues(PP_HTTP_STATUS_CODE, $http_response_code); - if (strpos($http_response_code, '5') === 0 - && function_exists('pinpoint_mark_as_error')) - { + if ( + strpos($http_response_code, '5') === 0 + && function_exists('pinpoint_mark_as_error') + ) { pinpoint_mark_as_error('Internal server error', __FILE__); } } diff --git a/lib/Pinpoint/Plugins/Sys/PDO/ProfilerPDOStatement.php b/lib/Pinpoint/Plugins/Sys/PDO/ProfilerPDOStatement.php index 38b2d20..732bea1 100644 --- a/lib/Pinpoint/Plugins/Sys/PDO/ProfilerPDOStatement.php +++ b/lib/Pinpoint/Plugins/Sys/PDO/ProfilerPDOStatement.php @@ -18,7 +18,6 @@ namespace Pinpoint\Plugins\Sys\PDO; -use function GuzzleHttp\Psr7\normalize_header; use PDO; class ProfilerPDOStatement extends \PDOStatement diff --git a/lib/Pinpoint/test/Bear.php b/lib/Pinpoint/test/Bear.php new file mode 100644 index 0000000..a49e64a --- /dev/null +++ b/lib/Pinpoint/test/Bear.php @@ -0,0 +1,14 @@ +onBefore(); + $_pinpoint_output_ret = parent::output($_1, $_2, $_3); + $_pinpoint_output_var->onEnd($_pinpoint_output_ret); + return $_pinpoint_output_ret; + } catch (\Exception $e) { + $_pinpoint_output_var->onException($e); + throw $e; + } + } + public function noreturn(string $_1, int $_2, array &$_3, $a, $b, $c) + { + $_pinpoint_noreturn_var = new \Pinpoint\test\OutputMonitor(__METHOD__, $this, $_1, $_2, $_3, $a, $b, $c); + $_pinpoint_noreturn_ret = null; + try { + $_pinpoint_noreturn_var->onBefore(); + parent::noreturn($_1, $_2, $_3, $a, $b, $c); + $_pinpoint_noreturn_var->onEnd($_pinpoint_noreturn_ret); + } catch (\Exception $e) { + $_pinpoint_noreturn_var->onException($e); + throw $e; + } + } +} \ No newline at end of file diff --git a/lib/Pinpoint/test/Cache/Pinpoint/test/Foo.php b/lib/Pinpoint/test/Cache/Pinpoint/test/Foo.php deleted file mode 100644 index f9804f4..0000000 --- a/lib/Pinpoint/test/Cache/Pinpoint/test/Foo.php +++ /dev/null @@ -1,46 +0,0 @@ -query('SELECT name, color, calories FROM fruit ORDER BY name'); - } - protected function fooTestACPrivate() - { - echo "I'm a private function"; - return "OK"; - } - public function fooTestCompatible(class1 $a, class2 $b, FooClass $c, FooClass4 $d) - { - return null; - } - public function returnNothing() : void - { - return; - } - public function returnNothing_1() - { - return; - } -} \ No newline at end of file diff --git a/lib/Pinpoint/test/Cache/Pinpoint/test/Proxied_TestTrait.php b/lib/Pinpoint/test/Cache/Pinpoint/test/Proxied_TestTrait.php deleted file mode 100644 index ab2b854..0000000 --- a/lib/Pinpoint/test/Cache/Pinpoint/test/Proxied_TestTrait.php +++ /dev/null @@ -1,15 +0,0 @@ -onBefore(); - parent::__construct($a, $b, $c); - $traitTestPlugin___construct_var->onEnd($traitTestPlugin___construct_ret); - } catch (\Exception $e) { - $traitTestPlugin___construct_var->onException($e); - throw $e; - } - } - public function foo($a, $b, $v, $d) : array - { - $traitTestPlugin_foo_var = new traitTestPlugin(__METHOD__, $this, $a, $b, $v, $d); - $traitTestPlugin_foo_ret = null; - try { - $traitTestPlugin_foo_var->onBefore(); - $traitTestPlugin_foo_ret = parent::foo($a, $b, $v, $d); - $traitTestPlugin_foo_var->onEnd($traitTestPlugin_foo_ret); - return $traitTestPlugin_foo_ret; - } catch (\Exception $e) { - $traitTestPlugin_foo_var->onException($e); - throw $e; - } - } - public function fooUseYield() - { - $traitTestPlugin_fooUseYield_var = new traitTestPlugin(__METHOD__, $this); - $traitTestPlugin_fooUseYield_ret = null; - try { - $traitTestPlugin_fooUseYield_var->onBefore(); - $traitTestPlugin_fooUseYield_ret = parent::fooUseYield(); - $traitTestPlugin_fooUseYield_var->onEnd($traitTestPlugin_fooUseYield_ret); - return $traitTestPlugin_fooUseYield_ret; - } catch (\Exception $e) { - throw $e; - } - } - public function fooNoReturn() - { - $traitTestPlugin_fooNoReturn_var = new traitTestPlugin(__METHOD__, $this); - $traitTestPlugin_fooNoReturn_ret = null; - try { - parent::fooNoReturn(); - } catch (\Exception $e) { - $traitTestPlugin_fooNoReturn_var->onException($e); - throw $e; - } - } - public function fooNoReturnButReturn() - { - $victim_fooNoReturnButReturn_var = new victim(__METHOD__, $this); - $victim_fooNoReturnButReturn_ret = null; - try { - $victim_fooNoReturnButReturn_ret = parent::fooNoReturnButReturn(); - return $victim_fooNoReturnButReturn_ret; - } catch (\Exception $e) { - $victim_fooNoReturnButReturn_var->onException($e); - throw $e; - } - } - public final function fooNaughtyFinal($a, $b, $c) - { - $over_fooNaughtyFinal_var = new over(__METHOD__, $this, $a, $b, $c); - $over_fooNaughtyFinal_ret = null; - try { - $over_fooNaughtyFinal_var->onBefore(); - $over_fooNaughtyFinal_ret = parent::fooNaughtyFinal($a, $b, $c); - $over_fooNaughtyFinal_var->onEnd($over_fooNaughtyFinal_ret); - return $over_fooNaughtyFinal_ret; - } catch (\Exception $e) { - $over_fooNaughtyFinal_var->onException($e); - throw $e; - } - } - protected function fooTestACPrivate() - { - $traitTestPlugin_fooTestACPrivate_var = new traitTestPlugin(__METHOD__, $this); - $traitTestPlugin_fooTestACPrivate_ret = null; - try { - $traitTestPlugin_fooTestACPrivate_ret = parent::fooTestACPrivate(); - return $traitTestPlugin_fooTestACPrivate_ret; - } catch (\Exception $e) { - $traitTestPlugin_fooTestACPrivate_var->onException($e); - throw $e; - } - } - public function fooTestCompatible(class1 $a, class2 $b, FooClass $c, FooClass4 $d) - { - $traitTestPlugin_fooTestCompatible_var = new traitTestPlugin(__METHOD__, $this, $a, $b, $c, $d); - $traitTestPlugin_fooTestCompatible_ret = null; - try { - $traitTestPlugin_fooTestCompatible_ret = parent::fooTestCompatible($a, $b, $c, $d); - return $traitTestPlugin_fooTestCompatible_ret; - } catch (\Exception $e) { - $traitTestPlugin_fooTestCompatible_var->onException($e); - throw $e; - } - } - public function returnNothing() : void - { - $traitTestPlugin_returnNothing_var = new traitTestPlugin(__METHOD__, $this); - $traitTestPlugin_returnNothing_ret = null; - try { - $traitTestPlugin_returnNothing_var->onBefore(); - parent::returnNothing(); - $traitTestPlugin_returnNothing_var->onEnd($traitTestPlugin_returnNothing_ret); - } catch (\Exception $e) { - $traitTestPlugin_returnNothing_var->onException($e); - throw $e; - } - } - public function returnNothing_1() - { - $traitTestPlugin_returnNothing_1_var = new traitTestPlugin(__METHOD__, $this); - $traitTestPlugin_returnNothing_1_ret = null; - try { - $traitTestPlugin_returnNothing_1_var->onBefore(); - parent::returnNothing_1(); - $traitTestPlugin_returnNothing_1_var->onEnd($traitTestPlugin_returnNothing_1_ret); - } catch (\Exception $e) { - $traitTestPlugin_returnNothing_1_var->onException($e); - throw $e; - } - } -} \ No newline at end of file diff --git a/lib/Pinpoint/test/Cache/Pinpoint/test/TestTrait.php b/lib/Pinpoint/test/Cache/Pinpoint/test/TestTrait.php deleted file mode 100644 index 0c93f7a..0000000 --- a/lib/Pinpoint/test/Cache/Pinpoint/test/TestTrait.php +++ /dev/null @@ -1,24 +0,0 @@ -onBefore(); - $this->Proxied_TestTrait_getReturnType(); - $traitTestPlugin_getReturnType_var->onEnd($traitTestPlugin_getReturnType_ret); - } catch (\Exception $e) { - $traitTestPlugin_getReturnType_var->onException($e); - throw $e; - } - } -} \ No newline at end of file diff --git a/lib/Pinpoint/test/ClassParseTest.php b/lib/Pinpoint/test/ClassParseTest.php index 4f89fc1..90b71bd 100644 --- a/lib/Pinpoint/test/ClassParseTest.php +++ b/lib/Pinpoint/test/ClassParseTest.php @@ -1,15 +1,17 @@ [ -// 'PDO'=>'plugins\\PDO', -// 'type03'=>'plugins\\type03', -// 'test\\curl'=>'plugins\\test\\curl', -// 'test\\type1'=>'plugins\\test\\type1', -// 'app\\curl_init_01'=>'plugins\\app\\curl_init_01' -// ], -// 'funCall'=>[ -// 'curl_init'=>'plugins\\curl_init', -// 'app\\foo\\curl_02'=>'plugins\\app\\foo\\curl_02', -// 'app\\foo\\curl_03'=>'plugins\\app\\foo\\curl_0/cersv\3' -// ], -// 'ignoreFiles'=>["pinpoint\\test\\IgnoreClass"], -// 'appendFiles'=>["pinpoint\\test\\AddClass"] -// ]; - - $nConf =new NamingConf(__DIR__.'/setting.ini'); + // template for dst conf + // $dst = [ + // 'classCall'=>[ + // 'PDO'=>'plugins\\PDO', + // 'type03'=>'plugins\\type03', + // 'test\\curl'=>'plugins\\test\\curl', + // 'test\\type1'=>'plugins\\test\\type1', + // 'app\\curl_init_01'=>'plugins\\app\\curl_init_01' + // ], + // 'funCall'=>[ + // 'curl_init'=>'plugins\\curl_init', + // 'app\\foo\\curl_02'=>'plugins\\app\\foo\\curl_02', + // 'app\\foo\\curl_03'=>'plugins\\app\\foo\\curl_0/cersv\3' + // ], + // 'ignoreFiles'=>["pinpoint\\test\\IgnoreClass"], + // 'appendFiles'=>["pinpoint\\test\\AddClass"] + // ]; + + $nConf = new NamingConf(__DIR__ . '/setting.ini'); static::$naming = $nConf->getConf(); } public function testTrait() { - $fullpath =__DIR__.'/TestTrait.php'; + $fullpath = __DIR__ . '/TestTrait.php'; $info = [ - 'getReturnType'=>[7,'pinpoint\\test','traitTestPlugin'] + 'getReturnType' => [7, 'pinpoint\\test', 'traitTestPlugin'] ]; // test empty naming $visitor = new OriginFileVisitor(); - $visitor->runAllVisitor($fullpath,$info); + $visitor->runAllVisitor($fullpath, $info); - foreach ( RenderAopClass::getInstance()->getLoadeMap() as $class => $location) - { - $exp = str_replace('Cache','Comparison',$location); + foreach (RenderAopClass::getInstance()->getJointClassMap() as $class => $location) { + $exp = str_replace('Cache', 'Comparison', $location); self::assertFileExists($exp); self::assertFileExists($location); - self::assertFileEquals($exp,$location,"$exp!=$location"); + self::assertFileEquals($exp, $location, "$exp!=$location"); } } public function testClass() { - $fullpath =__DIR__.'/TestClass.php'; + $fullpath = __DIR__ . '/TestClass.php'; $info = [ - 'foo'=>[7,'pinpoint\\test','traitTestPlugin'], - 'fooUseYield'=>[3,'pinpoint\\test','traitTestPlugin'], - 'fooNoReturn'=>[4,'pinpoint\\test','traitTestPlugin'], - 'fooNoReturnButReturn'=>[4,'pinpoint\\test\\burden\\depress\\herb\\e\\e\f\\longNp','victim'], - 'fooNaughtyFinal'=>[7,'\\','over'], - '\PDO::query'=>[7,'pinpoint\\test','traitTestPlugin'], - '\curl_exec' =>[7,'pinpoint\\test','traitTestPlugin'], - 'fooTestACPrivate' =>[4,'pinpoint\\test','traitTestPlugin'], - 'fooTestCompatible'=>[4,'pinpoint\\test','traitTestPlugin'], - 'returnNothing'=>[7,'pinpoint\\test','traitTestPlugin'], - 'returnNothing_1'=>[7,'pinpoint\\test','traitTestPlugin'], - '__construct'=>[7,'pinpoint\\test','traitTestPlugin'] + 'foo' => [7, 'pinpoint\\test', 'traitTestPlugin'], + 'fooUseYield' => [3, 'pinpoint\\test', 'traitTestPlugin'], + 'fooNoReturn' => [4, 'pinpoint\\test', 'traitTestPlugin'], + 'fooNoReturnButReturn' => [4, 'pinpoint\\test\\burden\\depress\\herb\\e\\e\f\\longNp', 'victim'], + 'fooNaughtyFinal' => [7, '\\', 'over'], + '\PDO::query' => [7, 'pinpoint\\test', 'traitTestPlugin'], + '\curl_exec' => [7, 'pinpoint\\test', 'traitTestPlugin'], + 'fooTestACPrivate' => [4, 'pinpoint\\test', 'traitTestPlugin'], + 'fooTestCompatible' => [4, 'pinpoint\\test', 'traitTestPlugin'], + 'returnNothing' => [7, 'pinpoint\\test', 'traitTestPlugin'], + 'returnNothing_1' => [7, 'pinpoint\\test', 'traitTestPlugin'], + '__construct' => [7, 'pinpoint\\test', 'traitTestPlugin'] ]; $visitor = new OriginFileVisitor(); - $visitor->runAllVisitor($fullpath,$info,static::$naming); - foreach ( RenderAopClass::getInstance()->getLoadeMap() as $class => $location) - { - $exp = str_replace('Cache','Comparison',$location); + $visitor->runAllVisitor($fullpath, $info, static::$naming); + foreach (RenderAopClass::getInstance()->getJointClassMap() as $class => $location) { + $exp = str_replace('Cache', 'Comparison', $location); self::assertFileExists($exp); self::assertFileExists($location); - self::assertFileEquals($exp,$location); + self::assertFileEquals($exp, $location); } - } public function testNamingReplace() { - $fullpath =__DIR__.'/Foo.php'; + $fullpath = __DIR__ . '/Foo.php'; $visitor = new OriginFileVisitor(); - $visitor->runAllVisitor($fullpath,[],static::$naming); - foreach ( RenderAopClass::getInstance()->getLoadeMap() as $class => $location) - { - $exp = str_replace('Cache','Comparison',$location); + $visitor->runAllVisitor($fullpath, [], static::$naming); + foreach (RenderAopClass::getInstance()->getJointClassMap() as $class => $location) { + $exp = str_replace('Cache', 'Comparison', $location); self::assertFileExists($location); self::assertFileExists($exp); - self::assertFileEquals($exp,$location); + self::assertFileEquals($exp, $location); } } public function testIgnoreList() { -// $fullpath =__DIR__.'/Foo.php'; -// $osr = new OrgClassParse($fullpath,null,static::$naming); -// foreach ($osr->classIndex as $class => $location) -// { -// $exp = str_replace('Cache','Comparison',$location); -// self::assertFileEquals($exp,$location); -// } + // $fullpath =__DIR__.'/Foo.php'; + // $osr = new OrgClassParse($fullpath,null,static::$naming); + // foreach ($osr->classIndex as $class => $location) + // { + // $exp = str_replace('Cache','Comparison',$location); + // self::assertFileEquals($exp,$location); + // } self::assertTrue(true); } - } diff --git a/lib/Pinpoint/test/Comparison/Pinpoint/test/Bear.php b/lib/Pinpoint/test/Comparison/Pinpoint/test/Bear.php new file mode 100644 index 0000000..194c772 --- /dev/null +++ b/lib/Pinpoint/test/Comparison/Pinpoint/test/Bear.php @@ -0,0 +1,35 @@ +onBefore(); + $_pinpoint_output_ret = parent::output($_1, $_2, $_3); + $_pinpoint_output_var->onEnd($_pinpoint_output_ret); + return $_pinpoint_output_ret; + } catch (\Exception $e) { + $_pinpoint_output_var->onException($e); + throw $e; + } + } + public function noreturn(string $_1, int $_2, array &$_3, $a, $b, $c) + { + $_pinpoint_noreturn_var = new \Pinpoint\test\OutputMonitor(__METHOD__, $this, $_1, $_2, $_3, $a, $b, $c); + $_pinpoint_noreturn_ret = null; + try { + $_pinpoint_noreturn_var->onBefore(); + parent::noreturn($_1, $_2, $_3, $a, $b, $c); + $_pinpoint_noreturn_var->onEnd($_pinpoint_noreturn_ret); + } catch (\Exception $e) { + $_pinpoint_noreturn_var->onException($e); + throw $e; + } + } +} \ No newline at end of file diff --git a/lib/Pinpoint/test/Comparison/Pinpoint/test/Foo.php b/lib/Pinpoint/test/Comparison/Pinpoint/test/Foo.php deleted file mode 100644 index f9804f4..0000000 --- a/lib/Pinpoint/test/Comparison/Pinpoint/test/Foo.php +++ /dev/null @@ -1,46 +0,0 @@ -query('SELECT name, color, calories FROM fruit ORDER BY name'); - } - protected function fooTestACPrivate() - { - echo "I'm a private function"; - return "OK"; - } - public function fooTestCompatible(class1 $a, class2 $b, FooClass $c, FooClass4 $d) - { - return null; - } - public function returnNothing() : void - { - return; - } - public function returnNothing_1() - { - return; - } -} \ No newline at end of file diff --git a/lib/Pinpoint/test/Comparison/Pinpoint/test/Proxied_TestTrait.php b/lib/Pinpoint/test/Comparison/Pinpoint/test/Proxied_TestTrait.php deleted file mode 100644 index ab2b854..0000000 --- a/lib/Pinpoint/test/Comparison/Pinpoint/test/Proxied_TestTrait.php +++ /dev/null @@ -1,15 +0,0 @@ -onBefore(); - parent::__construct($a, $b, $c); - $traitTestPlugin___construct_var->onEnd($traitTestPlugin___construct_ret); - } catch (\Exception $e) { - $traitTestPlugin___construct_var->onException($e); - throw $e; - } - } - public function foo($a, $b, $v, $d) : array - { - $traitTestPlugin_foo_var = new traitTestPlugin(__METHOD__, $this, $a, $b, $v, $d); - $traitTestPlugin_foo_ret = null; - try { - $traitTestPlugin_foo_var->onBefore(); - $traitTestPlugin_foo_ret = parent::foo($a, $b, $v, $d); - $traitTestPlugin_foo_var->onEnd($traitTestPlugin_foo_ret); - return $traitTestPlugin_foo_ret; - } catch (\Exception $e) { - $traitTestPlugin_foo_var->onException($e); - throw $e; - } - } - public function fooUseYield() - { - $traitTestPlugin_fooUseYield_var = new traitTestPlugin(__METHOD__, $this); - $traitTestPlugin_fooUseYield_ret = null; - try { - $traitTestPlugin_fooUseYield_var->onBefore(); - $traitTestPlugin_fooUseYield_ret = parent::fooUseYield(); - $traitTestPlugin_fooUseYield_var->onEnd($traitTestPlugin_fooUseYield_ret); - return $traitTestPlugin_fooUseYield_ret; - } catch (\Exception $e) { - throw $e; - } - } - public function fooNoReturn() - { - $traitTestPlugin_fooNoReturn_var = new traitTestPlugin(__METHOD__, $this); - $traitTestPlugin_fooNoReturn_ret = null; - try { - parent::fooNoReturn(); - } catch (\Exception $e) { - $traitTestPlugin_fooNoReturn_var->onException($e); - throw $e; - } - } - public function fooNoReturnButReturn() - { - $victim_fooNoReturnButReturn_var = new victim(__METHOD__, $this); - $victim_fooNoReturnButReturn_ret = null; - try { - $victim_fooNoReturnButReturn_ret = parent::fooNoReturnButReturn(); - return $victim_fooNoReturnButReturn_ret; - } catch (\Exception $e) { - $victim_fooNoReturnButReturn_var->onException($e); - throw $e; - } - } - public final function fooNaughtyFinal($a, $b, $c) - { - $over_fooNaughtyFinal_var = new over(__METHOD__, $this, $a, $b, $c); - $over_fooNaughtyFinal_ret = null; - try { - $over_fooNaughtyFinal_var->onBefore(); - $over_fooNaughtyFinal_ret = parent::fooNaughtyFinal($a, $b, $c); - $over_fooNaughtyFinal_var->onEnd($over_fooNaughtyFinal_ret); - return $over_fooNaughtyFinal_ret; - } catch (\Exception $e) { - $over_fooNaughtyFinal_var->onException($e); - throw $e; - } - } - protected function fooTestACPrivate() - { - $traitTestPlugin_fooTestACPrivate_var = new traitTestPlugin(__METHOD__, $this); - $traitTestPlugin_fooTestACPrivate_ret = null; - try { - $traitTestPlugin_fooTestACPrivate_ret = parent::fooTestACPrivate(); - return $traitTestPlugin_fooTestACPrivate_ret; - } catch (\Exception $e) { - $traitTestPlugin_fooTestACPrivate_var->onException($e); - throw $e; - } - } - public function fooTestCompatible(class1 $a, class2 $b, FooClass $c, FooClass4 $d) - { - $traitTestPlugin_fooTestCompatible_var = new traitTestPlugin(__METHOD__, $this, $a, $b, $c, $d); - $traitTestPlugin_fooTestCompatible_ret = null; - try { - $traitTestPlugin_fooTestCompatible_ret = parent::fooTestCompatible($a, $b, $c, $d); - return $traitTestPlugin_fooTestCompatible_ret; - } catch (\Exception $e) { - $traitTestPlugin_fooTestCompatible_var->onException($e); - throw $e; - } - } - public function returnNothing() : void - { - $traitTestPlugin_returnNothing_var = new traitTestPlugin(__METHOD__, $this); - $traitTestPlugin_returnNothing_ret = null; - try { - $traitTestPlugin_returnNothing_var->onBefore(); - parent::returnNothing(); - $traitTestPlugin_returnNothing_var->onEnd($traitTestPlugin_returnNothing_ret); - } catch (\Exception $e) { - $traitTestPlugin_returnNothing_var->onException($e); - throw $e; - } - } - public function returnNothing_1() - { - $traitTestPlugin_returnNothing_1_var = new traitTestPlugin(__METHOD__, $this); - $traitTestPlugin_returnNothing_1_ret = null; - try { - $traitTestPlugin_returnNothing_1_var->onBefore(); - parent::returnNothing_1(); - $traitTestPlugin_returnNothing_1_var->onEnd($traitTestPlugin_returnNothing_1_ret); - } catch (\Exception $e) { - $traitTestPlugin_returnNothing_1_var->onException($e); - throw $e; - } - } -} \ No newline at end of file diff --git a/lib/Pinpoint/test/Comparison/Pinpoint/test/TestTrait.php b/lib/Pinpoint/test/Comparison/Pinpoint/test/TestTrait.php deleted file mode 100644 index 0c93f7a..0000000 --- a/lib/Pinpoint/test/Comparison/Pinpoint/test/TestTrait.php +++ /dev/null @@ -1,24 +0,0 @@ -onBefore(); - $this->Proxied_TestTrait_getReturnType(); - $traitTestPlugin_getReturnType_var->onEnd($traitTestPlugin_getReturnType_ret); - } catch (\Exception $e) { - $traitTestPlugin_getReturnType_var->onException($e); - throw $e; - } - } -} \ No newline at end of file diff --git a/lib/Pinpoint/test/OriginFileVisitor_test.php b/lib/Pinpoint/test/OriginFileVisitor_test.php new file mode 100644 index 0000000..a41a7a2 --- /dev/null +++ b/lib/Pinpoint/test/OriginFileVisitor_test.php @@ -0,0 +1,48 @@ +assertFileExists($fullPath); + $joinClass = new JoinClass(Bear::class); + $joinClass->addJoinPoint('output', OutputMonitor::class); + $joinClass->addJoinPoint('noreturn', OutputMonitor::class); + $visitor = new OriginFileVisitor(); + $visitor->runAllVisitor($fullPath, $joinClass); + $classMap = RenderAopClass::getInstance()->getJointClassMap(); + $this->assertArrayHasKey(Bear::class,$classMap); + foreach ($classMap as $class => $file){ + // print_r(str_replace("Comparison","Cache",$file)); + $this->assertFileEquals($file,str_replace("Cache","Comparison",$file)); + } + // $this->assertFileEquals(""); + } +} + diff --git a/lib/Pinpoint/test/OutputMonitor.php b/lib/Pinpoint/test/OutputMonitor.php new file mode 100644 index 0000000..e5e30a7 --- /dev/null +++ b/lib/Pinpoint/test/OutputMonitor.php @@ -0,0 +1,21 @@ +getName(); // X +} + +// test(new X1()); + + + +class A +{ + public int $a = 10; + public int $b = 10; +} + + +$a = new A(); + +print_r($a); +$a->a = 12; +print_r($a); + +function change_a(A $a) +{ + $a->a = 13; +} + +function change_a1(A $a) +{ + $a->a = 14; +} + +change_a($a); +print_r($a); + +change_a1($a); +print_r($a); + + +$test_ar = array( + "a" => 1, + "b" => 3 +); + + +print_r(array_key_exists('b', $test_ar)); + +print(A::class); From bce51a6bbf421b7affaf810507b8923c3d05f9c3 Mon Sep 17 00:00:00 2001 From: eeliu <27064129+eeliu@users.noreply.github.com> Date: Mon, 30 Oct 2023 06:20:51 +0000 Subject: [PATCH 05/13] feat(aop): remove setting.ini - refactor aop for addJoinPoint api - tc for addFunctionAlias/addClassNameAlias https://github.com/pinpoint-apm/pinpoint-c-agent/issues/543 --- .devcontainer/devcontainer.json | 4 +- .gitignore | 3 +- .../{ClassFile.php => AbstractClassFile.php} | 4 +- .../{Monitor.php => AbstractMonitor.php} | 2 +- .../{JoinClass.php => AspectClassHandle.php} | 2 +- lib/Pinpoint/Common/CodeVisitor.php | 2 +- .../Common/GenOriginClassTemplateHelper.php | 18 +-- .../Common/GenProxyClassTemplateHelper.php | 14 +- lib/Pinpoint/Common/JoinClassInterface.php | 25 ++++ lib/Pinpoint/Common/OriginFileVisitor.php | 12 +- lib/Pinpoint/Common/PerRequest.php | 8 +- lib/Pinpoint/Common/PinpointDriver.php | 10 +- ...gins.php => PinpointPerRequestPlugins.php} | 2 +- .../Plugins/Yii2PerRequestPlugins.php | 15 +- lib/Pinpoint/test/AccessRemote.php | 38 ----- lib/Pinpoint/test/Bear.php | 59 +++++++- .../test/Cache/Pinpoint/test/Bear.php | 35 ----- .../test/Cache/Pinpoint/test/ProxyBear.php | 14 -- lib/Pinpoint/test/ClassParseTest.php | 135 ------------------ .../test/Comparison/Pinpoint/test/Bear.php | 28 ++++ .../Comparison/Pinpoint/test/ProxyBear.php | 46 ++++++ lib/Pinpoint/test/Foo.php | 51 ------- lib/Pinpoint/test/OriginFileVisitor_test.php | 28 ++-- lib/Pinpoint/test/OutputMonitor.php | 5 +- lib/Pinpoint/test/TestClass.php | 83 ----------- lib/Pinpoint/test/TestTrait.php | 19 --- lib/Pinpoint/test/UtilTest.php | 58 -------- lib/Pinpoint/test/setting.ini | 24 ---- 28 files changed, 226 insertions(+), 518 deletions(-) rename lib/Pinpoint/Common/{ClassFile.php => AbstractClassFile.php} (98%) rename lib/Pinpoint/Common/{Monitor.php => AbstractMonitor.php} (97%) rename lib/Pinpoint/Common/{JoinClass.php => AspectClassHandle.php} (98%) create mode 100644 lib/Pinpoint/Common/JoinClassInterface.php rename lib/Pinpoint/Plugins/{PerRequestPlugins.php => PinpointPerRequestPlugins.php} (99%) delete mode 100644 lib/Pinpoint/test/AccessRemote.php delete mode 100644 lib/Pinpoint/test/Cache/Pinpoint/test/Bear.php delete mode 100644 lib/Pinpoint/test/Cache/Pinpoint/test/ProxyBear.php delete mode 100644 lib/Pinpoint/test/ClassParseTest.php delete mode 100644 lib/Pinpoint/test/Foo.php delete mode 100644 lib/Pinpoint/test/TestClass.php delete mode 100644 lib/Pinpoint/test/TestTrait.php delete mode 100644 lib/Pinpoint/test/UtilTest.php delete mode 100644 lib/Pinpoint/test/setting.ini diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index f3b8c7a..faea12b 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -8,7 +8,9 @@ "streetsidesoftware.code-spell-checker", "recca0120.vscode-phpunit", "donjayamanne.githistory", - "adam-bender.commit-message-editor" + "adam-bender.commit-message-editor", + "bmewburn.vscode-intelephense-client", + "xdebug.php-debug" ] } } diff --git a/.gitignore b/.gitignore index 94434af..30bc0fb 100644 --- a/.gitignore +++ b/.gitignore @@ -2,10 +2,11 @@ composer.phar /vendor/ .idea/ composer.lock -lib/pinpoint/test/Cache +lib/pinpoint/test/Cache/ lib/pinpoint/test/test.php *.ast # Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control # You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file # composer.lock +lib/Pinpoint/test/Cache/Pinpoint/test/*.php diff --git a/lib/Pinpoint/Common/ClassFile.php b/lib/Pinpoint/Common/AbstractClassFile.php similarity index 98% rename from lib/Pinpoint/Common/ClassFile.php rename to lib/Pinpoint/Common/AbstractClassFile.php index 089125f..f3d1e1c 100644 --- a/lib/Pinpoint/Common/ClassFile.php +++ b/lib/Pinpoint/Common/AbstractClassFile.php @@ -29,7 +29,7 @@ use PhpParser\PrettyPrinter; /** - * Class ClassFile + * Class AbstractClassFile * * A abstract php-parse node * namespace node @@ -39,7 +39,7 @@ * * @package pinpoint\Common */ -abstract class ClassFile +abstract class AbstractClassFile { public $appendingFile = array(); diff --git a/lib/Pinpoint/Common/Monitor.php b/lib/Pinpoint/Common/AbstractMonitor.php similarity index 97% rename from lib/Pinpoint/Common/Monitor.php rename to lib/Pinpoint/Common/AbstractMonitor.php index 2e59b51..a3a5d7f 100644 --- a/lib/Pinpoint/Common/Monitor.php +++ b/lib/Pinpoint/Common/AbstractMonitor.php @@ -19,7 +19,7 @@ namespace Pinpoint\Common; -abstract class Monitor +abstract class AbstractMonitor { protected $monitor_name; protected $who; diff --git a/lib/Pinpoint/Common/JoinClass.php b/lib/Pinpoint/Common/AspectClassHandle.php similarity index 98% rename from lib/Pinpoint/Common/JoinClass.php rename to lib/Pinpoint/Common/AspectClassHandle.php index 052c732..513083d 100644 --- a/lib/Pinpoint/Common/JoinClass.php +++ b/lib/Pinpoint/Common/AspectClassHandle.php @@ -20,7 +20,7 @@ namespace Pinpoint\Common; -class JoinClass +class AspectClassHandle { public string $name; public $methodJoinPoints = array(); diff --git a/lib/Pinpoint/Common/CodeVisitor.php b/lib/Pinpoint/Common/CodeVisitor.php index ea84622..cc7a258 100644 --- a/lib/Pinpoint/Common/CodeVisitor.php +++ b/lib/Pinpoint/Common/CodeVisitor.php @@ -44,7 +44,7 @@ public function enterNode(Node $node) { if ($node instanceof Node\Stmt\Namespace_) { foreach ($this->visitors as $visitor) { - assert($visitor instanceof ClassFile); + assert($visitor instanceof AbstractClassFile); $visitor->handleEnterNamespaceNode($node); } } elseif ($node instanceof Node\Stmt\Use_) { diff --git a/lib/Pinpoint/Common/GenOriginClassTemplateHelper.php b/lib/Pinpoint/Common/GenOriginClassTemplateHelper.php index b360cc1..09df28a 100644 --- a/lib/Pinpoint/Common/GenOriginClassTemplateHelper.php +++ b/lib/Pinpoint/Common/GenOriginClassTemplateHelper.php @@ -26,9 +26,9 @@ namespace Pinpoint\Common; use PhpParser\Node; -use Pinpoint\Common\ClassFile; +use Pinpoint\Common\AbstractClassFile; -class GenOriginClassTemplateHelper extends ClassFile +class GenOriginClassTemplateHelper extends AbstractClassFile { protected $originClassFileDir; protected $originClassFilePath; @@ -37,18 +37,18 @@ class GenOriginClassTemplateHelper extends ClassFile protected $funcAlias = []; protected $suffix_use = []; protected $methodJoint; - // private $joinClass; - public function __construct(JoinClass $joinClass, string $namePrefix) + // private $classHandler; + public function __construct(AspectClassHandle $classHandler, string $namePrefix) { parent::__construct($namePrefix); - $path = Utils::findFile($joinClass->name); + $path = Utils::findFile($classHandler->name); $this->originClassFileDir = dirname($path); $this->originClassFilePath = $path; - // $this->joinClass = $joinClass; - $this->classAliasSet = $joinClass->classAlias; - $this->funcAlias = $joinClass->funcAlias; - $this->methodJoint = $joinClass->methodJoinPoints; + // $this->classHandler = $classHandler; + $this->classAliasSet = $classHandler->classAlias; + $this->funcAlias = $classHandler->funcAlias; + $this->methodJoint = $classHandler->methodJoinPoints; } private function getRealNp($node) diff --git a/lib/Pinpoint/Common/GenProxyClassTemplateHelper.php b/lib/Pinpoint/Common/GenProxyClassTemplateHelper.php index c5e77d2..0af1ef3 100644 --- a/lib/Pinpoint/Common/GenProxyClassTemplateHelper.php +++ b/lib/Pinpoint/Common/GenProxyClassTemplateHelper.php @@ -25,12 +25,12 @@ namespace Pinpoint\Common; -use Pinpoint\Common\ClassFile; +use Pinpoint\Common\AbstractClassFile; use PhpParser\BuilderFactory; use PhpParser\Node; use Pinpoint\Common\PluginParser; -class GenProxyClassTemplateHelper extends ClassFile +class GenProxyClassTemplateHelper extends AbstractClassFile { private $factory; @@ -47,11 +47,11 @@ class GenProxyClassTemplateHelper extends ClassFile private $handleEndTraverseCb = []; public $methodJoinPoints = []; - public function __construct(JoinClass $joinClass, $prefix) + public function __construct(AspectClassHandle $classHandler, $prefix) { parent::__construct($prefix); $this->factory = new BuilderFactory(); - $this->methodJoinPoints = $joinClass->methodJoinPoints; + $this->methodJoinPoints = $classHandler->methodJoinPoints; } @@ -168,7 +168,7 @@ public function handleClassLeaveMethodNode($node, $monitorClassFullName) /// $_pinpoint_method_var = new pinpoint\Plugins\CommonPlugins(__FUNCTION__,self,$p); $newPluginsStm = new Node\Stmt\Expression(new Node\Expr\Assign( new Node\Expr\Variable($varName), - $this->factory->new(new Node\Name\FullyQualified($monitorClassFullName) , $methodParams) + $this->factory->new(new Node\Name\FullyQualified($monitorClassFullName), $methodParams) )); $thisMethod->addStmt($newPluginsStm); @@ -540,7 +540,7 @@ function handleMagicConstNode($node) { } - function handleLeaveClassNode($node){ - + function handleLeaveClassNode($node) + { } } diff --git a/lib/Pinpoint/Common/JoinClassInterface.php b/lib/Pinpoint/Common/JoinClassInterface.php new file mode 100644 index 0000000..76f1021 --- /dev/null +++ b/lib/Pinpoint/Common/JoinClassInterface.php @@ -0,0 +1,25 @@ +phpFileParser = (new ParserFactory())->create(ParserFactory::ONLY_PHP7); } - public function runAllVisitor(string $fullPath, JoinClass $joinClass) + public function runAllVisitor(string $fullPath, AspectClassHandle $classHandler) { - $this->traverser->addVisitor($this->getVisitor($joinClass)); + $this->traverser->addVisitor($this->getVisitor($classHandler)); $code = file_get_contents($fullPath); $stmts = $this->phpFileParser->parse($code); $this->traverser->traverse($stmts); } - private function getVisitor(JoinClass $joinClass) + private function getVisitor(AspectClassHandle $classHandler) { $classPrefix = ""; $visitors = []; - if (!empty($joinClass->getMethodJoinPoints())) { + if (!empty($classHandler->getMethodJoinPoints())) { $classPrefix = CLASS_PREFIX; - $visitors[] = new GenProxyClassTemplateHelper($joinClass, $classPrefix); + $visitors[] = new GenProxyClassTemplateHelper($classHandler, $classPrefix); } - $visitors[] = new GenOriginClassTemplateHelper($joinClass, $classPrefix); + $visitors[] = new GenOriginClassTemplateHelper($classHandler, $classPrefix); $codeVisitor = new CodeVisitor($visitors); return $codeVisitor; } diff --git a/lib/Pinpoint/Common/PerRequest.php b/lib/Pinpoint/Common/PerRequest.php index 93ed95c..80d1f76 100644 --- a/lib/Pinpoint/Common/PerRequest.php +++ b/lib/Pinpoint/Common/PerRequest.php @@ -19,13 +19,7 @@ namespace Pinpoint\Common; -interface I_PerRequest -{ - public function joinedClass(): array; -} - - -class PerRequestDefault implements I_PerRequest +class PerRequestDefault implements JoinClassInterface { public function joinedClass(): array { diff --git a/lib/Pinpoint/Common/PinpointDriver.php b/lib/Pinpoint/Common/PinpointDriver.php index b6f502a..b3829b0 100644 --- a/lib/Pinpoint/Common/PinpointDriver.php +++ b/lib/Pinpoint/Common/PinpointDriver.php @@ -25,15 +25,13 @@ namespace Pinpoint\Common; -use Exception; -use Pinpoint\Plugins\PerRequestPlugins; class PinpointDriver { protected static $instance; protected $clAr = []; - private I_PerRequest $reqInst; + private JoinClassInterface $reqInst; public static function getInstance() { @@ -48,7 +46,7 @@ final private function __construct() if (defined('PP_REQ_PLUGINS') && class_exists(PP_REQ_PLUGINS)) { $userPerRequestClass = PP_REQ_PLUGINS; $this->reqInst = new $userPerRequestClass(); - assertInstanceOf('I_PerRequest', $this->reqInst); + assertInstanceOf('JoinClassInterface', $this->reqInst); } else { $this->reqInst = new PerRequestDefault(); } @@ -80,8 +78,8 @@ public function start() $fullPath = Utils::findFile($fullClassName); // Please DO NOT CHEAT ME assertFileExists($fullPath, "'$fullPath' must exist"); - assertInstanceOf("\Pinpoint\Common\Pinpoint\JoinClass", $junction); - + assertInstanceOf("\Pinpoint\Common\Pinpoint\AspectClassHandle", $junction); + $visitor = new OriginFileVisitor(); $visitor->runAllVisitor($fullPath, $junction); } diff --git a/lib/Pinpoint/Plugins/PerRequestPlugins.php b/lib/Pinpoint/Plugins/PinpointPerRequestPlugins.php similarity index 99% rename from lib/Pinpoint/Plugins/PerRequestPlugins.php rename to lib/Pinpoint/Plugins/PinpointPerRequestPlugins.php index 10fb442..d71146d 100644 --- a/lib/Pinpoint/Plugins/PerRequestPlugins.php +++ b/lib/Pinpoint/Plugins/PinpointPerRequestPlugins.php @@ -20,7 +20,7 @@ require_once __DIR__ . "/__init__.php"; -class PerRequestPlugins +class PinpointPerRequestPlugins { public $tid = null; public $sid = null; diff --git a/lib/Pinpoint/Plugins/Yii2PerRequestPlugins.php b/lib/Pinpoint/Plugins/Yii2PerRequestPlugins.php index c6ce7f9..20aa653 100644 --- a/lib/Pinpoint/Plugins/Yii2PerRequestPlugins.php +++ b/lib/Pinpoint/Plugins/Yii2PerRequestPlugins.php @@ -1,4 +1,5 @@ callExample(); - } - - private function callExample() - { - $ch = curl_init(); - - curl_setopt($ch, CURLOPT_URL, "exmaple.com"); - - echo curl_exec($ch); - - curl_close($ch); - } -} \ No newline at end of file diff --git a/lib/Pinpoint/test/Bear.php b/lib/Pinpoint/test/Bear.php index a49e64a..7e7c508 100644 --- a/lib/Pinpoint/test/Bear.php +++ b/lib/Pinpoint/test/Bear.php @@ -2,13 +2,70 @@ namespace Pinpoint\test; +/** + * I'm the placeholder + */ class Bear { + public $pdo; + /** + * @output + * @parameter: + * @return + */ public function output(string $_1, int $_2, array &$_3) { + return 1010; } - public function noreturn(string $_1, int $_2, array &$_3,$a,$b,$c) + + public function noreturn(string $_1, int $_2, array &$_3, $a, $b, $c) + { + } + + /** + * $joinClass->addClassNameAlias('PDO', \Pinpoint\Plugins\Sys\PDO\PDO::class); + */ + public function pdoNamespaceAlias($driver_options = NULL) + { + $this->pdo = new \PDO('dsn', 'user', 'pass', $driver_options); + } + + /** + * $joinClass->addFunctionAlias('curl_init', 'Pinpoint\Plugins\Sys\curl\curl_init'); + */ + public function curlAlias($host = "www.example.com") + { + + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_URL, $host); + + curl_setopt($ch, CURLOPT_HEADER, TRUE); + + curl_setopt($ch, CURLOPT_NOBODY, TRUE); // remove body + + curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); + + $head = curl_exec($ch); + + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + + curl_close($ch); + } + /** + * test protected function + */ + protected function checkProtected() + { + return __METHOD__; + } + /** + * test private function + */ + private function checkPrivate() { + $this->checkProtected(); + return __METHOD__; } } diff --git a/lib/Pinpoint/test/Cache/Pinpoint/test/Bear.php b/lib/Pinpoint/test/Cache/Pinpoint/test/Bear.php deleted file mode 100644 index 194c772..0000000 --- a/lib/Pinpoint/test/Cache/Pinpoint/test/Bear.php +++ /dev/null @@ -1,35 +0,0 @@ -onBefore(); - $_pinpoint_output_ret = parent::output($_1, $_2, $_3); - $_pinpoint_output_var->onEnd($_pinpoint_output_ret); - return $_pinpoint_output_ret; - } catch (\Exception $e) { - $_pinpoint_output_var->onException($e); - throw $e; - } - } - public function noreturn(string $_1, int $_2, array &$_3, $a, $b, $c) - { - $_pinpoint_noreturn_var = new \Pinpoint\test\OutputMonitor(__METHOD__, $this, $_1, $_2, $_3, $a, $b, $c); - $_pinpoint_noreturn_ret = null; - try { - $_pinpoint_noreturn_var->onBefore(); - parent::noreturn($_1, $_2, $_3, $a, $b, $c); - $_pinpoint_noreturn_var->onEnd($_pinpoint_noreturn_ret); - } catch (\Exception $e) { - $_pinpoint_noreturn_var->onException($e); - throw $e; - } - } -} \ No newline at end of file diff --git a/lib/Pinpoint/test/Cache/Pinpoint/test/ProxyBear.php b/lib/Pinpoint/test/Cache/Pinpoint/test/ProxyBear.php deleted file mode 100644 index 25ddace..0000000 --- a/lib/Pinpoint/test/Cache/Pinpoint/test/ProxyBear.php +++ /dev/null @@ -1,14 +0,0 @@ -[ - // 'PDO'=>'plugins\\PDO', - // 'type03'=>'plugins\\type03', - // 'test\\curl'=>'plugins\\test\\curl', - // 'test\\type1'=>'plugins\\test\\type1', - // 'app\\curl_init_01'=>'plugins\\app\\curl_init_01' - // ], - // 'funCall'=>[ - // 'curl_init'=>'plugins\\curl_init', - // 'app\\foo\\curl_02'=>'plugins\\app\\foo\\curl_02', - // 'app\\foo\\curl_03'=>'plugins\\app\\foo\\curl_0/cersv\3' - // ], - // 'ignoreFiles'=>["pinpoint\\test\\IgnoreClass"], - // 'appendFiles'=>["pinpoint\\test\\AddClass"] - // ]; - - $nConf = new NamingConf(__DIR__ . '/setting.ini'); - static::$naming = $nConf->getConf(); - } - - public function testTrait() - { - $fullpath = __DIR__ . '/TestTrait.php'; - $info = [ - 'getReturnType' => [7, 'pinpoint\\test', 'traitTestPlugin'] - ]; - // test empty naming - $visitor = new OriginFileVisitor(); - - $visitor->runAllVisitor($fullpath, $info); - - foreach (RenderAopClass::getInstance()->getJointClassMap() as $class => $location) { - $exp = str_replace('Cache', 'Comparison', $location); - self::assertFileExists($exp); - self::assertFileExists($location); - self::assertFileEquals($exp, $location, "$exp!=$location"); - } - } - - public function testClass() - { - $fullpath = __DIR__ . '/TestClass.php'; - $info = [ - 'foo' => [7, 'pinpoint\\test', 'traitTestPlugin'], - 'fooUseYield' => [3, 'pinpoint\\test', 'traitTestPlugin'], - 'fooNoReturn' => [4, 'pinpoint\\test', 'traitTestPlugin'], - 'fooNoReturnButReturn' => [4, 'pinpoint\\test\\burden\\depress\\herb\\e\\e\f\\longNp', 'victim'], - 'fooNaughtyFinal' => [7, '\\', 'over'], - '\PDO::query' => [7, 'pinpoint\\test', 'traitTestPlugin'], - '\curl_exec' => [7, 'pinpoint\\test', 'traitTestPlugin'], - 'fooTestACPrivate' => [4, 'pinpoint\\test', 'traitTestPlugin'], - 'fooTestCompatible' => [4, 'pinpoint\\test', 'traitTestPlugin'], - 'returnNothing' => [7, 'pinpoint\\test', 'traitTestPlugin'], - 'returnNothing_1' => [7, 'pinpoint\\test', 'traitTestPlugin'], - '__construct' => [7, 'pinpoint\\test', 'traitTestPlugin'] - ]; - - - $visitor = new OriginFileVisitor(); - - $visitor->runAllVisitor($fullpath, $info, static::$naming); - foreach (RenderAopClass::getInstance()->getJointClassMap() as $class => $location) { - $exp = str_replace('Cache', 'Comparison', $location); - self::assertFileExists($exp); - self::assertFileExists($location); - self::assertFileEquals($exp, $location); - } - } - - public function testNamingReplace() - { - $fullpath = __DIR__ . '/Foo.php'; - $visitor = new OriginFileVisitor(); - $visitor->runAllVisitor($fullpath, [], static::$naming); - foreach (RenderAopClass::getInstance()->getJointClassMap() as $class => $location) { - $exp = str_replace('Cache', 'Comparison', $location); - self::assertFileExists($location); - self::assertFileExists($exp); - self::assertFileEquals($exp, $location); - } - } - - public function testIgnoreList() - { - // $fullpath =__DIR__.'/Foo.php'; - // $osr = new OrgClassParse($fullpath,null,static::$naming); - // foreach ($osr->classIndex as $class => $location) - // { - // $exp = str_replace('Cache','Comparison',$location); - // self::assertFileEquals($exp,$location); - // } - self::assertTrue(true); - } -} diff --git a/lib/Pinpoint/test/Comparison/Pinpoint/test/Bear.php b/lib/Pinpoint/test/Comparison/Pinpoint/test/Bear.php index 194c772..1fd6d16 100644 --- a/lib/Pinpoint/test/Comparison/Pinpoint/test/Bear.php +++ b/lib/Pinpoint/test/Comparison/Pinpoint/test/Bear.php @@ -32,4 +32,32 @@ public function noreturn(string $_1, int $_2, array &$_3, $a, $b, $c) throw $e; } } + protected function checkProtected() + { + $_pinpoint_checkProtected_var = new \Pinpoint\test\OutputMonitor(__METHOD__, $this); + $_pinpoint_checkProtected_ret = null; + try { + $_pinpoint_checkProtected_var->onBefore(); + $_pinpoint_checkProtected_ret = parent::checkProtected(); + $_pinpoint_checkProtected_var->onEnd($_pinpoint_checkProtected_ret); + return $_pinpoint_checkProtected_ret; + } catch (\Exception $e) { + $_pinpoint_checkProtected_var->onException($e); + throw $e; + } + } + protected function checkPrivate() + { + $_pinpoint_checkPrivate_var = new \Pinpoint\test\OutputMonitor(__METHOD__, $this); + $_pinpoint_checkPrivate_ret = null; + try { + $_pinpoint_checkPrivate_var->onBefore(); + $_pinpoint_checkPrivate_ret = parent::checkPrivate(); + $_pinpoint_checkPrivate_var->onEnd($_pinpoint_checkPrivate_ret); + return $_pinpoint_checkPrivate_ret; + } catch (\Exception $e) { + $_pinpoint_checkPrivate_var->onException($e); + throw $e; + } + } } \ No newline at end of file diff --git a/lib/Pinpoint/test/Comparison/Pinpoint/test/ProxyBear.php b/lib/Pinpoint/test/Comparison/Pinpoint/test/ProxyBear.php index 25ddace..a73b6cc 100644 --- a/lib/Pinpoint/test/Comparison/Pinpoint/test/ProxyBear.php +++ b/lib/Pinpoint/test/Comparison/Pinpoint/test/ProxyBear.php @@ -2,8 +2,17 @@ namespace Pinpoint\test; +/** + * I'm the placeholder + */ class ProxyBear { + public $pdo; + /** + * @output + * @parameter: + * @return + */ public function output(string $_1, int $_2, array &$_3) { return 1010; @@ -11,4 +20,41 @@ public function output(string $_1, int $_2, array &$_3) public function noreturn(string $_1, int $_2, array &$_3, $a, $b, $c) { } + /** + * $joinClass->addClassNameAlias('PDO', \Pinpoint\Plugins\Sys\PDO\PDO::class); + */ + public function pdoNamespaceAlias($driver_options = NULL) + { + $this->pdo = new \Pinpoint\Plugins\Sys\PDO\PDO('dsn', 'user', 'pass', $driver_options); + } + /** + * $joinClass->addFunctionAlias('curl_init', 'Pinpoint\Plugins\Sys\curl\curl_init'); + */ + public function curlAlias($host = "www.example.com") + { + $ch = \Pinpoint\Plugins\Sys\curl\curl_init(); + \Pinpoint\Plugins\Sys\curl\curl_setopt($ch, CURLOPT_URL, $host); + \Pinpoint\Plugins\Sys\curl\curl_setopt($ch, CURLOPT_HEADER, TRUE); + \Pinpoint\Plugins\Sys\curl\curl_setopt($ch, CURLOPT_NOBODY, TRUE); + // remove body + \Pinpoint\Plugins\Sys\curl\curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); + $head = \Pinpoint\Plugins\Sys\curl\curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + \Pinpoint\Plugins\Sys\curl\curl_close($ch); + } + /** + * test protected function + */ + protected function checkProtected() + { + return __METHOD__; + } + /** + * test private function + */ + protected function checkPrivate() + { + $this->checkProtected(); + return __METHOD__; + } } \ No newline at end of file diff --git a/lib/Pinpoint/test/Foo.php b/lib/Pinpoint/test/Foo.php deleted file mode 100644 index f7b6005..0000000 --- a/lib/Pinpoint/test/Foo.php +++ /dev/null @@ -1,51 +0,0 @@ -assertFileExists($fullPath); - $joinClass = new JoinClass(Bear::class); - $joinClass->addJoinPoint('output', OutputMonitor::class); - $joinClass->addJoinPoint('noreturn', OutputMonitor::class); + $classHandler = new AspectClassHandle(Bear::class); + $classHandler->addJoinPoint('output', OutputMonitor::class); + $classHandler->addJoinPoint('noreturn', OutputMonitor::class); + + $classHandler->addClassNameAlias('PDO', \Pinpoint\Plugins\Sys\PDO\PDO::class); + $classHandler->addFunctionAlias('curl_init', 'Pinpoint\Plugins\Sys\curl\curl_init'); + $classHandler->addFunctionAlias('curl_setopt', 'Pinpoint\Plugins\Sys\curl\curl_setopt'); + $classHandler->addFunctionAlias('curl_exec', 'Pinpoint\Plugins\Sys\curl\curl_exec'); + $classHandler->addFunctionAlias('curl_close', 'Pinpoint\Plugins\Sys\curl\curl_close'); + + $classHandler->addJoinPoint('checkProtected', OutputMonitor::class); + $classHandler->addJoinPoint('checkPrivate', OutputMonitor::class); + $visitor = new OriginFileVisitor(); - $visitor->runAllVisitor($fullPath, $joinClass); + $visitor->runAllVisitor($fullPath, $classHandler); $classMap = RenderAopClass::getInstance()->getJointClassMap(); - $this->assertArrayHasKey(Bear::class,$classMap); - foreach ($classMap as $class => $file){ + $this->assertArrayHasKey(Bear::class, $classMap); + foreach ($classMap as $class => $file) { // print_r(str_replace("Comparison","Cache",$file)); - $this->assertFileEquals($file,str_replace("Cache","Comparison",$file)); + $this->assertFileEquals($file, str_replace("Cache", "Comparison", $file)); } - // $this->assertFileEquals(""); } } - diff --git a/lib/Pinpoint/test/OutputMonitor.php b/lib/Pinpoint/test/OutputMonitor.php index e5e30a7..fc558aa 100644 --- a/lib/Pinpoint/test/OutputMonitor.php +++ b/lib/Pinpoint/test/OutputMonitor.php @@ -2,9 +2,9 @@ namespace Pinpoint\test; -use Pinpoint\Common\Monitor; +use Pinpoint\Common\AbstractMonitor; -class OutputMonitor extends Monitor +class OutputMonitor extends AbstractMonitor { function onBefore() { @@ -12,7 +12,6 @@ function onBefore() function onEnd(&$ret) { - return 1011; } function onException($e) diff --git a/lib/Pinpoint/test/TestClass.php b/lib/Pinpoint/test/TestClass.php deleted file mode 100644 index c744f9a..0000000 --- a/lib/Pinpoint/test/TestClass.php +++ /dev/null @@ -1,83 +0,0 @@ -query('SELECT name, color, calories FROM fruit ORDER BY name'); - - } - - private function fooTestACPrivate() - { - echo "I'm a private function"; - return "OK"; - } - public function fooTestCompatible(class1 $a,class2 $b,FooClass $c,FooClass4 $d) - { - return null; - } - - public function returnNothing(): void - { - return ; - } - public function returnNothing_1() - { - return ; - } -} diff --git a/lib/Pinpoint/test/TestTrait.php b/lib/Pinpoint/test/TestTrait.php deleted file mode 100644 index bfc0e78..0000000 --- a/lib/Pinpoint/test/TestTrait.php +++ /dev/null @@ -1,19 +0,0 @@ - Date: Mon, 30 Oct 2023 16:55:51 +0800 Subject: [PATCH 06/13] support yii2:UrlRule --- Readme.md | 2 - auto_pinpointed.php | 1 - lib/Pinpoint/Common/AbstractMonitor.php | 2 +- lib/Pinpoint/Common/AspectClassHandle.php | 8 ++-- .../Common/GenOriginClassTemplateHelper.php | 2 +- lib/Pinpoint/Common/JoinClassInterface.php | 2 +- lib/Pinpoint/Common/PerRequest.php | 2 +- lib/Pinpoint/Common/PinpointDriver.php | 27 +++++++----- .../Plugins/PinpointPerRequestPlugins.php | 2 +- .../Plugins/Yii2PerRequestPlugins.php | 12 ++++-- lib/Pinpoint/Plugins/yii2/UrlRule.php | 42 +++++++++++++++++++ 11 files changed, 76 insertions(+), 26 deletions(-) create mode 100644 lib/Pinpoint/Plugins/yii2/UrlRule.php diff --git a/Readme.md b/Readme.md index 2ffbd35..98f7a4a 100644 --- a/Readme.md +++ b/Readme.md @@ -61,8 +61,6 @@ require_once __DIR__."/../vendor/autoload.php"; // A writable path for caching AOP code define('AOP_CACHE_DIR',__DIR__.'/../Cache/'); -// Your plugins directory: All plugins must have a suffix "Plugin.php",as "CommonPlugin.php mysqlPlugin.php RPCPlugin.php" -define('PLUGINS_DIR',__DIR__.'/../Plugins/'); // since 0.2.5+ PINPOINT_USE_CACHE = N, auto_pinpointed.php will generate Cache/* on every request. define('PINPOINT_USE_CACHE','YES'); // Use pinpoint-php-aop auto_pinpointed.php instead of vendor/autoload.php diff --git a/auto_pinpointed.php b/auto_pinpointed.php index d77b2c9..140ef39 100644 --- a/auto_pinpointed.php +++ b/auto_pinpointed.php @@ -23,5 +23,4 @@ use Pinpoint\Common\PinpointDriver; define('CLASS_PREFIX', 'Proxied_'); -assert(defined('PLUGINS_DIR')); PinpointDriver::getInstance()->start(); diff --git a/lib/Pinpoint/Common/AbstractMonitor.php b/lib/Pinpoint/Common/AbstractMonitor.php index a3a5d7f..da11207 100644 --- a/lib/Pinpoint/Common/AbstractMonitor.php +++ b/lib/Pinpoint/Common/AbstractMonitor.php @@ -33,7 +33,7 @@ public function __construct($name, $who, &...$args) abstract function onBefore(); - abstract function onEnd(&$ret); + abstract function onEnd($ret); abstract function onException($e); } diff --git a/lib/Pinpoint/Common/AspectClassHandle.php b/lib/Pinpoint/Common/AspectClassHandle.php index 513083d..c0cc4ac 100644 --- a/lib/Pinpoint/Common/AspectClassHandle.php +++ b/lib/Pinpoint/Common/AspectClassHandle.php @@ -22,14 +22,14 @@ class AspectClassHandle { - public string $name; + public string $aspClassName; public $methodJoinPoints = array(); public $classAlias = array(); public $funcAlias = array(); public function __construct(string $_name) { - $this->name = $_name; + $this->aspClassName = $_name; } public function getMethodJoinPoints() @@ -39,8 +39,8 @@ public function getMethodJoinPoints() public function addJoinPoint(string $method, string $monitor) { - if (method_exists($this->name, $method) == false) { - throw new \Exception("no '$method' in '$this->name'"); + if (method_exists($this->aspClassName, $method) == false) { + throw new \Exception("no '$method' in '$this->aspClassName'"); } $this->methodJoinPoints[$method] = $monitor; diff --git a/lib/Pinpoint/Common/GenOriginClassTemplateHelper.php b/lib/Pinpoint/Common/GenOriginClassTemplateHelper.php index 09df28a..97ba083 100644 --- a/lib/Pinpoint/Common/GenOriginClassTemplateHelper.php +++ b/lib/Pinpoint/Common/GenOriginClassTemplateHelper.php @@ -41,7 +41,7 @@ class GenOriginClassTemplateHelper extends AbstractClassFile public function __construct(AspectClassHandle $classHandler, string $namePrefix) { parent::__construct($namePrefix); - $path = Utils::findFile($classHandler->name); + $path = Utils::findFile($classHandler->aspClassName); $this->originClassFileDir = dirname($path); $this->originClassFilePath = $path; diff --git a/lib/Pinpoint/Common/JoinClassInterface.php b/lib/Pinpoint/Common/JoinClassInterface.php index 76f1021..ff67ae6 100644 --- a/lib/Pinpoint/Common/JoinClassInterface.php +++ b/lib/Pinpoint/Common/JoinClassInterface.php @@ -21,5 +21,5 @@ interface JoinClassInterface { - public function joinedClass(): array; + public function joinedClassSet(): array; } diff --git a/lib/Pinpoint/Common/PerRequest.php b/lib/Pinpoint/Common/PerRequest.php index 80d1f76..ab620d1 100644 --- a/lib/Pinpoint/Common/PerRequest.php +++ b/lib/Pinpoint/Common/PerRequest.php @@ -21,7 +21,7 @@ class PerRequestDefault implements JoinClassInterface { - public function joinedClass(): array + public function joinedClassSet(): array { return []; } diff --git a/lib/Pinpoint/Common/PinpointDriver.php b/lib/Pinpoint/Common/PinpointDriver.php index b3829b0..5a2a699 100644 --- a/lib/Pinpoint/Common/PinpointDriver.php +++ b/lib/Pinpoint/Common/PinpointDriver.php @@ -46,7 +46,7 @@ final private function __construct() if (defined('PP_REQ_PLUGINS') && class_exists(PP_REQ_PLUGINS)) { $userPerRequestClass = PP_REQ_PLUGINS; $this->reqInst = new $userPerRequestClass(); - assertInstanceOf('JoinClassInterface', $this->reqInst); + assert(is_a($this->reqInst, 'Pinpoint\Common\JoinClassInterface')); } else { $this->reqInst = new PerRequestDefault(); } @@ -59,29 +59,34 @@ public function getRequestInst() public function start() { - $joinedClass = $this->reqInst->joinedClass(); - if (empty($joinedClass)) { - return; - } - RenderAopClass::getInstance(); /// checking the cached file exist, if exist load it if (Utils::checkCacheReady()) { RenderAopClass::getInstance()->createFrom(Utils::loadCachedClass()); + VendorAdaptorClassLoader::enable(); RenderAopClassLoader::start(); return; } VendorAdaptorClassLoader::enable(); - foreach ($joinedClass as $fullClassName => $junction) { - if (empty($fullClassName)) + + $joinedClassSet = $this->reqInst->joinedClassSet(); + if (empty($joinedClassSet)) { + return; + } + + foreach ($joinedClassSet as $aspClassHandler) { + assert(is_a($aspClassHandler, '\Pinpoint\Common\AspectClassHandle')); + $fullClassName = $aspClassHandler->aspClassName; + if (empty($fullClassName)) { continue; + } + $fullPath = Utils::findFile($fullClassName); // Please DO NOT CHEAT ME - assertFileExists($fullPath, "'$fullPath' must exist"); - assertInstanceOf("\Pinpoint\Common\Pinpoint\AspectClassHandle", $junction); + assert(file_exists($fullPath), " '$fullClassName' ->'$fullPath' must exist"); $visitor = new OriginFileVisitor(); - $visitor->runAllVisitor($fullPath, $junction); + $visitor->runAllVisitor($fullPath, $aspClassHandler); } // save render aop class into index file Utils::saveCachedClass(RenderAopClass::getInstance()->getJointClassMap()); diff --git a/lib/Pinpoint/Plugins/PinpointPerRequestPlugins.php b/lib/Pinpoint/Plugins/PinpointPerRequestPlugins.php index d71146d..b361c0b 100644 --- a/lib/Pinpoint/Plugins/PinpointPerRequestPlugins.php +++ b/lib/Pinpoint/Plugins/PinpointPerRequestPlugins.php @@ -39,7 +39,7 @@ public function traceLimit() return $this->isLimit; } - protected function __construct() + public function __construct() { if (defined('PP_REPORT_MEMORY_USAGE') && PP_REPORT_MEMORY_USAGE === '1') { $this->mem_start = memory_get_usage(); diff --git a/lib/Pinpoint/Plugins/Yii2PerRequestPlugins.php b/lib/Pinpoint/Plugins/Yii2PerRequestPlugins.php index 20aa653..93b0339 100644 --- a/lib/Pinpoint/Plugins/Yii2PerRequestPlugins.php +++ b/lib/Pinpoint/Plugins/Yii2PerRequestPlugins.php @@ -22,10 +22,11 @@ use Pinpoint\Common\Utils; use Pinpoint\Plugins\PinpointPerRequestPlugins; use Pinpoint\Common\JoinClassInterface; +use Pinpoint\Common\AspectClassHandle; class Yii2PerRequestPlugins extends PinpointPerRequestPlugins implements JoinClassInterface { - protected function __construct() + public function __construct() { parent::__construct(); // enable findFile patch @@ -49,8 +50,13 @@ public function findFileInYii($className): string return ""; } - public function joinedClass(): array + public function joinedClassSet(): array { - return []; + $cls = []; + $classHandler = new AspectClassHandle(\yii\web\UrlRule::class); + $classHandler->addJoinPoint('parseRequest', yii2\UrlRule::class); + + $cls[] = $classHandler; + return $cls; } } diff --git a/lib/Pinpoint/Plugins/yii2/UrlRule.php b/lib/Pinpoint/Plugins/yii2/UrlRule.php new file mode 100644 index 0000000..4231bb9 --- /dev/null +++ b/lib/Pinpoint/Plugins/yii2/UrlRule.php @@ -0,0 +1,42 @@ +args[1]; + $request->__pinpoint__route = $route; + } + } + + function onException($e) + { + } +} From 7643a75ac9a91e9de4508ac6b5ab6073e8b7717b Mon Sep 17 00:00:00 2001 From: eeliu <27064129+eeliu@users.noreply.github.com> Date: Tue, 31 Oct 2023 10:48:03 +0800 Subject: [PATCH 07/13] add logger and userclassloader --- .devcontainer/devcontainer.json | 3 +- composer.json | 5 +- lib/Pinpoint/Common/AbstractClassFile.php | 1 + lib/Pinpoint/Common/AbstractMonitor.php | 2 +- .../Common/GenOriginClassTemplateHelper.php | 3 + .../Common/GenProxyClassTemplateHelper.php | 6 +- lib/Pinpoint/Common/Logger.php | 65 +++++++++++++ lib/Pinpoint/Common/OriginFileVisitor.php | 1 + lib/Pinpoint/Common/PerRequest.php | 9 ++ lib/Pinpoint/Common/PinpointDriver.php | 6 +- lib/Pinpoint/Common/RenderAopClass.php | 7 +- lib/Pinpoint/Common/RenderAopClassLoader.php | 11 ++- .../Common/UserClassLoaderInterface.php | 25 +++++ lib/Pinpoint/Common/Utils.php | 3 + .../Common/VendorAdaptorClassLoader.php | 94 ++++++++----------- .../Plugins/Yii2PerRequestPlugins.php | 8 ++ lib/Pinpoint/Plugins/yii2/UrlRule.php | 11 ++- test_logger.php | 15 +++ 18 files changed, 201 insertions(+), 74 deletions(-) create mode 100644 lib/Pinpoint/Common/Logger.php create mode 100644 lib/Pinpoint/Common/UserClassLoaderInterface.php create mode 100644 test_logger.php diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index faea12b..51a5513 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -10,7 +10,8 @@ "donjayamanne.githistory", "adam-bender.commit-message-editor", "bmewburn.vscode-intelephense-client", - "xdebug.php-debug" + "xdebug.php-debug", + "streetsidesoftware.code-spell-checker" ] } } diff --git a/composer.json b/composer.json index 4da4723..986e906 100644 --- a/composer.json +++ b/composer.json @@ -20,6 +20,7 @@ }, "require": { "php": ">=7", - "nikic/php-parser": "^4.1" + "nikic/php-parser": "^4.1", + "monolog/monolog": "2.x-dev" } -} \ No newline at end of file +} diff --git a/lib/Pinpoint/Common/AbstractClassFile.php b/lib/Pinpoint/Common/AbstractClassFile.php index f3d1e1c..fd1a109 100644 --- a/lib/Pinpoint/Common/AbstractClassFile.php +++ b/lib/Pinpoint/Common/AbstractClassFile.php @@ -132,6 +132,7 @@ public function done() $fullPath = AOP_CACHE_DIR . '/' . str_replace('\\', '/', $this->className) . '.php'; $context = $this->_astPrinter->prettyPrintFile($this->newAstNode); RenderAopClass::getInstance()->insertMapping($this->className, $fullPath); + Logger::Inst()->debug("map/save new class '$this->className' to '$fullPath' "); Utils::saveObj($context, $fullPath); } diff --git a/lib/Pinpoint/Common/AbstractMonitor.php b/lib/Pinpoint/Common/AbstractMonitor.php index da11207..a3a5d7f 100644 --- a/lib/Pinpoint/Common/AbstractMonitor.php +++ b/lib/Pinpoint/Common/AbstractMonitor.php @@ -33,7 +33,7 @@ public function __construct($name, $who, &...$args) abstract function onBefore(); - abstract function onEnd($ret); + abstract function onEnd(&$ret); abstract function onException($e); } diff --git a/lib/Pinpoint/Common/GenOriginClassTemplateHelper.php b/lib/Pinpoint/Common/GenOriginClassTemplateHelper.php index 97ba083..6641d6f 100644 --- a/lib/Pinpoint/Common/GenOriginClassTemplateHelper.php +++ b/lib/Pinpoint/Common/GenOriginClassTemplateHelper.php @@ -242,6 +242,7 @@ function handlerUseUseNode(&$node) } } if (!empty($hiddenClassAlias)) { + Logger::Inst()->debug("found hiddenClassAlias:'$hiddenClassAlias'"); $this->classAliasSet += $hiddenClassAlias; } return; @@ -278,12 +279,14 @@ function handlerUseNode($node) if (array_key_exists($fullName, $this->funcAlias)) { $newName = new Node\Name($this->funcAlias[$fullName]); $uses->name = $newName; + Logger::Inst()->debug("found funcAlias:'$fullName' -> '$this->funcAlias[$fullName]' "); } } else { // use ABC\Math; if (array_key_exists($fullName, $this->classAliasSet)) { $newName = new Node\Name($this->classAliasSet[$fullName]); $uses->name = $newName; + Logger::Inst()->debug("found classAlias:'$fullName' -> '$this->classAliasSet[$fullName]' "); } } } diff --git a/lib/Pinpoint/Common/GenProxyClassTemplateHelper.php b/lib/Pinpoint/Common/GenProxyClassTemplateHelper.php index 0af1ef3..c3c7a66 100644 --- a/lib/Pinpoint/Common/GenProxyClassTemplateHelper.php +++ b/lib/Pinpoint/Common/GenProxyClassTemplateHelper.php @@ -120,7 +120,7 @@ public function handleClassLeaveMethodNode($node, $monitorClassFullName) // 1. make a new method overriding parent's $originMethodName = $node->name->toString(); - + Logger::Inst()->debug("generate pinpoint code block for '$originMethodName'"); $funcVar = new Node\Arg(new Node\Scalar\MagicConst\Method()); $thisMethod = $this->factory->method($originMethodName); @@ -131,11 +131,11 @@ public function handleClassLeaveMethodNode($node, $monitorClassFullName) } if ($node->flags & Node\Stmt\Class_::MODIFIER_PRIVATE) { + Logger::Inst()->debug("'$originMethodName' is a private, changes to protected"); $thisMethod->makeProtected(); } if ($node->flags & Node\Stmt\Class_::MODIFIER_ABSTRACT) { - $thisMethod->makeAbstract(); } @@ -151,6 +151,7 @@ public function handleClassLeaveMethodNode($node, $monitorClassFullName) if ($node->flags & Node\Stmt\Class_::MODIFIER_STATIC) { $thisMethod->makeStatic(); $selfVar = new Node\Arg(new Node\Expr\ConstFetch(new Node\Name('null'))); + Logger::Inst()->debug("'$originMethodName' is a static function"); } else { $selfVar = new Node\Arg(new Node\Expr\Variable('this')); } @@ -188,6 +189,7 @@ public function handleClassLeaveMethodNode($node, $monitorClassFullName) ); if ($this->hasRet) { + Logger::Inst()->debug("'$originMethodName' has return value "); /// $ret = paraent::$originMethodName(); $tryBlock[] = new Node\Stmt\Expression(new Node\Expr\Assign( new Node\Expr\Variable($retName), diff --git a/lib/Pinpoint/Common/Logger.php b/lib/Pinpoint/Common/Logger.php new file mode 100644 index 0000000..96ebfe4 --- /dev/null +++ b/lib/Pinpoint/Common/Logger.php @@ -0,0 +1,65 @@ +log = $logger; + } + + public function debug($message, array $context = []) + { + if ($this->log != null) { + $this->log->debug($message, $context); + } + } + + public function info($message, array $context = []) + { + if ($this->log != null) { + $this->log->info($message, $context); + } + } + public function warning($message, array $context = []) + { + if ($this->log != null) { + $this->log->warning($message, $context); + } + } +} diff --git a/lib/Pinpoint/Common/OriginFileVisitor.php b/lib/Pinpoint/Common/OriginFileVisitor.php index c9ccf60..a20bd7f 100644 --- a/lib/Pinpoint/Common/OriginFileVisitor.php +++ b/lib/Pinpoint/Common/OriginFileVisitor.php @@ -45,6 +45,7 @@ private function getVisitor(AspectClassHandle $classHandler) $classPrefix = ""; $visitors = []; if (!empty($classHandler->getMethodJoinPoints())) { + Logger::Inst()->debug("found methodJoinPoints "); $classPrefix = CLASS_PREFIX; $visitors[] = new GenProxyClassTemplateHelper($classHandler, $classPrefix); } diff --git a/lib/Pinpoint/Common/PerRequest.php b/lib/Pinpoint/Common/PerRequest.php index ab620d1..9fd2c66 100644 --- a/lib/Pinpoint/Common/PerRequest.php +++ b/lib/Pinpoint/Common/PerRequest.php @@ -19,8 +19,17 @@ namespace Pinpoint\Common; +use Monolog\Logger as mlogger; +use Monolog\Handler\StreamHandler; + class PerRequestDefault implements JoinClassInterface { + public function __construct() + { + $log = new mlogger('name'); + $log->pushHandler(new StreamHandler('php://stdout', Logger::WARNING)); + Logger::Inst()->setLogger($log); + } public function joinedClassSet(): array { return []; diff --git a/lib/Pinpoint/Common/PinpointDriver.php b/lib/Pinpoint/Common/PinpointDriver.php index 5a2a699..b24de56 100644 --- a/lib/Pinpoint/Common/PinpointDriver.php +++ b/lib/Pinpoint/Common/PinpointDriver.php @@ -62,11 +62,13 @@ public function start() RenderAopClass::getInstance(); /// checking the cached file exist, if exist load it if (Utils::checkCacheReady()) { + Logger::Inst()->debug("found cache"); RenderAopClass::getInstance()->createFrom(Utils::loadCachedClass()); VendorAdaptorClassLoader::enable(); RenderAopClassLoader::start(); return; } + VendorAdaptorClassLoader::enable(); $joinedClassSet = $this->reqInst->joinedClassSet(); @@ -80,10 +82,10 @@ public function start() if (empty($fullClassName)) { continue; } - $fullPath = Utils::findFile($fullClassName); + Logger::Inst()->debug("found aspectClass '$fullClassName' -> '$fullPath' "); // Please DO NOT CHEAT ME - assert(file_exists($fullPath), " '$fullClassName' ->'$fullPath' must exist"); + assert(file_exists($fullPath), "'$fullClassName' ->'$fullPath' must exist"); $visitor = new OriginFileVisitor(); $visitor->runAllVisitor($fullPath, $aspClassHandler); diff --git a/lib/Pinpoint/Common/RenderAopClass.php b/lib/Pinpoint/Common/RenderAopClass.php index 40fb757..9227a32 100644 --- a/lib/Pinpoint/Common/RenderAopClass.php +++ b/lib/Pinpoint/Common/RenderAopClass.php @@ -48,14 +48,17 @@ public function createFrom(array $clsMap) public function findFile($classFullName): string { + Logger::Inst()->debug("try to findFile:'$classFullName'"); if (is_callable($this->clsLoadUserFilterCB)) { if (call_user_func($this->clsLoadUserFilterCB, $classFullName) == true) { return ''; } } - if (isset($this->classLoaderMap[$classFullName])) { - return $this->classLoaderMap[$classFullName]; + $classFile = $this->classLoaderMap[$classFullName]; + if (isset($classFile)) { + Logger::Inst()->debug("findFile:'$classFullName' -> $classFile'"); + return $classFile; } return ''; diff --git a/lib/Pinpoint/Common/RenderAopClassLoader.php b/lib/Pinpoint/Common/RenderAopClassLoader.php index 1e97e34..07223b7 100644 --- a/lib/Pinpoint/Common/RenderAopClassLoader.php +++ b/lib/Pinpoint/Common/RenderAopClassLoader.php @@ -1,4 +1,6 @@ -findFile($class); - if($file != ''){ + if ($file != '') { require $file; return true; } @@ -20,6 +22,7 @@ public static function loadClass($class) public static function start() { - spl_autoload_register( [__NAMESPACE__.'\RenderAopClassLoader','loadClass'],true,true); + spl_autoload_register([__NAMESPACE__ . '\RenderAopClassLoader', 'loadClass'], true, true); + Logger::Inst()->debug("register RenderAopClassLoader"); } -} \ No newline at end of file +} diff --git a/lib/Pinpoint/Common/UserClassLoaderInterface.php b/lib/Pinpoint/Common/UserClassLoaderInterface.php new file mode 100644 index 0000000..fc46beb --- /dev/null +++ b/lib/Pinpoint/Common/UserClassLoaderInterface.php @@ -0,0 +1,25 @@ +debug("saveCachedClass size= '$size'"); } } diff --git a/lib/Pinpoint/Common/VendorAdaptorClassLoader.php b/lib/Pinpoint/Common/VendorAdaptorClassLoader.php index caf3672..f6e28f3 100644 --- a/lib/Pinpoint/Common/VendorAdaptorClassLoader.php +++ b/lib/Pinpoint/Common/VendorAdaptorClassLoader.php @@ -1,4 +1,6 @@ -vendor_load_class_func = function (string $clsFullName) use (&$orgLoader){ - return call_user_func($orgLoader,$clsFullName); + $this->vendor_load_class_func = function (string $clsFullName) use (&$orgLoader) { + return call_user_func($orgLoader, $clsFullName); }; - // check loader is ClassLoader - if($orgLoader[0] instanceof ClassLoader) - { + // it's a common ClassLoader + if ($orgLoader[0] instanceof ClassLoader) { - $this->callOrgFindFile = function (string $clsFullName) use (&$orgLoader){ + $this->originClassLoaderFunc = function (string $clsFullName) use (&$orgLoader) { return $orgLoader[0]->findFile($clsFullName); }; - - }else if( is_callable($orgLoader) && count($orgLoader) >=2 ){ - /** - * here hide a case: what if the findFile is private - * [0]: maybe the class name - * [1]:maybe the static function name - * - * 1. check [0] , there is findFile function - */ - - if(!method_exists($orgLoader[0],'findFile')){ - throw new Exception("ClassLoader not compatible: no findFile method"); - } - - $this->callOrgFindFile = function (string $clsFullName) use (&$orgLoader){ - $_loader = new $orgLoader[0]; - $callfindFile = function($name) { - return $this->findFile($name); - }; - return $callfindFile->call($_loader,$clsFullName); - }; - - }else{ - throw new Exception("ClassLoader not compatible: classLoader unknow"); + return; } - assert($this->callOrgFindFile); + //check is `findFile` classLoader + if ($userLoader != null) { + $this->originClassLoaderFunc = $userLoader->userClassLoader($orgLoader); + assert(is_callable($this->originClassLoaderFunc)); + return; + } + throw new Exception("unknown classLoader:'$orgLoader'"); } - public function findFile(string $classFullName):string + public function findFile(string $classFullName): string { - - if( is_callable($this->callOrgFindFile) ) - { - $file = call_user_func($this->callOrgFindFile,$classFullName); - if ( $file !== false ) - { + Logger::Inst()->debug("try to VendorAdaptorClassLoader->findFile:'$classFullName' "); + if (is_callable($this->originClassLoaderFunc)) { + $file = call_user_func($this->originClassLoaderFunc, $classFullName); + if ($file !== false) { + Logger::Inst()->debug("VendorAdaptorClassLoader->findFile:'$classFullName' ->'$file' "); return realpath($file) ?: $file; } } @@ -96,8 +80,8 @@ public function findFile(string $classFullName):string */ public function loadClass($class) { - if(is_callable($this->vendor_load_class_func)){ - return call_user_func($this->vendor_load_class_func,$class); + if (is_callable($this->vendor_load_class_func)) { + return call_user_func($this->vendor_load_class_func, $class); } } @@ -106,16 +90,18 @@ public function loadClass($class) * @param $classIndex * @return bool */ - public static function enable() + public static function enable(UserClassLoaderInterface $u_classLoader = null) { $loaders = spl_autoload_functions(); - foreach ($loaders as &$loader) { - if ( is_array($loader) && is_callable($loader) ) {// common ClassLoader style - - try{ + foreach ($loaders as &$olderLoader) { + if (is_array($olderLoader) && is_callable($olderLoader)) { + try { // replace composer loader with aopclassLoader - $_loader = new self($loader); - }catch (Exception $e){ + $newLoader = new VendorAdaptorClassLoader($olderLoader, $u_classLoader); + // unregister composer loader + spl_autoload_unregister($olderLoader); + spl_autoload_register(array($newLoader, 'loadClass'), true, false); + } catch (Exception $e) { /** * if current loader not compatible, just ignore it! * why? @@ -123,15 +109,9 @@ public static function enable() * 2. Keep this loader, as it will handled its class. (We could write patch for this loader) * 3. Pinpoint classloader is the highest priority */ - continue; + Logger::Inst()->debug(" re-register pinpointloader failed '$e' "); } - - // unregister composer loader - spl_autoload_unregister($loader); - - spl_autoload_register(array($_loader,'loadClass'),true,false); } } } - } diff --git a/lib/Pinpoint/Plugins/Yii2PerRequestPlugins.php b/lib/Pinpoint/Plugins/Yii2PerRequestPlugins.php index 93b0339..1668e7d 100644 --- a/lib/Pinpoint/Plugins/Yii2PerRequestPlugins.php +++ b/lib/Pinpoint/Plugins/Yii2PerRequestPlugins.php @@ -23,6 +23,11 @@ use Pinpoint\Plugins\PinpointPerRequestPlugins; use Pinpoint\Common\JoinClassInterface; use Pinpoint\Common\AspectClassHandle; +use Pinpoint\Common\Logger; + +use Monolog\Logger as mLogger; +use Monolog\Handler\StreamHandler; + class Yii2PerRequestPlugins extends PinpointPerRequestPlugins implements JoinClassInterface { @@ -31,6 +36,9 @@ public function __construct() parent::__construct(); // enable findFile patch Utils::addLoaderPatch(array($this, 'findFileInYii'), null); + $log = new mLogger('Yii2PerRequestPlugins'); + $log->pushHandler(new StreamHandler('php://stdout', mLogger::DEBUG)); + Logger::Inst()->setLogger($log); } public function findFileInYii($className): string diff --git a/lib/Pinpoint/Plugins/yii2/UrlRule.php b/lib/Pinpoint/Plugins/yii2/UrlRule.php index 4231bb9..d536c78 100644 --- a/lib/Pinpoint/Plugins/yii2/UrlRule.php +++ b/lib/Pinpoint/Plugins/yii2/UrlRule.php @@ -20,6 +20,7 @@ namespace Pinpoint\Plugins\yii2; use Pinpoint\Common\AbstractMonitor; +use Pinpoint\Common\Logger; class UrlRule extends AbstractMonitor { @@ -27,16 +28,20 @@ function onBefore() { } - function onEnd($ret) + function onEnd(&$ret) { if (!is_bool($ret) && sizeof($ret) == 2) { $route = $ret[0]; - $request = $this->args[1]; - $request->__pinpoint__route = $route; + // $request = $this->args[1]; + // $request->__pinpoint__route = $route; + Logger::Inst()->debug("found route:'$route'"); + pinpoint_set_context("__pinpoint__route", $route); } + // return $ret; } function onException($e) { + Logger::Inst()->debug(__CLASS__ . "onException '$e'"); } } diff --git a/test_logger.php b/test_logger.php new file mode 100644 index 0000000..7be6837 --- /dev/null +++ b/test_logger.php @@ -0,0 +1,15 @@ +pushHandler(new StreamHandler('php://stdout', Logger::WARNING)); + +// add records to the log +$log->warning('Foo'); +$log->error('Bar'); From d610af3c273968aa34a562dfd7786f00983d737e Mon Sep 17 00:00:00 2001 From: eeliu <27064129+eeliu@users.noreply.github.com> Date: Thu, 2 Nov 2023 17:30:51 +0800 Subject: [PATCH 08/13] try to fix bug in yii --- .gitignore | 4 +- auto_pinpointed.php | 1 - lib/Pinpoint/Common/AbstractClassFile.php | 9 +- lib/Pinpoint/Common/AbstractMonitor.php | 4 +- lib/Pinpoint/Common/ClassLoaderFactory.php | 45 ++ lib/Pinpoint/Common/CodeVisitor.php | 4 - .../Common/GenOriginClassTemplateHelper.php | 294 ---------- .../Common/GenProxyClassTemplateHelper.php | 523 ++++++++---------- .../{RenderAopClass.php => MonitorClass.php} | 26 +- lib/Pinpoint/Common/MonitorClassLoader.php | 38 ++ lib/Pinpoint/Common/OriginFileVisitor.php | 8 +- .../{PerRequest.php => PerRequestDefault.php} | 16 +- lib/Pinpoint/Common/PinpointDriver.php | 32 +- lib/Pinpoint/Common/RenderAopClassLoader.php | 28 - lib/Pinpoint/Common/StanderClassLoader.php | 72 +++ ...rInterface.php => UserFindClassLoader.php} | 13 +- ...terface.php => UserFrameworkInterface.php} | 3 +- lib/Pinpoint/Common/Utils.php | 70 +-- .../Common/VendorAdaptorClassLoader.php | 117 ---- .../Common/VendorClassLoaderAdaptor.php | 95 ++++ lib/Pinpoint/Plugins/Common/CommonPlugin.php | 21 +- lib/Pinpoint/Plugins/Common/PinTrace.php | 26 +- .../Plugins/Common/PluginsDefines.php | 87 --- lib/Pinpoint/Plugins/Common/Trace.php | 36 +- lib/Pinpoint/Plugins/Common/defines.php | 91 +++ .../{AutoGen => }/GuzzleHttp/GuzzlePlugin.php | 0 .../{AutoGen => }/MongoPlugin/MongoPlugin.php | 0 .../Plugins/PinpointPerRequestPlugins.php | 6 +- .../Plugins/Yii2PerRequestPlugins.php | 47 +- lib/Pinpoint/Plugins/__init__.php | 25 +- .../Yii2 => yii2}/ConnectionPlugin.php | 19 +- lib/Pinpoint/Plugins/yii2/UrlRule.php | 7 +- lib/Pinpoint/test/Bear.php | 30 +- .../test/Comparison/Pinpoint/test/Bear.php | 100 +++- .../Comparison/Pinpoint/test/ProxyBear.php | 60 -- lib/Pinpoint/test/OriginFileVisitor_test.php | 13 +- lib/Pinpoint/test/OutputMonitor.php | 7 + lib/Pinpoint/test/OutputMonitorNoReturn.php | 20 + lib/Pinpoint/test/bearRun.php | 34 ++ lib/Pinpoint/test/php_parse.php | 2 +- test.php | 70 --- 41 files changed, 909 insertions(+), 1194 deletions(-) create mode 100644 lib/Pinpoint/Common/ClassLoaderFactory.php delete mode 100644 lib/Pinpoint/Common/GenOriginClassTemplateHelper.php rename lib/Pinpoint/Common/{RenderAopClass.php => MonitorClass.php} (68%) create mode 100644 lib/Pinpoint/Common/MonitorClassLoader.php rename lib/Pinpoint/Common/{PerRequest.php => PerRequestDefault.php} (71%) delete mode 100644 lib/Pinpoint/Common/RenderAopClassLoader.php create mode 100644 lib/Pinpoint/Common/StanderClassLoader.php rename lib/Pinpoint/Common/{UserClassLoaderInterface.php => UserFindClassLoader.php} (59%) rename lib/Pinpoint/Common/{JoinClassInterface.php => UserFrameworkInterface.php} (88%) delete mode 100644 lib/Pinpoint/Common/VendorAdaptorClassLoader.php create mode 100644 lib/Pinpoint/Common/VendorClassLoaderAdaptor.php delete mode 100644 lib/Pinpoint/Plugins/Common/PluginsDefines.php create mode 100644 lib/Pinpoint/Plugins/Common/defines.php rename lib/Pinpoint/Plugins/{AutoGen => }/GuzzleHttp/GuzzlePlugin.php (100%) rename lib/Pinpoint/Plugins/{AutoGen => }/MongoPlugin/MongoPlugin.php (100%) rename lib/Pinpoint/Plugins/{AutoGen/Yii2 => yii2}/ConnectionPlugin.php (86%) delete mode 100644 lib/Pinpoint/test/Comparison/Pinpoint/test/ProxyBear.php create mode 100644 lib/Pinpoint/test/OutputMonitorNoReturn.php create mode 100644 lib/Pinpoint/test/bearRun.php delete mode 100644 test.php diff --git a/.gitignore b/.gitignore index 30bc0fb..87ed5ae 100644 --- a/.gitignore +++ b/.gitignore @@ -2,11 +2,11 @@ composer.phar /vendor/ .idea/ composer.lock -lib/pinpoint/test/Cache/ +lib/pinpoint/test/Cache/* lib/pinpoint/test/test.php *.ast # Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control # You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file # composer.lock -lib/Pinpoint/test/Cache/Pinpoint/test/*.php +test*.php \ No newline at end of file diff --git a/auto_pinpointed.php b/auto_pinpointed.php index 140ef39..98446e5 100644 --- a/auto_pinpointed.php +++ b/auto_pinpointed.php @@ -22,5 +22,4 @@ use Pinpoint\Common\PinpointDriver; -define('CLASS_PREFIX', 'Proxied_'); PinpointDriver::getInstance()->start(); diff --git a/lib/Pinpoint/Common/AbstractClassFile.php b/lib/Pinpoint/Common/AbstractClassFile.php index fd1a109..8d2defa 100644 --- a/lib/Pinpoint/Common/AbstractClassFile.php +++ b/lib/Pinpoint/Common/AbstractClassFile.php @@ -45,8 +45,6 @@ abstract class AbstractClassFile public $newAstNode; - protected $newNamePrefix; - public $npStr; public $className = ''; /// Foo\A Foo\B @@ -65,15 +63,13 @@ abstract class AbstractClassFile public $hasRet; - public $fileNode; protected $_astPrinter; public $namespace = ''; - public function __construct($_newNamePrefix) + public function __construct() { - $this->newNamePrefix = $_newNamePrefix; $this->_astPrinter = new PrettyPrinter\Standard(); } @@ -131,7 +127,7 @@ public function done() { $fullPath = AOP_CACHE_DIR . '/' . str_replace('\\', '/', $this->className) . '.php'; $context = $this->_astPrinter->prettyPrintFile($this->newAstNode); - RenderAopClass::getInstance()->insertMapping($this->className, $fullPath); + MonitorClass::getInstance()->insertMapping($this->className, $fullPath); Logger::Inst()->debug("map/save new class '$this->className' to '$fullPath' "); Utils::saveObj($context, $fullPath); } @@ -139,7 +135,6 @@ public function done() abstract function handleAfterTraverse($nodes); abstract function handleLeaveNamespace($nodes); abstract function handlerUseNode($node); - abstract function handleMagicConstNode($node); abstract function handleLeaveMethodNode($node); abstract function handleEnterClassConstFetch($node); abstract function handleEnterNew($node); diff --git a/lib/Pinpoint/Common/AbstractMonitor.php b/lib/Pinpoint/Common/AbstractMonitor.php index a3a5d7f..5ee9d11 100644 --- a/lib/Pinpoint/Common/AbstractMonitor.php +++ b/lib/Pinpoint/Common/AbstractMonitor.php @@ -24,11 +24,11 @@ abstract class AbstractMonitor protected $monitor_name; protected $who; protected $args; - public function __construct($name, $who, &...$args) + public function __construct($name, $who, ...$args) { $this->monitor_name = $name; $this->who = $who; - $this->args = &$args; + $this->args = $args; } abstract function onBefore(); diff --git a/lib/Pinpoint/Common/ClassLoaderFactory.php b/lib/Pinpoint/Common/ClassLoaderFactory.php new file mode 100644 index 0000000..a90036c --- /dev/null +++ b/lib/Pinpoint/Common/ClassLoaderFactory.php @@ -0,0 +1,45 @@ +_userFindClass = $userFindClass; + } + + public function createLoader(&$originLoader): StanderClassLoader + { + $loaderClass = $originLoader[0]; + + if (is_a($loaderClass, ClassLoader::class)) + return new StanderClassLoader($originLoader); + + return new UserFindClassLoader($originLoader, $this->_userFindClass); + } +} diff --git a/lib/Pinpoint/Common/CodeVisitor.php b/lib/Pinpoint/Common/CodeVisitor.php index cc7a258..575d56f 100644 --- a/lib/Pinpoint/Common/CodeVisitor.php +++ b/lib/Pinpoint/Common/CodeVisitor.php @@ -104,10 +104,6 @@ public function leaveNode(Node $node) foreach ($this->visitors as $visitor) { $visitor->handleLeaveMethodNode($node); } - } elseif ($node instanceof Node\Scalar\MagicConst) { - foreach ($this->visitors as $visitor) { - $visitor->handleMagicConstNode($node); - } } elseif ($node instanceof Node\Stmt\Namespace_) { foreach ($this->visitors as $visitor) { $visitor->handleLeaveNamespace($node); diff --git a/lib/Pinpoint/Common/GenOriginClassTemplateHelper.php b/lib/Pinpoint/Common/GenOriginClassTemplateHelper.php deleted file mode 100644 index 6641d6f..0000000 --- a/lib/Pinpoint/Common/GenOriginClassTemplateHelper.php +++ /dev/null @@ -1,294 +0,0 @@ -aspClassName); - - $this->originClassFileDir = dirname($path); - $this->originClassFilePath = $path; - // $this->classHandler = $classHandler; - $this->classAliasSet = $classHandler->classAlias; - $this->funcAlias = $classHandler->funcAlias; - $this->methodJoint = $classHandler->methodJoinPoints; - } - - private function getRealNp($node) - { - - if ($node instanceof Node\Name\FullyQualified) // Use directly access - { - return $node->toString(); - } elseif ($node instanceof Node\Expr\Variable) { //#16 support new a variable - return $node->name; - } elseif ($node instanceof Node\Name) { // Use namespace suggestion - $prefixNm = $node->getFirst(); - if (isset($this->suffix_use[$prefixNm])) { - $namePrefix = $this->suffix_use[$prefixNm]; - $nm = $namePrefix . "\\" . $node->toString(); - return $nm; - } else { - return $node->toString(); - } - } - } - - - public function renderClassName($node, $filer) - { - $classFullName = $this->getRealNp($node); - - if (isset($filer[$classFullName])) { - $newName = $filer[$classFullName]; - return new Node\Name\FullyQualified($newName); - } - return $node; - } - - public function renderFunName(&$node, $filer) - { - $classFullName = $node->toString(); - if (isset($filer[$classFullName])) { - $newName = $filer[$classFullName]; - return new Node\Name\FullyQualified($newName); - } - return $node; - } - - public function handleEnterFuncCall($node) - { - assert($node instanceof Node\Expr\FuncCall); - if ($node->name instanceof Node\Expr\Variable) { - // not support anonymous function - } else { - $node->name = $this->renderFunName($node->name, $this->funcAlias); - } - return $node; - } - - - public function handleEnterNew($node) - { - assert($node instanceof Node\Expr\New_); - $node->class = $this->renderClassName($node->class, $this->classAliasSet); - return $node; - } - - public function handleEnterClassConstFetch($node) - { - assert($node instanceof Node\Expr\ClassConstFetch); - $node->class = $this->renderClassName($node->class, $this->classAliasSet); - return $node; - } - - - /** rename the class Proxied_foo - * @param $node - */ - public function handleLeaveClassNode($node) - { - assert($node instanceof Node\Stmt\Class_); - $className = $this->newNamePrefix . $node->name->toString(); - - $node->name = new Node\Identifier($className); - - $this->className = empty($this->namespace) ? ($className) : $this->namespace . '\\' . $className; - $this->myLoaderName = $this->className; - - if ($node->flags & Node\Stmt\Class_::MODIFIER_FINAL) { - /// remove FINAL flag - $node->flags = $node->flags & (~(Node\Stmt\Class_::MODIFIER_FINAL)); - } - } - - /** - * rename trait Foo{} => trait Proxy_Foo{} - * @param $node - */ - public function handleLeaveTraitNode(&$node) - { - assert($node instanceof Node\Stmt\Trait_); - $className = $this->newNamePrefix . $node->name->toString(); - - $node->name = new Node\Identifier($className); - - $this->traitName = empty($this->namespace) ? ($className) : ($this->namespace . '\\' . $className); - $this->myLoaderName = $this->traitName; - } - - - public function handleLeaveMethodNode($node) - { - $func = trim($node->name->toString()); - if (!array_key_exists($func, $this->methodJoint)) { - return; - } - - assert($node instanceof Node\Stmt\ClassMethod); - if ($node->flags & Node\Stmt\Class_::MODIFIER_PRIVATE) { - // unset private - $node->flags = $node->flags & (~Node\Stmt\Class_::MODIFIER_PRIVATE); - - // set protect - $node->flags = $node->flags | (Node\Stmt\Class_::MODIFIER_PROTECTED); - } - - if ($node->flags & Node\Stmt\Class_::MODIFIER_FINAL) { - $node->flags = $node->flags & (~Node\Stmt\Class_::MODIFIER_FINAL); - } - } - - /** - * @obsoleted - * convert \Exception to Exception - * try to use namespace cover - * @param $node - * @return Node\Name - */ - public function handleFullyQualifiedNode(&$node) - { - assert($node instanceof Node\Name\FullyQualified); - $name = $node->toString(); - if (isset($this->classAliasSet[$name])) { - return new Node\Name\FullyQualified($this->classAliasSet[$name]); - } else { - return $node; - } - } - - public function handleMagicConstNode($node) - { - switch ($node->getName()) { - case '__FILE__': - return new Node\Scalar\String_($this->originClassFilePath); - case '__DIR__': - return new Node\Scalar\String_($this->originClassFileDir); - case '__FUNCTION__': - return new Node\Scalar\String_($this->classMethod); - case '__CLASS__': - return new Node\Scalar\String_($this->className); - case '__METHOD__': - return new Node\Scalar\String_($this->classMethod); - case '__NAMESPACE__': - return new Node\Scalar\String_($this->namespace); - case '__LINE__': - return new Node\Scalar\LNumber($node->getAttribute('startLine')); - default: - break; - } - return $node; - } - - - public function handleLeaveNamespace($nodes) - { - return $nodes; - } - - - function handlerUseUseNode(&$node) - { - assert($node instanceof Node\Stmt\UseUse); - - // parse use A\B\C as ABC; - // here , A\B\C is hidden by ABC - // so re-add ABC - if ($node->alias) { - $namespaceAlias = $node->alias->name; - $hiddenClassAlias = []; - $newName = trim($node->name->toString(), "\ \\"); - foreach ($this->classAliasSet as $clName => $classAlias) { - if (strpos($clName, $newName) === 0) { - $classNewName = str_replace($newName, $namespaceAlias, $clName); - $hiddenClassAlias[$classNewName] = $classAlias; - } - } - if (!empty($hiddenClassAlias)) { - Logger::Inst()->debug("found hiddenClassAlias:'$hiddenClassAlias'"); - $this->classAliasSet += $hiddenClassAlias; - } - return; - } - - // parse use A/B/C, but the nm_ is A/B/C/D - $suffixNm = $node->name->getLast(); - if (!$node->name->isUnqualified()) { - $this->suffix_use[$suffixNm] = $node->name->slice(0, -1)->toString(); - } - } - - function handleAfterTraverse($nodes) - { - $this->newAstNode = $nodes; - } - - function handlerUseNode($node) - { - //rename the nodes - assert($node instanceof Node\Stmt\Use_); - $type = $node->type; - if ($type == Node\Stmt\Use_::TYPE_CONSTANT) { - return; - } - - // replace the exactly match - // use A/B/C; -> Plugins/A/B/C - foreach ($node->uses as &$uses) { - $fullName = trim($uses->name->toString(), "\ \\"); - - if ($type == Node\Stmt\Use_::TYPE_FUNCTION) { - // use function Math\{add, subtract}; - if (array_key_exists($fullName, $this->funcAlias)) { - $newName = new Node\Name($this->funcAlias[$fullName]); - $uses->name = $newName; - Logger::Inst()->debug("found funcAlias:'$fullName' -> '$this->funcAlias[$fullName]' "); - } - } else { - // use ABC\Math; - if (array_key_exists($fullName, $this->classAliasSet)) { - $newName = new Node\Name($this->classAliasSet[$fullName]); - $uses->name = $newName; - Logger::Inst()->debug("found classAlias:'$fullName' -> '$this->classAliasSet[$fullName]' "); - } - } - } - } -} diff --git a/lib/Pinpoint/Common/GenProxyClassTemplateHelper.php b/lib/Pinpoint/Common/GenProxyClassTemplateHelper.php index c3c7a66..8228710 100644 --- a/lib/Pinpoint/Common/GenProxyClassTemplateHelper.php +++ b/lib/Pinpoint/Common/GenProxyClassTemplateHelper.php @@ -28,30 +28,32 @@ use Pinpoint\Common\AbstractClassFile; use PhpParser\BuilderFactory; use PhpParser\Node; -use Pinpoint\Common\PluginParser; + +const _originNamePrefix_ = "__pinpoint__"; class GenProxyClassTemplateHelper extends AbstractClassFile { - private $factory; - - private $mClassNode = null; // class { } - private $mTraitNode = null; - - private $extendTraitName; - + private BuilderFactory $factory; private $useBlockAr = []; - - private $trailUseAsArray = []; - private $handleLeaveMethodCb = []; - private $handleEndTraverseCb = []; public $methodJoinPoints = []; + private $newMethodsStmts = []; - public function __construct(AspectClassHandle $classHandler, $prefix) + protected $originClassFileDir; + protected $originClassFilePath; + protected $suffix_use = []; + protected $classAliasSet = []; + protected $funcAlias = []; + protected $methodJoint; + + public function __construct(AspectClassHandle $classHandler) { - parent::__construct($prefix); + parent::__construct(); $this->factory = new BuilderFactory(); $this->methodJoinPoints = $classHandler->methodJoinPoints; + $this->classAliasSet = $classHandler->classAlias; + $this->funcAlias = $classHandler->funcAlias; + $this->methodJoint = $classHandler->methodJoinPoints; } @@ -60,43 +62,79 @@ public function handleEnterNamespaceNode($node) parent::handleEnterNamespaceNode($node); } - public function handleEnterClassNode($node) + private function getRealNp($node) { - assert($node instanceof Node\Stmt\Class_); - parent::handleEnterClassNode($node); - $extendClass = $this->newNamePrefix . $node->name->toString(); - $this->mClassNode = $this->factory->class(trim($node->name->toString()))->extend($extendClass); - if (!empty($this->namespace)) { - // if the proxy_class has namespace, add into use - // if not, just ignore it . support for yii1 - $fullName = $this->namespace . '\\' . $extendClass; - $this->useBlockAr[] = array($fullName, null); + if ($node instanceof Node\Name\FullyQualified) // Use directly access + { + return $node->toString(); + } elseif ($node instanceof Node\Expr\Variable) { //#16 support new a variable + return $node->name; + } elseif ($node instanceof Node\Name) { // Use namespace suggestion + $prefixNm = $node->getFirst(); + if (isset($this->suffix_use[$prefixNm])) { + $namePrefix = $this->suffix_use[$prefixNm]; + $nm = $namePrefix . "\\" . $node->toString(); + return $nm; + } else { + return $node->toString(); + } } + } + + private function renderClassName($node, $filer) + { + $classFullName = $this->getRealNp($node); + + if (isset($filer[$classFullName])) { + $methodNewName = $filer[$classFullName]; + return new Node\Name\FullyQualified($methodNewName); + } + return $node; + } + + public function handleEnterNew($node) + { + assert($node instanceof Node\Expr\New_); + $node->class = $this->renderClassName($node->class, $this->classAliasSet); + return $node; + } + + public function handleEnterClassConstFetch($node) + { + assert($node instanceof Node\Expr\ClassConstFetch); + $node->class = $this->renderClassName($node->class, $this->classAliasSet); + return $node; + } - switch ($node->flags) { - case Node\Stmt\Class_::MODIFIER_FINAL: - $this->mClassNode->makeFinal(); - break; - case Node\Stmt\Class_::MODIFIER_ABSTRACT: - $this->mClassNode->makeAbstract(); - break; - default: - break; + public function handleEnterFuncCall($node) + { + assert($node instanceof Node\Expr\FuncCall); + if ($node->name instanceof Node\Expr\Variable) { + // not support anonymous function + } else { + $node->name = $this->renderFunName($node->name, $this->funcAlias); } + return $node; + } + + + public function handleEnterClassNode($node) + { + assert($node instanceof Node\Stmt\Class_); + parent::handleEnterClassNode($node); $this->handleLeaveMethodCb = array($this, 'handleClassLeaveMethodNode'); - $this->handleEndTraverseCb = array($this, 'handleAfterTraverseClass'); } public function handleEnterTraitNode(&$node) { assert($node instanceof Node\Stmt\Trait_); - parent::handleEnterTraitNode($node); - $this->mTraitNode = $this->factory->trait(trim($node->name->toString())); - $this->extendTraitName = $this->newNamePrefix . $node->name->toString(); - $this->handleLeaveMethodCb = array($this, 'handleTraitLeaveMethodNode'); - $this->handleEndTraverseCb = array($this, 'handleAfterTraverseTrait'); + // parent::handleEnterTraitNode($node); + // $this->mTraitNode = $this->factory->trait(trim($node->name->toString())); + // $this->extendTraitName = $this->newNamePrefix . $node->name->toString(); + // $this->handleLeaveMethodCb = array($this, 'handleTraitLeaveMethodNode'); + // $this->handleEndTraverseCb = array($this, 'handleAfterTraverseTrait'); } public static function convertParamsName2Arg($params) @@ -120,36 +158,47 @@ public function handleClassLeaveMethodNode($node, $monitorClassFullName) // 1. make a new method overriding parent's $originMethodName = $node->name->toString(); + $newMethodName = $this->methodNewName($originMethodName); + $node->name = new Node\Name\FullyQualified($newMethodName); + Logger::Inst()->debug("generate pinpoint code block for '$originMethodName'"); $funcVar = new Node\Arg(new Node\Scalar\MagicConst\Method()); - $thisMethod = $this->factory->method($originMethodName); + $jointMethod = $this->factory->method($originMethodName); + $docComments = <<setDocComment($docComments); // 1.1 public/protect/private/ if ($node->flags & Node\Stmt\Class_::MODIFIER_PUBLIC) { - $thisMethod->makePublic(); + $jointMethod->makePublic(); } if ($node->flags & Node\Stmt\Class_::MODIFIER_PRIVATE) { - Logger::Inst()->debug("'$originMethodName' is a private, changes to protected"); - $thisMethod->makeProtected(); + Logger::Inst()->debug("'$originMethodName' is a private"); + $jointMethod->makePrivate(); } if ($node->flags & Node\Stmt\Class_::MODIFIER_ABSTRACT) { - $thisMethod->makeAbstract(); + $jointMethod->makeAbstract(); } if ($node->flags & Node\Stmt\Class_::MODIFIER_FINAL) { - $thisMethod->makeFinal(); + $jointMethod->makeFinal(); } if ($node->flags & Node\Stmt\Class_::MODIFIER_PROTECTED) { - $thisMethod->makeProtected(); + $jointMethod->makeProtected(); } //1.2 gen $this-> + $isStatic = false; if ($node->flags & Node\Stmt\Class_::MODIFIER_STATIC) { - $thisMethod->makeStatic(); + $isStatic = true; + $jointMethod->makeStatic(); $selfVar = new Node\Arg(new Node\Expr\ConstFetch(new Node\Name('null'))); Logger::Inst()->debug("'$originMethodName' is a static function"); } else { @@ -158,9 +207,9 @@ public function handleClassLeaveMethodNode($node, $monitorClassFullName) $methodParams = array_merge([$funcVar, $selfVar], GenProxyClassTemplateHelper::convertParamsName2Arg($node->params)); - $thisMethod->addParams($node->params); + $jointMethod->addParams($node->params); if ($node->returnType) { - $thisMethod->setReturnType($node->returnType); + $jointMethod->setReturnType($node->returnType); } $varName = '_pinpoint_' . $originMethodName . '_var'; @@ -172,13 +221,13 @@ public function handleClassLeaveMethodNode($node, $monitorClassFullName) $this->factory->new(new Node\Name\FullyQualified($monitorClassFullName), $methodParams) )); - $thisMethod->addStmt($newPluginsStm); + $jointMethod->addStmt($newPluginsStm); // $var = null; $newVar = new Node\Stmt\Expression(new Node\Expr\Assign( new Node\Expr\Variable($retName), new Node\Expr\ConstFetch(new Node\Name('null')) )); - $thisMethod->addStmt($newVar); + $jointMethod->addStmt($newVar); $tryBlock = []; $catchNode = []; @@ -190,15 +239,28 @@ public function handleClassLeaveMethodNode($node, $monitorClassFullName) if ($this->hasRet) { Logger::Inst()->debug("'$originMethodName' has return value "); - /// $ret = paraent::$originMethodName(); - $tryBlock[] = new Node\Stmt\Expression(new Node\Expr\Assign( - new Node\Expr\Variable($retName), - new Node\Expr\StaticCall( - new Node\Name("parent"), - new Node\Identifier($originMethodName), - GenProxyClassTemplateHelper::convertParamsName2Arg($node->params) - ) - )); + + if ($isStatic) { + /// $ret = self::newMethodName(); + $tryBlock[] = new Node\Stmt\Expression(new Node\Expr\Assign( + new Node\Expr\Variable($retName), + new Node\Expr\StaticCall( + new Node\Name("self"), + new Node\Identifier($newMethodName), + GenProxyClassTemplateHelper::convertParamsName2Arg($node->params) + ) + )); + } else { + /// $ret = $this->$newMethodName(); + $tryBlock[] = new Node\Stmt\Expression(new Node\Expr\Assign( + new Node\Expr\Variable($retName), + new Node\Expr\MethodCall( + new Node\Expr\Variable("this"), + new Node\Identifier($newMethodName), + GenProxyClassTemplateHelper::convertParamsName2Arg($node->params) + ) + )); + } /// $var->onEnd($ret); $tryBlock[] = new Node\Stmt\Expression( @@ -214,11 +276,25 @@ public function handleClassLeaveMethodNode($node, $monitorClassFullName) } else { /// paraent::$originMethodName(); - $tryBlock[] = new Node\Stmt\Expression($this->factory->staticCall( - new Node\Name("parent"), - new Node\Identifier($originMethodName), - GenProxyClassTemplateHelper::convertParamsName2Arg($node->params) - )); + if ($isStatic) { + /// $ret = self::newMethodName(); + $tryBlock[] = new Node\Stmt\Expression( + new Node\Expr\StaticCall( + new Node\Name("self"), + new Node\Identifier($newMethodName), + GenProxyClassTemplateHelper::convertParamsName2Arg($node->params) + ) + ); + } else { + /// $ret = $this->$newMethodName(); + $tryBlock[] = new Node\Stmt\Expression( + new Node\Expr\MethodCall( + new Node\Expr\Variable("this"), + new Node\Identifier($newMethodName), + GenProxyClassTemplateHelper::convertParamsName2Arg($node->params) + ) + ); + } /// $var->onEnd($ret); $tryBlock[] = new Node\Stmt\Expression( @@ -252,9 +328,9 @@ public function handleClassLeaveMethodNode($node, $monitorClassFullName) $tryCatchFinallyNode = new Node\Stmt\TryCatch($tryBlock, $catchNode); - $thisMethod->addStmt($tryCatchFinallyNode); + $jointMethod->addStmt($tryCatchFinallyNode); - $this->mClassNode->addStmt($thisMethod); + $this->newMethodsStmts[] = $jointMethod->getNode(); } public static function itemInArray($ar, $v) @@ -268,175 +344,16 @@ public static function itemInArray($ar, $v) return !empty($new); } - public function handleTraitLeaveMethodNode($node, $info) + private function methodNewName($olderName): string { - /// todo this methodName looks ugly - - /// - check use , add use Proxied_Foo { } - /// - insert alias use Proxied_Foo::xxx as Foo_xxxx - /// - new function xxxx - - assert($node instanceof Node\Stmt\ClassMethod); - - list($mode, $namespace, $className) = $info; - - // foo_1 - $originMethodName = $node->name->toString(); - - $np = empty($namespace) ? $className : $namespace . '\\' . $className; - $np_ar = [$np, null]; - // use CommonPlugins\Plugins; - if (!static::itemInArray($this->useBlockAr, $np_ar)) { - $this->useBlockAr[] = $np_ar; - } - - // $this->extendTraitName::$originMethodName as $this->extendTraitName_$originMethodName; - $this->trailUseAsArray[] = $originMethodName; - $extendMethodName = $this->extendTraitName . '_' . $originMethodName; - - - $funcVar = new Node\Arg(new Node\Scalar\MagicConst\Method()); - - // public function funcName(){} - $thisMethod = $this->factory->method($originMethodName); - - if ($node->flags & Node\Stmt\Class_::MODIFIER_PUBLIC) { - $thisMethod->makePublic(); - } - - if ($node->flags & Node\Stmt\Class_::MODIFIER_PRIVATE) { - $thisMethod->makePrivate(); - } - - if ($node->flags & Node\Stmt\Class_::MODIFIER_ABSTRACT) { - - $thisMethod->makeAbstract(); - } - - if ($node->flags & Node\Stmt\Class_::MODIFIER_FINAL) { - $thisMethod->makeFinal(); - } - - if ($node->flags & Node\Stmt\Class_::MODIFIER_PROTECTED) { - $thisMethod->makeProtected(); - } - - if ($node->flags & Node\Stmt\Class_::MODIFIER_STATIC) { - $thisMethod->makeStatic(); - $selfVar = new Node\Arg(new Node\Expr\ConstFetch(new Node\Name('null'))); - } else { - $selfVar = new Node\Arg(new Node\Expr\Variable('this')); - } - - $methodParams = array_merge([$funcVar, $selfVar], GenProxyClassTemplateHelper::convertParamsName2Arg($node->params)); - - $thisMethod->addParams($node->params); - if ($node->returnType) { - $thisMethod->setReturnType($node->returnType); - } - - $varName = $className . '_' . $originMethodName . '_var'; - $retName = $className . '_' . $originMethodName . '_ret'; - - /// $var = new CommonPlugins(__FUNCTION__,self,$p); - $newPluginsStm = new Node\Stmt\Expression(new Node\Expr\Assign( - new Node\Expr\Variable($varName), - $this->factory->new($className, $methodParams) - )); - - $thisMethod->addStmt($newPluginsStm); - // $var = null; - $newVar = new Node\Stmt\Expression(new Node\Expr\Assign( - new Node\Expr\Variable($retName), - new Node\Expr\ConstFetch(new Node\Name('null')) - )); - $thisMethod->addStmt($newVar); - - $tryBlock = []; - $catchNode = []; - - // $plugin->onBefore(); - $tryBlock[] = new Node\Stmt\Expression( - $this->factory->methodCall(new Node\Expr\Variable($varName), "onBefore") - ); - - if ($this->hasRet) { - /// $ret = $this->method(&...$args); - $tryBlock[] = new Node\Stmt\Expression(new Node\Expr\Assign( - new Node\Expr\Variable($retName), - new Node\Expr\MethodCall( - new Node\Expr\Variable("this"), - new Node\Identifier($extendMethodName), - GenProxyClassTemplateHelper::convertParamsName2Arg($node->params) - ) - )); - - /// $var->onEnd($ret); - if ($mode & PluginParser::END) { - $tryBlock[] = new Node\Stmt\Expression( - $this->factory->methodCall( - new Node\Expr\Variable($varName), - "onEnd", - [new Node\Expr\Variable($retName)] - ) - ); - } - - /// return $var; - $tryBlock[] = new Node\Stmt\Return_(new Node\Expr\Variable($retName)); - } else { - /// $this->>$originMethodName(); - $tryBlock[] = new Node\Stmt\Expression(new Node\Expr\MethodCall( - new Node\Expr\Variable("this"), - new Node\Identifier($extendMethodName), - GenProxyClassTemplateHelper::convertParamsName2Arg($node->params) - )); - - /// $var->onEnd($ret); - if ($mode & PluginParser::END) { - $tryBlock[] = new Node\Stmt\Expression( - $this->factory->methodCall( - new Node\Expr\Variable($varName), - "onEnd", - [new Node\Expr\Variable($retName)] - ) - ); - } - } - - $expArgs = []; - $expArgs[] = new Node\Arg(new Node\Expr\Variable('e')); - - if ($mode & PluginParser::EXCEPTION) { - - $catchBlock[] = new Node\Stmt\Expression( - $this->factory->methodCall( - new Node\Expr\Variable($varName), - "onException", - $expArgs - ) - ); - } - - $catchBlock[] = new Node\Stmt\Throw_(new Node\Expr\Variable("e")); - - $catchNode[] = new Node\Stmt\Catch_( - [new Node\Name('\Exception')], - new Node\Expr\Variable('e'), - $catchBlock - ); - - $tryCatchFinallyNode = new Node\Stmt\TryCatch($tryBlock, $catchNode); - - $thisMethod->addStmt($tryCatchFinallyNode); - - $this->mTraitNode->addStmt($thisMethod); + return _originNamePrefix_ . $olderName; } public function handleLeaveMethodNode($node) { $methodName = trim($node->name->toString()); if (array_key_exists($methodName, $this->methodJoinPoints)) { + // rename method name call_user_func_array( $this->handleLeaveMethodCb, [ @@ -447,86 +364,46 @@ public function handleLeaveMethodNode($node) } } - public function handleAfterTraverseClass() + public function renderFunName(&$node, $filer) { - $useNodes = []; - $this->fileName = $this->className; - - $this->useBlockArToNodes($useNodes); - if (!empty($this->namespace)) { - $this->fileNode = $this->factory->namespace($this->namespace); - if (count($useNodes) > 0) { - $this->fileNode->addStmts($useNodes); - } - $this->fileNode->addStmt($this->mClassNode); - return array($this->fileNode->getNode()); - } else { - $this->fileNode = []; //$this->factory->namespace($this->namespace); - foreach ($useNodes as $node) { - $this->fileNode[] = $node->getNode(); - } - $this->fileNode[] = $this->mClassNode->getNode(); - return $this->fileNode; + $classFullName = $node->toString(); + if (isset($filer[$classFullName])) { + $methodNewName = $filer[$classFullName]; + return new Node\Name\FullyQualified($methodNewName); } + return $node; } - private function useBlockArToNodes(&$stmNode) - { - - foreach ($this->useBlockAr as $var) { - - if (isset($var[1])) { // the second must be alias : use class as foo - $node = $this->factory->use($var[0])->as($var[1]); - } else { //== 1 - $node = $this->factory->use($var[0]); - } - $stmNode[] = $node; - } - } - - public function handleAfterTraverseTrait() + /** rename the class Proxied_foo + * @param $node + */ + public function handleLeaveClassNode($node) { - $useNodes = []; - $this->useBlockArToNodes($useNodes); - - // use Proxied_Foo{} - $useTraitNode = $this->factory->useTrait($this->extendTraitName); - - foreach ($this->trailUseAsArray as $alias) { - // $extendMethodName::thisfuncName as $this->extendTraitName.'_'.$originMethodName; - $useTraitNode->with($this->factory->traitUseAdaptation($this->extendTraitName, $alias)->as($this->extendTraitName . '_' . $alias)); - } - - $this->mTraitNode->addStmt($useTraitNode); - // todo does need to handle trait without any namespace - $this->fileNode = $this->factory->namespace($this->namespace) - ->addStmts($useNodes) - ->addStmt($this->mTraitNode); - - $this->fileName = $this->traitName; - - return array($this->fileNode->getNode()); + assert($node instanceof Node\Stmt\Class_); + array_push($node->stmts, ...$this->newMethodsStmts); } public function handleAfterTraverse($nodes) { - $this->newAstNode = call_user_func_array($this->handleEndTraverseCb, []); + $this->newAstNode = $nodes; } - function handleLeaveNamespace($nodes) + public function handleLeaveNamespace($nodes) { - // do nothing + return $nodes; } - function handleEnterClassConstFetch($node) - { - } - function handleEnterNew($node) - { - } - function handleEnterFuncCall($node) + + public function handleFullyQualifiedNode(&$node) { + assert($node instanceof Node\Name\FullyQualified); + $name = $node->toString(); + if (isset($this->classAliasSet[$name])) { + return new Node\Name\FullyQualified($this->classAliasSet[$name]); + } else { + return $node; + } } function handlerUseNode($node) @@ -535,14 +412,66 @@ function handlerUseNode($node) foreach ($node->uses as $uses) { $this->useBlockAr[] = array($uses->name->toString(), $uses->alias ? $uses->alias->name : null); } - } + //rename the nodes + assert($node instanceof Node\Stmt\Use_); + $type = $node->type; + if ($type == Node\Stmt\Use_::TYPE_CONSTANT) { + return; + } - function handleMagicConstNode($node) - { + // replace the exactly match + // use A/B/C; -> Plugins/A/B/C + foreach ($node->uses as &$uses) { + $fullName = trim($uses->name->toString(), "\ \\"); + + if ($type == Node\Stmt\Use_::TYPE_FUNCTION) { + // use function Math\{add, subtract}; + if (array_key_exists($fullName, $this->funcAlias)) { + $methodNewName = new Node\Name($this->funcAlias[$fullName]); + $uses->name = $methodNewName; + Logger::Inst()->debug("found funcAlias:'$fullName' -> '$this->funcAlias[$fullName]' "); + } + } else { + // use ABC\Math; + if (array_key_exists($fullName, $this->classAliasSet)) { + $methodNewName = new Node\Name($this->classAliasSet[$fullName]); + $uses->name = $methodNewName; + Logger::Inst()->debug("found classAlias:'$fullName' -> '$this->classAliasSet[$fullName]' "); + } + } + } } - function handleLeaveClassNode($node) + + function handlerUseUseNode(&$node) { + assert($node instanceof Node\Stmt\UseUse); + + // parse use A\B\C as ABC; + // here , A\B\C is hidden by ABC + // so re-add ABC + if ($node->alias) { + $namespaceAlias = $node->alias->name; + $hiddenClassAlias = []; + $methodNewName = trim($node->name->toString(), "\ \\"); + foreach ($this->classAliasSet as $clName => $classAlias) { + if (strpos($clName, $methodNewName) === 0) { + $classNewName = str_replace($methodNewName, $namespaceAlias, $clName); + $hiddenClassAlias[$classNewName] = $classAlias; + } + } + if (!empty($hiddenClassAlias)) { + Logger::Inst()->debug("found hiddenClassAlias:'$hiddenClassAlias'"); + $this->classAliasSet += $hiddenClassAlias; + } + return; + } + + // parse use A/B/C, but the nm_ is A/B/C/D + $suffixNm = $node->name->getLast(); + if (!$node->name->isUnqualified()) { + $this->suffix_use[$suffixNm] = $node->name->slice(0, -1)->toString(); + } } } diff --git a/lib/Pinpoint/Common/RenderAopClass.php b/lib/Pinpoint/Common/MonitorClass.php similarity index 68% rename from lib/Pinpoint/Common/RenderAopClass.php rename to lib/Pinpoint/Common/MonitorClass.php index 9227a32..679dab3 100644 --- a/lib/Pinpoint/Common/RenderAopClass.php +++ b/lib/Pinpoint/Common/MonitorClass.php @@ -20,7 +20,7 @@ namespace Pinpoint\Common; -class RenderAopClass +class MonitorClass { private static $_instance = null; @@ -30,14 +30,16 @@ private function __construct() { } - private $clsLoadUserFilterCB = null; + public function __destruct() + { + } - public static function getInstance(): RenderAopClass + public static function getInstance(): MonitorClass { if (self::$_instance) { return self::$_instance; } - self::$_instance = new RenderAopClass(); + self::$_instance = new MonitorClass(); return self::$_instance; } @@ -46,18 +48,11 @@ public function createFrom(array $clsMap) $this->classLoaderMap = $clsMap; } - public function findFile($classFullName): string + public function findFile(string $classFullName): string { - Logger::Inst()->debug("try to findFile:'$classFullName'"); - if (is_callable($this->clsLoadUserFilterCB)) { - if (call_user_func($this->clsLoadUserFilterCB, $classFullName) == true) { - return ''; - } - } - + Logger::Inst()->debug("try to loadclass '$classFullName'", [__CLASS__]); $classFile = $this->classLoaderMap[$classFullName]; if (isset($classFile)) { - Logger::Inst()->debug("findFile:'$classFullName' -> $classFile'"); return $classFile; } @@ -73,9 +68,4 @@ public function getJointClassMap(): array { return $this->classLoaderMap; } - - public function setUserFilter(callable $filter) - { - $this->clsLoadUserFilterCB = $filter; - } } diff --git a/lib/Pinpoint/Common/MonitorClassLoader.php b/lib/Pinpoint/Common/MonitorClassLoader.php new file mode 100644 index 0000000..04d90db --- /dev/null +++ b/lib/Pinpoint/Common/MonitorClassLoader.php @@ -0,0 +1,38 @@ +findFile($class); + if ($file != '') { + Logger::Inst()->debug("MonitorClassLoader::loadClass: '$file'", [__CLASS__]); + require $file; + return true; + } else { + return false; + } + } + /** + * spl_autoload_register MonitorClassLoader::loadClass + */ + public static function start() + { + if (!self::$registered) { + spl_autoload_register(self::$loader, true, true); + self::$registered = true; + Logger::Inst()->debug("register MonitorClassLoader"); + } + } +} diff --git a/lib/Pinpoint/Common/OriginFileVisitor.php b/lib/Pinpoint/Common/OriginFileVisitor.php index a20bd7f..45889b7 100644 --- a/lib/Pinpoint/Common/OriginFileVisitor.php +++ b/lib/Pinpoint/Common/OriginFileVisitor.php @@ -42,15 +42,15 @@ public function runAllVisitor(string $fullPath, AspectClassHandle $classHandler) private function getVisitor(AspectClassHandle $classHandler) { - $classPrefix = ""; + // $classPrefix = ""; $visitors = []; if (!empty($classHandler->getMethodJoinPoints())) { Logger::Inst()->debug("found methodJoinPoints "); - $classPrefix = CLASS_PREFIX; - $visitors[] = new GenProxyClassTemplateHelper($classHandler, $classPrefix); + // $classPrefix = CLASS_PREFIX; + $visitors[] = new GenProxyClassTemplateHelper($classHandler); } - $visitors[] = new GenOriginClassTemplateHelper($classHandler, $classPrefix); + // $visitors[] = new GenOriginClassTemplateHelper($classHandler, $classPrefix); $codeVisitor = new CodeVisitor($visitors); return $codeVisitor; } diff --git a/lib/Pinpoint/Common/PerRequest.php b/lib/Pinpoint/Common/PerRequestDefault.php similarity index 71% rename from lib/Pinpoint/Common/PerRequest.php rename to lib/Pinpoint/Common/PerRequestDefault.php index 9fd2c66..e235f9c 100644 --- a/lib/Pinpoint/Common/PerRequest.php +++ b/lib/Pinpoint/Common/PerRequestDefault.php @@ -22,16 +22,26 @@ use Monolog\Logger as mlogger; use Monolog\Handler\StreamHandler; -class PerRequestDefault implements JoinClassInterface +class PerRequestDefault implements UserFrameworkInterface { public function __construct() { - $log = new mlogger('name'); - $log->pushHandler(new StreamHandler('php://stdout', Logger::WARNING)); + $log = new mlogger('pp'); + $log->pushHandler(new StreamHandler('php://stdout', mlogger::DEBUG)); Logger::Inst()->setLogger($log); } public function joinedClassSet(): array { return []; } + + public function findClass($name): string + { + return ""; + } + + public function userFindClass(&$loader): callable + { + return [$this, 'findClass']; + } } diff --git a/lib/Pinpoint/Common/PinpointDriver.php b/lib/Pinpoint/Common/PinpointDriver.php index b24de56..cccb834 100644 --- a/lib/Pinpoint/Common/PinpointDriver.php +++ b/lib/Pinpoint/Common/PinpointDriver.php @@ -31,7 +31,7 @@ class PinpointDriver protected static $instance; protected $clAr = []; - private JoinClassInterface $reqInst; + private UserFrameworkInterface $reqInst; public static function getInstance() { @@ -46,7 +46,7 @@ final private function __construct() if (defined('PP_REQ_PLUGINS') && class_exists(PP_REQ_PLUGINS)) { $userPerRequestClass = PP_REQ_PLUGINS; $this->reqInst = new $userPerRequestClass(); - assert(is_a($this->reqInst, 'Pinpoint\Common\JoinClassInterface')); + assert(is_a($this->reqInst, 'Pinpoint\Common\UserFrameworkInterface')); } else { $this->reqInst = new PerRequestDefault(); } @@ -59,17 +59,15 @@ public function getRequestInst() public function start() { - RenderAopClass::getInstance(); - /// checking the cached file exist, if exist load it if (Utils::checkCacheReady()) { Logger::Inst()->debug("found cache"); - RenderAopClass::getInstance()->createFrom(Utils::loadCachedClass()); - VendorAdaptorClassLoader::enable(); - RenderAopClassLoader::start(); + MonitorClass::getInstance()->createFrom(Utils::loadCachedClass()); + MonitorClassLoader::start(); return; } - - VendorAdaptorClassLoader::enable(); + Logger::Inst()->debug("no found cache, try to generate joinclass"); + VendorClassLoaderAdaptor::Inst()->setUserFindClass($this->reqInst); + VendorClassLoaderAdaptor::Inst()->start(); $joinedClassSet = $this->reqInst->joinedClassSet(); if (empty($joinedClassSet)) { @@ -82,7 +80,7 @@ public function start() if (empty($fullClassName)) { continue; } - $fullPath = Utils::findFile($fullClassName); + $fullPath = VendorClassLoaderAdaptor::Inst()->findFileViaSpl($fullClassName); Logger::Inst()->debug("found aspectClass '$fullClassName' -> '$fullPath' "); // Please DO NOT CHEAT ME assert(file_exists($fullPath), "'$fullClassName' ->'$fullPath' must exist"); @@ -91,18 +89,8 @@ public function start() $visitor->runAllVisitor($fullPath, $aspClassHandler); } // save render aop class into index file - Utils::saveCachedClass(RenderAopClass::getInstance()->getJointClassMap()); + Utils::saveCachedClass(MonitorClass::getInstance()->getJointClassMap()); // enable RenderAop class loader - RenderAopClassLoader::start(); - } - - /** - * start /tail are the spl_autoload_functions checking order - * @param callable $start - * @param callable $tail - */ - public function addClassFinderHelper(callable $start, callable $tail) - { - Utils::addLoaderPatch($start, $tail); + // MonitorClassLoader::start(); } } diff --git a/lib/Pinpoint/Common/RenderAopClassLoader.php b/lib/Pinpoint/Common/RenderAopClassLoader.php deleted file mode 100644 index 07223b7..0000000 --- a/lib/Pinpoint/Common/RenderAopClassLoader.php +++ /dev/null @@ -1,28 +0,0 @@ -findFile($class); - if ($file != '') { - require $file; - return true; - } - } - - public static function start() - { - spl_autoload_register([__NAMESPACE__ . '\RenderAopClassLoader', 'loadClass'], true, true); - Logger::Inst()->debug("register RenderAopClassLoader"); - } -} diff --git a/lib/Pinpoint/Common/StanderClassLoader.php b/lib/Pinpoint/Common/StanderClassLoader.php new file mode 100644 index 0000000..59c2aca --- /dev/null +++ b/lib/Pinpoint/Common/StanderClassLoader.php @@ -0,0 +1,72 @@ +debug(" create a StanderClassLoader"); + $this->loadClassFunc = $orgLoader; + if ($orgLoader[0] instanceof ClassLoader) { + $this->findClassFunc = [$orgLoader[0], 'findFile']; + } + } + + public function getClassLoader(): callable + { + return [$this, 'loadClass']; + } + + public function findFile(string $classFullName): string + { + Logger::Inst()->debug("findClass:'$classFullName'"); + if (is_callable($this->findClassFunc)) { + $file = call_user_func($this->findClassFunc, $classFullName); + if ($file !== false) { + Logger::Inst()->debug("findClass:'$classFullName' ->'$file'"); + return realpath($file) ?: $file; + } + } + + return ''; + } + + /** + * call vendor loader or other framework defined loader + * @param $class + */ + public function loadClass($class) + { + Logger::Inst()->debug("try to loadClass:'$class'", ['StanderClassLoader']); + if (is_callable($this->loadClassFunc)) { + $classFilePath = call_user_func($this->loadClassFunc, $class); + if (is_string($classFilePath) && file_exists($classFilePath)) { + Logger::Inst()->debug("loadClass:'$class' -> '$classFilePath'", ['StanderClassLoader']); + require_once $classFilePath; + } + return $classFilePath; + } + } +} diff --git a/lib/Pinpoint/Common/UserClassLoaderInterface.php b/lib/Pinpoint/Common/UserFindClassLoader.php similarity index 59% rename from lib/Pinpoint/Common/UserClassLoaderInterface.php rename to lib/Pinpoint/Common/UserFindClassLoader.php index fc46beb..691ffdc 100644 --- a/lib/Pinpoint/Common/UserClassLoaderInterface.php +++ b/lib/Pinpoint/Common/UserFindClassLoader.php @@ -19,7 +19,16 @@ namespace Pinpoint\Common; -interface UserClassLoaderInterface + +class UserFindClassLoader extends StanderClassLoader { - public function userClassLoader(&$loader): callable; + public function __construct(array &$orgLoader, UserFrameworkInterface $userFindClass) + { + Logger::Inst()->debug(" create a UserFindClassLoader"); + parent::__construct($orgLoader); + if (is_callable($userFindClass)) { + $this->findClassFunc = $userFindClass->userFindClass($orgLoader); + assert(is_callable($this->findClassFunc)); + } + } } diff --git a/lib/Pinpoint/Common/JoinClassInterface.php b/lib/Pinpoint/Common/UserFrameworkInterface.php similarity index 88% rename from lib/Pinpoint/Common/JoinClassInterface.php rename to lib/Pinpoint/Common/UserFrameworkInterface.php index ff67ae6..eaea037 100644 --- a/lib/Pinpoint/Common/JoinClassInterface.php +++ b/lib/Pinpoint/Common/UserFrameworkInterface.php @@ -19,7 +19,8 @@ namespace Pinpoint\Common; -interface JoinClassInterface +interface UserFrameworkInterface { public function joinedClassSet(): array; + public function userFindClass(&$loader): callable; } diff --git a/lib/Pinpoint/Common/Utils.php b/lib/Pinpoint/Common/Utils.php index ad7496a..1a7a665 100644 --- a/lib/Pinpoint/Common/Utils.php +++ b/lib/Pinpoint/Common/Utils.php @@ -27,69 +27,7 @@ class Utils { - - - const U_INDEX_FILE_PATH = AOP_CACHE_DIR . '__class_index_table'; - - static private $beforeClassLoaderCb = null; - static private $endClassLoaderCb = null; - - public static function addLoaderPatch(callable $start, callable $tail = null) - { - static::$beforeClassLoaderCb = $start; - static::$endClassLoaderCb = $tail; - } - - /** - * locate a class (via VendorAdaptorClassLoader) - * @param $class - * @return bool|string - */ - public static function findFile(string $className): string - { - if (is_callable(static::$beforeClassLoaderCb)) { - $files = call_user_func(static::$beforeClassLoaderCb, $className); - if ($files) { - return $files; - } - } - - $splLoaders = spl_autoload_functions(); - foreach ($splLoaders as &$loader) { - - if (is_array($loader) && $loader[0] instanceof VendorAdaptorClassLoader) { - $address = $loader[0]->findFile($className); - if ($address) { - return realpath($address); - } - } - // keep peace with unknown loader - } - - if (is_callable(static::$endClassLoaderCb)) { - $files = call_user_func(static::$endClassLoaderCb, $className); - if ($files) { - return $files; - } - } - - return ''; - } - - public static function parseUserFunc($str) - { - preg_match_all('#(?<=@hook:).*#', $str, $matched); - - if ($matched) { - $func = []; - foreach ($matched[0] as $str) { - $func = array_merge($func, preg_split("# |\|#", $str, -1, PREG_SPLIT_NO_EMPTY)); - } - return $func; - } - - return []; - } + const U_INDEX_FILE_PATH = AOP_CACHE_DIR . '/.__class_index_table'; public static function saveObj(&$context, $fullPath) { @@ -98,7 +36,6 @@ public static function saveObj(&$context, $fullPath) mkdir($dir, 0777, true); } file_put_contents($fullPath, $context); - } @@ -115,8 +52,11 @@ public static function scanDir($dir, $pattern, &$tree) public static function checkCacheReady(): bool { + $cachePath = static::U_INDEX_FILE_PATH; + $useCache = defined('PINPOINT_USE_CACHE') && PINPOINT_USE_CACHE; + Logger::Inst()->debug("cachePath:'$cachePath' useCache '$useCache' "); return (defined('PINPOINT_USE_CACHE') && - stristr(PINPOINT_USE_CACHE, "YES") !== false) && + PINPOINT_USE_CACHE) && file_exists(static::U_INDEX_FILE_PATH); } diff --git a/lib/Pinpoint/Common/VendorAdaptorClassLoader.php b/lib/Pinpoint/Common/VendorAdaptorClassLoader.php deleted file mode 100644 index f6e28f3..0000000 --- a/lib/Pinpoint/Common/VendorAdaptorClassLoader.php +++ /dev/null @@ -1,117 +0,0 @@ -vendor_load_class_func = function (string $clsFullName) use (&$orgLoader) { - return call_user_func($orgLoader, $clsFullName); - }; - - // it's a common ClassLoader - if ($orgLoader[0] instanceof ClassLoader) { - - $this->originClassLoaderFunc = function (string $clsFullName) use (&$orgLoader) { - return $orgLoader[0]->findFile($clsFullName); - }; - return; - } - - //check is `findFile` classLoader - if ($userLoader != null) { - $this->originClassLoaderFunc = $userLoader->userClassLoader($orgLoader); - assert(is_callable($this->originClassLoaderFunc)); - return; - } - - throw new Exception("unknown classLoader:'$orgLoader'"); - } - - public function findFile(string $classFullName): string - { - Logger::Inst()->debug("try to VendorAdaptorClassLoader->findFile:'$classFullName' "); - if (is_callable($this->originClassLoaderFunc)) { - $file = call_user_func($this->originClassLoaderFunc, $classFullName); - if ($file !== false) { - Logger::Inst()->debug("VendorAdaptorClassLoader->findFile:'$classFullName' ->'$file' "); - return realpath($file) ?: $file; - } - } - - return ''; - } - - /** - * call vendor loader or other framework defined loader - * @param $class - */ - public function loadClass($class) - { - if (is_callable($this->vendor_load_class_func)) { - return call_user_func($this->vendor_load_class_func, $class); - } - } - - /** - * register pinpoint aop class loader, wrapper vendor class loader - * @param $classIndex - * @return bool - */ - public static function enable(UserClassLoaderInterface $u_classLoader = null) - { - $loaders = spl_autoload_functions(); - foreach ($loaders as &$olderLoader) { - if (is_array($olderLoader) && is_callable($olderLoader)) { - try { - // replace composer loader with aopclassLoader - $newLoader = new VendorAdaptorClassLoader($olderLoader, $u_classLoader); - // unregister composer loader - spl_autoload_unregister($olderLoader); - spl_autoload_register(array($newLoader, 'loadClass'), true, false); - } catch (Exception $e) { - /** - * if current loader not compatible, just ignore it! - * why? - * 1. pinpoint-php-aop only works on known framework! Exception will not expose to usr - * 2. Keep this loader, as it will handled its class. (We could write patch for this loader) - * 3. Pinpoint classloader is the highest priority - */ - Logger::Inst()->debug(" re-register pinpointloader failed '$e' "); - } - } - } - } -} diff --git a/lib/Pinpoint/Common/VendorClassLoaderAdaptor.php b/lib/Pinpoint/Common/VendorClassLoaderAdaptor.php new file mode 100644 index 0000000..7af0287 --- /dev/null +++ b/lib/Pinpoint/Common/VendorClassLoaderAdaptor.php @@ -0,0 +1,95 @@ +classLoaderFactory = new ClassLoaderFactory(); + } + + public static function Inst() + { + if (!self::$inst) { + self::$inst = new static(); + } + return self::$inst; + } + + public function setUserFindClass(UserFrameworkInterface $userFindClass = null) + { + $this->classLoaderFactory->setUserFindClass($userFindClass); + } + + /** + * register pinpoint aop class loader, wrapper vendor class loader + * @param $classIndex + * @return bool + */ + public function start() + { + $loaders = spl_autoload_functions(); + foreach ($loaders as &$olderLoader) { + if (is_array($olderLoader) && is_callable($olderLoader)) { + try { + $newLoader = $this->classLoaderFactory->createLoader($olderLoader); + spl_autoload_unregister($olderLoader); + spl_autoload_register($newLoader->getClassLoader(), true, false); + } catch (Exception $e) { + Logger::Inst()->debug(" re-register pinpointloader failed '$e' "); + } + } + } + } + + /** + * locate a class (via VendorClassLoaderAdaptor) + * @param $class + * @return bool|string + */ + public function findFileViaSpl(string $className): string + { + $splLoaders = spl_autoload_functions(); + foreach ($splLoaders as &$loader) { + if (is_array($loader)) { + $vendorLoader = $loader[0]; + assert(is_a($vendorLoader, StanderClassLoader::class), get_class($vendorLoader)); + $address = $vendorLoader->findFile($className); + if ($address) { + return realpath($address); + } + } + } + + return ''; + } +} diff --git a/lib/Pinpoint/Plugins/Common/CommonPlugin.php b/lib/Pinpoint/Plugins/Common/CommonPlugin.php index 1e7f563..7f8ff4c 100644 --- a/lib/Pinpoint/Plugins/Common/CommonPlugin.php +++ b/lib/Pinpoint/Plugins/Common/CommonPlugin.php @@ -1,4 +1,5 @@ getMessage()); + public function onException($e) + { + pinpoint_add_clue(PP_ADD_EXCEPTION, $e->getMessage()); } } diff --git a/lib/Pinpoint/Plugins/Common/PinTrace.php b/lib/Pinpoint/Plugins/Common/PinTrace.php index 0ec2d02..88b6ff9 100644 --- a/lib/Pinpoint/Plugins/Common/PinTrace.php +++ b/lib/Pinpoint/Plugins/Common/PinTrace.php @@ -1,4 +1,5 @@ apId = $apId; - $this->who = $who; - $this->args = &$args; + parent::__construct($monitorName, $who, $args); pinpoint_start_trace(); - pinpoint_add_clue(PP_INTERCEPTOR_NAME,$apId); + pinpoint_add_clue(PP_INTERCEPTOR_NAME, $monitorName); } public function __destruct() @@ -48,12 +44,8 @@ public function __destruct() pinpoint_end_trace(); } - abstract function onBefore(); - - abstract function onEnd(&$ret); - public function onException($e) { - pinpoint_add_clue(PP_ADD_EXCEPTION,$e->getMessage()); + pinpoint_add_clue(PP_ADD_EXCEPTION, $e->getMessage()); } } diff --git a/lib/Pinpoint/Plugins/Common/PluginsDefines.php b/lib/Pinpoint/Plugins/Common/PluginsDefines.php deleted file mode 100644 index fa7752b..0000000 --- a/lib/Pinpoint/Plugins/Common/PluginsDefines.php +++ /dev/null @@ -1,87 +0,0 @@ -apId = $apId; - $this->who = $who; - $this->args = &$args; + parent::__construct($apId, $who, $args); } - public function __destruct(){} + public function __destruct() + { + } - function onBefore(){} + function onBefore() + { + } - function onEnd(&$ret){} + function onEnd(&$ret) + { + } - public function onException($e) {} -} \ No newline at end of file + public function onException($e) + { + } +} diff --git a/lib/Pinpoint/Plugins/Common/defines.php b/lib/Pinpoint/Plugins/Common/defines.php new file mode 100644 index 0000000..b78be87 --- /dev/null +++ b/lib/Pinpoint/Plugins/Common/defines.php @@ -0,0 +1,91 @@ +ptype = $_SERVER[PP_HEADER_PAPPTYPE]; - pinpoint_add_clue(PP_PARENT_TYPE, $this->ptype); + $this->parentAppType = $_SERVER[PP_HEADER_PAPPTYPE]; + pinpoint_add_clue(PP_PARENT_TYPE, $this->parentAppType); } if (isset($_SERVER[PP_HEADER_PINPOINT_HOST]) || array_key_exists(PP_HEADER_PINPOINT_HOST, $_SERVER)) { diff --git a/lib/Pinpoint/Plugins/Yii2PerRequestPlugins.php b/lib/Pinpoint/Plugins/Yii2PerRequestPlugins.php index 1668e7d..9a03909 100644 --- a/lib/Pinpoint/Plugins/Yii2PerRequestPlugins.php +++ b/lib/Pinpoint/Plugins/Yii2PerRequestPlugins.php @@ -18,10 +18,9 @@ namespace Pinpoint\Plugins; -use Yii; -use Pinpoint\Common\Utils; +use yii; use Pinpoint\Plugins\PinpointPerRequestPlugins; -use Pinpoint\Common\JoinClassInterface; +use Pinpoint\Common\UserFrameworkInterface; use Pinpoint\Common\AspectClassHandle; use Pinpoint\Common\Logger; @@ -29,41 +28,57 @@ use Monolog\Handler\StreamHandler; -class Yii2PerRequestPlugins extends PinpointPerRequestPlugins implements JoinClassInterface +class Yii2PerRequestPlugins extends PinpointPerRequestPlugins implements UserFrameworkInterface { + // private $_yiiLoader = array(); public function __construct() { parent::__construct(); // enable findFile patch - Utils::addLoaderPatch(array($this, 'findFileInYii'), null); - $log = new mLogger('Yii2PerRequestPlugins'); - $log->pushHandler(new StreamHandler('php://stdout', mLogger::DEBUG)); + $log = new mLogger('yii2'); + $log->pushHandler(new StreamHandler('php://stdout', mLogger::INFO)); Logger::Inst()->setLogger($log); } - - public function findFileInYii($className): string + /** + * port from https://github.com/yiisoft/yii2/blob/6804fbeae8aa5f8ad5066b50f1864eb0b9d77849/framework/BaseYii.php#L279-L293 + */ + public function findFileInYii2($className): string { + $classFile = false; + Logger::Inst()->debug("try to yii::loader '$className' "); if (isset(Yii::$classMap[$className])) { $classFile = Yii::$classMap[$className]; if (strpos($classFile, '@') === 0) { - return Yii::getAlias($classFile); + $classFile = Yii::getAlias($classFile); } } elseif (strpos($className, '\\') !== false) { $classFile = Yii::getAlias('@' . str_replace('\\', '/', $className) . '.php', false); - if ($classFile === false || !is_file($classFile)) { - return ""; - } - return $classFile; } - return ""; + + if ($classFile === false || !is_file($classFile)) { + return ""; + } + Logger::Inst()->debug("yii::loader '$className' ->'$classFile'"); + // require_once file + return $classFile; + } + + public function userFindClass(&$loader): callable + { + return [$this, 'findFileInYii2']; } public function joinedClassSet(): array { $cls = []; + // \yii\web\UrlRule $classHandler = new AspectClassHandle(\yii\web\UrlRule::class); - $classHandler->addJoinPoint('parseRequest', yii2\UrlRule::class); + $classHandler->addJoinPoint('parseRequest', \Pinpoint\Plugins\yii2\UrlRule::class); + $cls[] = $classHandler; + // yii\db\Connection::createPdoInstance + $classHandler = new AspectClassHandle(\yii\db\Connection::class); + $classHandler->addJoinPoint('createPdoInstance', \Pinpoint\Plugins\yii2\ConnectionPlugin::class); $cls[] = $classHandler; return $cls; } diff --git a/lib/Pinpoint/Plugins/__init__.php b/lib/Pinpoint/Plugins/__init__.php index 57783b7..1879689 100644 --- a/lib/Pinpoint/Plugins/__init__.php +++ b/lib/Pinpoint/Plugins/__init__.php @@ -1,4 +1,5 @@ =')){ - require_once __DIR__."/Sys/mysqli8/Mysqli8.php"; - }elseif(version_compare(phpversion(), '7.0.0', '<')){ +if (function_exists('mysqli_connect')) { + if (version_compare(phpversion(), '8.0.0', '<')) { + require_once __DIR__ . "/Sys/mysqli/Mysqli.php"; + } elseif (version_compare(phpversion(), '8.0.0', '>=')) { + require_once __DIR__ . "/Sys/mysqli8/Mysqli8.php"; + } elseif (version_compare(phpversion(), '7.0.0', '<')) { throw new \Exception("not support php5+"); } -} \ No newline at end of file +} diff --git a/lib/Pinpoint/Plugins/AutoGen/Yii2/ConnectionPlugin.php b/lib/Pinpoint/Plugins/yii2/ConnectionPlugin.php similarity index 86% rename from lib/Pinpoint/Plugins/AutoGen/Yii2/ConnectionPlugin.php rename to lib/Pinpoint/Plugins/yii2/ConnectionPlugin.php index f2cb344..6dfdf17 100644 --- a/lib/Pinpoint/Plugins/AutoGen/Yii2/ConnectionPlugin.php +++ b/lib/Pinpoint/Plugins/yii2/ConnectionPlugin.php @@ -1,4 +1,6 @@ -who; @@ -37,5 +39,4 @@ function onEnd(&$ret) $ret = new PDO($dsn, $con->username, $con->password, $con->attributes); } } - -} \ No newline at end of file +} diff --git a/lib/Pinpoint/Plugins/yii2/UrlRule.php b/lib/Pinpoint/Plugins/yii2/UrlRule.php index d536c78..c59c5fd 100644 --- a/lib/Pinpoint/Plugins/yii2/UrlRule.php +++ b/lib/Pinpoint/Plugins/yii2/UrlRule.php @@ -34,14 +34,13 @@ function onEnd(&$ret) $route = $ret[0]; // $request = $this->args[1]; // $request->__pinpoint__route = $route; - Logger::Inst()->debug("found route:'$route'"); - pinpoint_set_context("__pinpoint__route", $route); + Logger::Inst()->info("found route:'$route'", ['UrlRule']); + pinpoint_set_context(PP_ROUTE_KEY, $route); } - // return $ret; } function onException($e) { - Logger::Inst()->debug(__CLASS__ . "onException '$e'"); + Logger::Inst()->info(__CLASS__ . "onException '$e'"); } } diff --git a/lib/Pinpoint/test/Bear.php b/lib/Pinpoint/test/Bear.php index 7e7c508..d1c58f6 100644 --- a/lib/Pinpoint/test/Bear.php +++ b/lib/Pinpoint/test/Bear.php @@ -7,20 +7,24 @@ */ class Bear { + public function __construct($a, $b, $c) + { + } + public $pdo; /** - * @output + * @output @output I'm annotation * @parameter: * @return */ - public function output(string $_1, int $_2, array &$_3) + public function output(string $_1, int $_2, array $_3) { - return 1010; } - public function noreturn(string $_1, int $_2, array &$_3, $a, $b, $c) + public function noreturn(string $_1, int $_2) { + $this->output('1', 3, [4]); } /** @@ -28,7 +32,7 @@ public function noreturn(string $_1, int $_2, array &$_3, $a, $b, $c) */ public function pdoNamespaceAlias($driver_options = NULL) { - $this->pdo = new \PDO('dsn', 'user', 'pass', $driver_options); + $this->pdo = new \PDO('sqlite:/tmp/foo.db', 'user', 'pass', $driver_options); } /** @@ -53,6 +57,13 @@ public function curlAlias($host = "www.example.com") curl_close($ch); } + + public function callInternal() + { + $this->checkProtected(); + $this->checkPrivate(); + } + /** * test protected function */ @@ -68,4 +79,13 @@ private function checkPrivate() $this->checkProtected(); return __METHOD__; } + + public static function staticFuncFoo(string $_1, int $_2, array $_3) + { + } + + public static function callstaticFuncFoo(string $_1, int $_2, array $_3) + { + self::staticFuncFoo("1", 2, [3]); + } } diff --git a/lib/Pinpoint/test/Comparison/Pinpoint/test/Bear.php b/lib/Pinpoint/test/Comparison/Pinpoint/test/Bear.php index 1fd6d16..ff78857 100644 --- a/lib/Pinpoint/test/Comparison/Pinpoint/test/Bear.php +++ b/lib/Pinpoint/test/Comparison/Pinpoint/test/Bear.php @@ -2,16 +2,87 @@ namespace Pinpoint\test; -use Pinpoint\test\ProxyBear; -class Bear extends ProxyBear +/** + * I'm the placeholder + */ +class Bear { - public function output(string $_1, int $_2, array &$_3) + public function __construct($a, $b, $c) + { + } + public $pdo; + /** + * @output @output I'm annotation + * @parameter: + * @return + */ + public function __pinpoint__output(string $_1, int $_2, array $_3) + { + return 1010; + } + public function __pinpoint__noreturn(string $_1, int $_2) + { + $this->output('1', 3, [4]); + } + /** + * $joinClass->addClassNameAlias('PDO', \Pinpoint\Plugins\Sys\PDO\PDO::class); + */ + public function pdoNamespaceAlias($driver_options = NULL) + { + $this->pdo = new \Pinpoint\Plugins\Sys\PDO\PDO('sqlite:/tmp/foo.db', 'user', 'pass', $driver_options); + } + /** + * $joinClass->addFunctionAlias('curl_init', 'Pinpoint\Plugins\Sys\curl\curl_init'); + */ + public function curlAlias($host = "www.example.com") + { + $ch = \Pinpoint\Plugins\Sys\curl\curl_init(); + \Pinpoint\Plugins\Sys\curl\curl_setopt($ch, CURLOPT_URL, $host); + \Pinpoint\Plugins\Sys\curl\curl_setopt($ch, CURLOPT_HEADER, TRUE); + \Pinpoint\Plugins\Sys\curl\curl_setopt($ch, CURLOPT_NOBODY, TRUE); + // remove body + \Pinpoint\Plugins\Sys\curl\curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); + $head = \Pinpoint\Plugins\Sys\curl\curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + \Pinpoint\Plugins\Sys\curl\curl_close($ch); + } + public function callInternal() + { + $this->checkProtected(); + $this->checkPrivate(); + } + /** + * test protected function + */ + protected function __pinpoint__checkProtected() + { + return __METHOD__; + } + /** + * test private function + */ + private function __pinpoint__checkPrivate() + { + $this->checkProtected(); + return __METHOD__; + } + public static function staticFuncFoo(string $_1, int $_2, array $_3) + { + } + public static function callstaticFuncFoo(string $_1, int $_2, array $_3) + { + self::staticFuncFoo("1", 2, [3]); + } + /* + * output auto-generated by pinpoint-apm/pinpoint-php-aop + */ + public function output(string $_1, int $_2, array $_3) { $_pinpoint_output_var = new \Pinpoint\test\OutputMonitor(__METHOD__, $this, $_1, $_2, $_3); $_pinpoint_output_ret = null; try { $_pinpoint_output_var->onBefore(); - $_pinpoint_output_ret = parent::output($_1, $_2, $_3); + $_pinpoint_output_ret = $this->__pinpoint__output($_1, $_2, $_3); $_pinpoint_output_var->onEnd($_pinpoint_output_ret); return $_pinpoint_output_ret; } catch (\Exception $e) { @@ -19,26 +90,32 @@ public function output(string $_1, int $_2, array &$_3) throw $e; } } - public function noreturn(string $_1, int $_2, array &$_3, $a, $b, $c) + /* + * noreturn auto-generated by pinpoint-apm/pinpoint-php-aop + */ + public function noreturn(string $_1, int $_2) { - $_pinpoint_noreturn_var = new \Pinpoint\test\OutputMonitor(__METHOD__, $this, $_1, $_2, $_3, $a, $b, $c); + $_pinpoint_noreturn_var = new \Pinpoint\test\OutputMonitorNoReturn(__METHOD__, $this, $_1, $_2); $_pinpoint_noreturn_ret = null; try { $_pinpoint_noreturn_var->onBefore(); - parent::noreturn($_1, $_2, $_3, $a, $b, $c); + $this->__pinpoint__noreturn($_1, $_2); $_pinpoint_noreturn_var->onEnd($_pinpoint_noreturn_ret); } catch (\Exception $e) { $_pinpoint_noreturn_var->onException($e); throw $e; } } + /* + * checkProtected auto-generated by pinpoint-apm/pinpoint-php-aop + */ protected function checkProtected() { $_pinpoint_checkProtected_var = new \Pinpoint\test\OutputMonitor(__METHOD__, $this); $_pinpoint_checkProtected_ret = null; try { $_pinpoint_checkProtected_var->onBefore(); - $_pinpoint_checkProtected_ret = parent::checkProtected(); + $_pinpoint_checkProtected_ret = $this->__pinpoint__checkProtected(); $_pinpoint_checkProtected_var->onEnd($_pinpoint_checkProtected_ret); return $_pinpoint_checkProtected_ret; } catch (\Exception $e) { @@ -46,13 +123,16 @@ protected function checkProtected() throw $e; } } - protected function checkPrivate() + /* + * checkPrivate auto-generated by pinpoint-apm/pinpoint-php-aop + */ + private function checkPrivate() { $_pinpoint_checkPrivate_var = new \Pinpoint\test\OutputMonitor(__METHOD__, $this); $_pinpoint_checkPrivate_ret = null; try { $_pinpoint_checkPrivate_var->onBefore(); - $_pinpoint_checkPrivate_ret = parent::checkPrivate(); + $_pinpoint_checkPrivate_ret = $this->__pinpoint__checkPrivate(); $_pinpoint_checkPrivate_var->onEnd($_pinpoint_checkPrivate_ret); return $_pinpoint_checkPrivate_ret; } catch (\Exception $e) { diff --git a/lib/Pinpoint/test/Comparison/Pinpoint/test/ProxyBear.php b/lib/Pinpoint/test/Comparison/Pinpoint/test/ProxyBear.php deleted file mode 100644 index a73b6cc..0000000 --- a/lib/Pinpoint/test/Comparison/Pinpoint/test/ProxyBear.php +++ /dev/null @@ -1,60 +0,0 @@ -addClassNameAlias('PDO', \Pinpoint\Plugins\Sys\PDO\PDO::class); - */ - public function pdoNamespaceAlias($driver_options = NULL) - { - $this->pdo = new \Pinpoint\Plugins\Sys\PDO\PDO('dsn', 'user', 'pass', $driver_options); - } - /** - * $joinClass->addFunctionAlias('curl_init', 'Pinpoint\Plugins\Sys\curl\curl_init'); - */ - public function curlAlias($host = "www.example.com") - { - $ch = \Pinpoint\Plugins\Sys\curl\curl_init(); - \Pinpoint\Plugins\Sys\curl\curl_setopt($ch, CURLOPT_URL, $host); - \Pinpoint\Plugins\Sys\curl\curl_setopt($ch, CURLOPT_HEADER, TRUE); - \Pinpoint\Plugins\Sys\curl\curl_setopt($ch, CURLOPT_NOBODY, TRUE); - // remove body - \Pinpoint\Plugins\Sys\curl\curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); - $head = \Pinpoint\Plugins\Sys\curl\curl_exec($ch); - $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); - \Pinpoint\Plugins\Sys\curl\curl_close($ch); - } - /** - * test protected function - */ - protected function checkProtected() - { - return __METHOD__; - } - /** - * test private function - */ - protected function checkPrivate() - { - $this->checkProtected(); - return __METHOD__; - } -} \ No newline at end of file diff --git a/lib/Pinpoint/test/OriginFileVisitor_test.php b/lib/Pinpoint/test/OriginFileVisitor_test.php index 6a9ef6e..710b5e7 100644 --- a/lib/Pinpoint/test/OriginFileVisitor_test.php +++ b/lib/Pinpoint/test/OriginFileVisitor_test.php @@ -8,8 +8,8 @@ use Pinpoint\Common\OriginFileVisitor; use Pinpoint\Common\Utils; use Pinpoint\Common\AspectClassHandle; -use Pinpoint\Common\VendorAdaptorClassLoader; -use Pinpoint\Common\RenderAopClass; +use Pinpoint\Common\VendorClassLoaderAdaptor; +use Pinpoint\Common\MonitorClass; define('CLASS_PREFIX', 'Proxy'); define('AOP_CACHE_DIR', __DIR__ . '/Cache'); @@ -23,17 +23,17 @@ class OriginFileVisitor_test extends TestCase { public function setUp() { - VendorAdaptorClassLoader::enable(); + VendorClassLoaderAdaptor::Inst()->start(); parent::setUp(); } public function test_FileVisitor() { - $fullPath = Utils::findFile(Bear::class); + $fullPath = VendorClassLoaderAdaptor::Inst()->findFileViaSpl(Bear::class); $this->assertFileExists($fullPath); $classHandler = new AspectClassHandle(Bear::class); $classHandler->addJoinPoint('output', OutputMonitor::class); - $classHandler->addJoinPoint('noreturn', OutputMonitor::class); + $classHandler->addJoinPoint('noreturn', OutputMonitorNoReturn::class); $classHandler->addClassNameAlias('PDO', \Pinpoint\Plugins\Sys\PDO\PDO::class); $classHandler->addFunctionAlias('curl_init', 'Pinpoint\Plugins\Sys\curl\curl_init'); @@ -46,11 +46,12 @@ public function test_FileVisitor() $visitor = new OriginFileVisitor(); $visitor->runAllVisitor($fullPath, $classHandler); - $classMap = RenderAopClass::getInstance()->getJointClassMap(); + $classMap = MonitorClass::getInstance()->getJointClassMap(); $this->assertArrayHasKey(Bear::class, $classMap); foreach ($classMap as $class => $file) { // print_r(str_replace("Comparison","Cache",$file)); $this->assertFileEquals($file, str_replace("Cache", "Comparison", $file)); } + Utils::saveCachedClass(MonitorClass::getInstance()->getJointClassMap()); } } diff --git a/lib/Pinpoint/test/OutputMonitor.php b/lib/Pinpoint/test/OutputMonitor.php index fc558aa..2a72025 100644 --- a/lib/Pinpoint/test/OutputMonitor.php +++ b/lib/Pinpoint/test/OutputMonitor.php @@ -3,18 +3,25 @@ namespace Pinpoint\test; use Pinpoint\Common\AbstractMonitor; +use Pinpoint\Common\Logger; class OutputMonitor extends AbstractMonitor { function onBefore() { + Logger::Inst()->debug("onbefore"); } function onEnd(&$ret) { + if ($ret === 1010) { + $ret = 1011; + } + Logger::Inst()->debug("onEnd"); } function onException($e) { + Logger::Inst()->debug("onException"); } } diff --git a/lib/Pinpoint/test/OutputMonitorNoReturn.php b/lib/Pinpoint/test/OutputMonitorNoReturn.php new file mode 100644 index 0000000..7fe9909 --- /dev/null +++ b/lib/Pinpoint/test/OutputMonitorNoReturn.php @@ -0,0 +1,20 @@ +output("a", 2, $ar); +} + +assert($bear->output("a", 2, $ar) == 1011); + +$bear->noreturn("a", 2); + +try { + $bear->pdoNamespaceAlias(); +} catch (PDOException $e) { +} +$bear->curlAlias(); +$bear->callInternal(); +$bear->callstaticFuncFoo("a", 2, $ar); diff --git a/lib/Pinpoint/test/php_parse.php b/lib/Pinpoint/test/php_parse.php index 4e1bdcb..72b94e0 100644 --- a/lib/Pinpoint/test/php_parse.php +++ b/lib/Pinpoint/test/php_parse.php @@ -7,7 +7,7 @@ use PDO; use PhpParser\ParserFactory; use PhpParser\PrettyPrinter; -$filename='Cache/Pinpoint/test/Bear.php'; +$filename='Bear.php'; $code = file_get_contents($filename); diff --git a/test.php b/test.php deleted file mode 100644 index 092911b..0000000 --- a/test.php +++ /dev/null @@ -1,70 +0,0 @@ -getName(); // X -} - -// test(new X1()); - - - -class A -{ - public int $a = 10; - public int $b = 10; -} - - -$a = new A(); - -print_r($a); -$a->a = 12; -print_r($a); - -function change_a(A $a) -{ - $a->a = 13; -} - -function change_a1(A $a) -{ - $a->a = 14; -} - -change_a($a); -print_r($a); - -change_a1($a); -print_r($a); - - -$test_ar = array( - "a" => 1, - "b" => 3 -); - - -print_r(array_key_exists('b', $test_ar)); - -print(A::class); From 93537dcaa111ffd4a24b83f07bed14d90cfe3558 Mon Sep 17 00:00:00 2001 From: eeliu <27064129+eeliu@users.noreply.github.com> Date: Thu, 2 Nov 2023 18:09:43 +0800 Subject: [PATCH 09/13] add UT on PinpointPerRequestPlugins --- .gitignore | 2 +- lib/Pinpoint/Plugins/Common/defines.php | 1 + .../Plugins/PinpointPerRequestPlugins.php | 8 +++++++- test_logger.php | 15 --------------- 4 files changed, 9 insertions(+), 17 deletions(-) delete mode 100644 test_logger.php diff --git a/.gitignore b/.gitignore index 87ed5ae..21e3449 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,4 @@ lib/pinpoint/test/test.php # Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control # You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file # composer.lock -test*.php \ No newline at end of file +/test_*.php \ No newline at end of file diff --git a/lib/Pinpoint/Plugins/Common/defines.php b/lib/Pinpoint/Plugins/Common/defines.php index b78be87..ed11b9d 100644 --- a/lib/Pinpoint/Plugins/Common/defines.php +++ b/lib/Pinpoint/Plugins/Common/defines.php @@ -89,3 +89,4 @@ # key for support UT # https://github.com/pinpoint-apm/pinpoint-c-agent/issues/534 define("PP_ROUTE_KEY", '__pinpoint__route'); +define("UT", 'UT'); diff --git a/lib/Pinpoint/Plugins/PinpointPerRequestPlugins.php b/lib/Pinpoint/Plugins/PinpointPerRequestPlugins.php index 01db52a..22973d9 100644 --- a/lib/Pinpoint/Plugins/PinpointPerRequestPlugins.php +++ b/lib/Pinpoint/Plugins/PinpointPerRequestPlugins.php @@ -20,6 +20,8 @@ require_once __DIR__ . "/__init__.php"; +use Pinpoint\Common\Logger; + class PinpointPerRequestPlugins { public $tid = null; @@ -148,7 +150,11 @@ public function __destruct() pinpoint_mark_as_error('Internal server error', __FILE__); } } - + $urlTemplateUrl = pinpoint_get_context(PP_ROUTE_KEY); + if ($urlTemplateUrl != false && !empty($urlTemplateUrl)) { + pinpoint_add_clue(UT, $urlTemplateUrl); + Logger::Inst()->debug("add ut '$urlTemplateUrl'"); + } pinpoint_end_trace(); } diff --git a/test_logger.php b/test_logger.php deleted file mode 100644 index 7be6837..0000000 --- a/test_logger.php +++ /dev/null @@ -1,15 +0,0 @@ -pushHandler(new StreamHandler('php://stdout', Logger::WARNING)); - -// add records to the log -$log->warning('Foo'); -$log->error('Bar'); From b1c15f08b461221f3c2fea2b8ccc9d7a3e061775 Mon Sep 17 00:00:00 2001 From: eeliu <27064129+eeliu@users.noreply.github.com> Date: Fri, 3 Nov 2023 15:46:54 +0800 Subject: [PATCH 10/13] monitor \yii\web\UrlManager --- composer.json | 3 +-- lib/Pinpoint/Common/Logger.php | 11 +++++++++++ lib/Pinpoint/Common/PerRequestDefault.php | 5 ----- lib/Pinpoint/Plugins/Yii2PerRequestPlugins.php | 18 +++++++++++------- lib/Pinpoint/Plugins/yii2/UrlRule.php | 7 +++++-- ...itor_test.php => TestOriginFileVisitor.php} | 2 +- 6 files changed, 29 insertions(+), 17 deletions(-) rename lib/Pinpoint/test/{OriginFileVisitor_test.php => TestOriginFileVisitor.php} (97%) diff --git a/composer.json b/composer.json index 986e906..d1e0e95 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,6 @@ }, "require": { "php": ">=7", - "nikic/php-parser": "^4.1", - "monolog/monolog": "2.x-dev" + "nikic/php-parser": "^4.1" } } diff --git a/lib/Pinpoint/Common/Logger.php b/lib/Pinpoint/Common/Logger.php index 96ebfe4..e9741f1 100644 --- a/lib/Pinpoint/Common/Logger.php +++ b/lib/Pinpoint/Common/Logger.php @@ -27,6 +27,11 @@ private function __construct() { } + private function defaultLogger(string $message, $context) + { + error_log($message . " " . "'$context'", 0); + } + public static function Inst() { if (!(self::$_inst instanceof self)) { @@ -47,6 +52,8 @@ public function debug($message, array $context = []) { if ($this->log != null) { $this->log->debug($message, $context); + } else { + $this->defaultLogger($message, $context); } } @@ -54,12 +61,16 @@ public function info($message, array $context = []) { if ($this->log != null) { $this->log->info($message, $context); + } else { + $this->defaultLogger($message, $context); } } public function warning($message, array $context = []) { if ($this->log != null) { $this->log->warning($message, $context); + } else { + $this->defaultLogger($message, $context); } } } diff --git a/lib/Pinpoint/Common/PerRequestDefault.php b/lib/Pinpoint/Common/PerRequestDefault.php index e235f9c..5b82a42 100644 --- a/lib/Pinpoint/Common/PerRequestDefault.php +++ b/lib/Pinpoint/Common/PerRequestDefault.php @@ -19,16 +19,11 @@ namespace Pinpoint\Common; -use Monolog\Logger as mlogger; -use Monolog\Handler\StreamHandler; class PerRequestDefault implements UserFrameworkInterface { public function __construct() { - $log = new mlogger('pp'); - $log->pushHandler(new StreamHandler('php://stdout', mlogger::DEBUG)); - Logger::Inst()->setLogger($log); } public function joinedClassSet(): array { diff --git a/lib/Pinpoint/Plugins/Yii2PerRequestPlugins.php b/lib/Pinpoint/Plugins/Yii2PerRequestPlugins.php index 9a03909..4279c0c 100644 --- a/lib/Pinpoint/Plugins/Yii2PerRequestPlugins.php +++ b/lib/Pinpoint/Plugins/Yii2PerRequestPlugins.php @@ -24,8 +24,7 @@ use Pinpoint\Common\AspectClassHandle; use Pinpoint\Common\Logger; -use Monolog\Logger as mLogger; -use Monolog\Handler\StreamHandler; + class Yii2PerRequestPlugins extends PinpointPerRequestPlugins implements UserFrameworkInterface @@ -34,10 +33,13 @@ class Yii2PerRequestPlugins extends PinpointPerRequestPlugins implements UserFra public function __construct() { parent::__construct(); + // if you need logger set here + // use Monolog\Logger as mLogger; + // use Monolog\Handler\StreamHandler; // enable findFile patch - $log = new mLogger('yii2'); - $log->pushHandler(new StreamHandler('php://stdout', mLogger::INFO)); - Logger::Inst()->setLogger($log); + // $log = new mLogger('yii2'); + // $log->pushHandler(new StreamHandler('php://stdout', mLogger::INFO)); + // Logger::Inst()->setLogger($log); } /** * port from https://github.com/yiisoft/yii2/blob/6804fbeae8aa5f8ad5066b50f1864eb0b9d77849/framework/BaseYii.php#L279-L293 @@ -71,11 +73,13 @@ public function userFindClass(&$loader): callable public function joinedClassSet(): array { $cls = []; - // \yii\web\UrlRule - $classHandler = new AspectClassHandle(\yii\web\UrlRule::class); + + // \yii\web\UrlManager + $classHandler = new AspectClassHandle(\yii\web\UrlManager::class); $classHandler->addJoinPoint('parseRequest', \Pinpoint\Plugins\yii2\UrlRule::class); $cls[] = $classHandler; + // yii\db\Connection::createPdoInstance $classHandler = new AspectClassHandle(\yii\db\Connection::class); $classHandler->addJoinPoint('createPdoInstance', \Pinpoint\Plugins\yii2\ConnectionPlugin::class); diff --git a/lib/Pinpoint/Plugins/yii2/UrlRule.php b/lib/Pinpoint/Plugins/yii2/UrlRule.php index c59c5fd..cc1dc1f 100644 --- a/lib/Pinpoint/Plugins/yii2/UrlRule.php +++ b/lib/Pinpoint/Plugins/yii2/UrlRule.php @@ -34,13 +34,16 @@ function onEnd(&$ret) $route = $ret[0]; // $request = $this->args[1]; // $request->__pinpoint__route = $route; - Logger::Inst()->info("found route:'$route'", ['UrlRule']); + if (empty($route)) { + $route = "/"; + } + Logger::Inst()->debug("found route:'$route'", ['UrlRule']); pinpoint_set_context(PP_ROUTE_KEY, $route); } } function onException($e) { - Logger::Inst()->info(__CLASS__ . "onException '$e'"); + Logger::Inst()->debug(__CLASS__ . "onException '$e'"); } } diff --git a/lib/Pinpoint/test/OriginFileVisitor_test.php b/lib/Pinpoint/test/TestOriginFileVisitor.php similarity index 97% rename from lib/Pinpoint/test/OriginFileVisitor_test.php rename to lib/Pinpoint/test/TestOriginFileVisitor.php index 710b5e7..175589d 100644 --- a/lib/Pinpoint/test/OriginFileVisitor_test.php +++ b/lib/Pinpoint/test/TestOriginFileVisitor.php @@ -19,7 +19,7 @@ * Test convert user class to dst AOP class * @package pinpoint\test */ -class OriginFileVisitor_test extends TestCase +class TestOriginFileVisitor extends TestCase { public function setUp() { From 4617f7cc1d974edfc05d1daa9b0ebcea04c78a49 Mon Sep 17 00:00:00 2001 From: eeliu <27064129+eeliu@users.noreply.github.com> Date: Fri, 3 Nov 2023 16:18:22 +0800 Subject: [PATCH 11/13] fix error_log format --- lib/Pinpoint/Common/Logger.php | 3 ++- .../{TestOriginFileVisitor.php => OriginFileVisitor_Test.php} | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) rename lib/Pinpoint/test/{TestOriginFileVisitor.php => OriginFileVisitor_Test.php} (97%) diff --git a/lib/Pinpoint/Common/Logger.php b/lib/Pinpoint/Common/Logger.php index e9741f1..54bd0e2 100644 --- a/lib/Pinpoint/Common/Logger.php +++ b/lib/Pinpoint/Common/Logger.php @@ -29,7 +29,8 @@ private function __construct() private function defaultLogger(string $message, $context) { - error_log($message . " " . "'$context'", 0); + $ctx = implode("", $context); + error_log($message . " " . "'$ctx'", 0); } public static function Inst() diff --git a/lib/Pinpoint/test/TestOriginFileVisitor.php b/lib/Pinpoint/test/OriginFileVisitor_Test.php similarity index 97% rename from lib/Pinpoint/test/TestOriginFileVisitor.php rename to lib/Pinpoint/test/OriginFileVisitor_Test.php index 175589d..879ba97 100644 --- a/lib/Pinpoint/test/TestOriginFileVisitor.php +++ b/lib/Pinpoint/test/OriginFileVisitor_Test.php @@ -19,7 +19,7 @@ * Test convert user class to dst AOP class * @package pinpoint\test */ -class TestOriginFileVisitor extends TestCase +class OriginFileVisitor_Test extends TestCase { public function setUp() { From 46425edac8577a374b2f17fa9a2eaa678ea77d96 Mon Sep 17 00:00:00 2001 From: eeliu <27064129+eeliu@users.noreply.github.com> Date: Fri, 3 Nov 2023 17:19:24 +0800 Subject: [PATCH 12/13] try php 8 --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e1f2cf7..8c0d924 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-versions: ['7.1', '7.2', '7.3', '7.4'] + php-versions: [ '7.4','8.0','8.1','8.2'] steps: - uses: actions/checkout@v2 - name: Setup PHP From 6d60a5a6748cd8477978b6138db9285bb960ae11 Mon Sep 17 00:00:00 2001 From: eeliu <27064129+eeliu@users.noreply.github.com> Date: Fri, 3 Nov 2023 17:33:22 +0800 Subject: [PATCH 13/13] fix TestCase --- composer.json | 2 +- lib/Pinpoint/test/OriginFileVisitor_Test.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index d1e0e95..56d6f0e 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ }, "minimum-stability": "dev", "require-dev": { - "phpunit/phpunit": "^7" + "phpunit/phpunit": "^8" }, "require": { "php": ">=7", diff --git a/lib/Pinpoint/test/OriginFileVisitor_Test.php b/lib/Pinpoint/test/OriginFileVisitor_Test.php index 879ba97..5a7d32c 100644 --- a/lib/Pinpoint/test/OriginFileVisitor_Test.php +++ b/lib/Pinpoint/test/OriginFileVisitor_Test.php @@ -21,7 +21,7 @@ */ class OriginFileVisitor_Test extends TestCase { - public function setUp() + protected function setUp(): void { VendorClassLoaderAdaptor::Inst()->start(); parent::setUp();