code-distortion / clarity-context
为 Laravel 设计的上下文跟踪器包
Requires
- php: 8.0.* | 8.1.* | 8.2.* | 8.3.*
- code-distortion/staticall: ^0.1.0
Requires (Dev)
- infection/infection: ^0.10 | ^0.11 | ^0.12 | ^0.13 | ^0.14 | ^0.15 | ^0.16 | ^0.17 | ^0.18 | ^0.19 | ^0.20 | ^0.21 | ^0.22 | ^0.23 | ^0.24 | ^0.25 | ^0.26 | ^0.27
- orchestra/testbench: ^6.12 | ^7.0 | ^8.0
- phpstan/phpstan: ^0.9 | ^0.10 | ^0.11 | ^0.12 | ^1.0
- phpunit/phpunit: ~4.8 | ^5.0 | ^6.0 | ^7.0 | ^8.4 | ^9.0 | ^10.0
- squizlabs/php_codesniffer: ^3.8.0
Suggests
- code-distortion/clarity-control: Handle Your Exceptions. Part of the Clarity Suite
- code-distortion/clarity-logger: Useful Exception Logs. Part of the Clarity Suite
README
code-distortion/clarity-context 是一个为 Laravel 设计的上下文跟踪器包,可以在发生异常时为您提供代码操作的鸟瞰图。
为您的代码添加上下文。例如。
// in a file in your project Clarity::context('Performing checkout', ['user-id' => $userId, 'order-id' => $orderId]); …
// in another file Clarity::context('Sending payment request to gateway'); Clarity::context(['payment-gateway' => 'examplexyz.com', 'card-id' => $cardId, 'amount' => $amount]); …
收集这些信息是为了当发生异常时,可以用来 显示代码在异常发生时的操作情况。例如。
app/Domain/Checkout/PerformCheckoutAction.php on line 20 (method "submit")
- "Performing checkout"
- user-id = 5
- order-id = 123
app/Domain/Payments/MakePaymentAction.php on line 19 (method "handle") (last application frame)
- "Sending payment request to gateway"
- payment-gateway = 'examplexyz.com'
- card-id = 456
- amount = '10.99'
vendor/laravel/framework/src/Illuminate/Http/Client/PendingRequest.php on line 856 (closure)
- The exception was thrown
Clarity Suite
Clarity Context 是 Clarity Suite 的一部分,旨在让您更容易地管理异常。
- Clarity Context - 理解您的异常
- Clarity Logger - 有用的异常日志
- Clarity Control - 处理您的异常
目录
安装
使用 composer 安装包
composer require code-distortion/clarity-context
配置文件
如果您想发布 config/code_distortion.clarity_context.php
配置文件,请使用以下命令。
它简单地为您提供了开启或关闭此包的选项。
php artisan vendor:publish --provider="CodeDistortion\ClarityContext\ServiceProvider" --tag="config"
为您的代码添加上下文
Clarity Context 允许您在代码中添加上下文详细信息。它跟踪当前调用栈中的内容,以便在发生异常时使用。例如。
Clarity::context("A quick description of what's currently happening"); Clarity::context(['some-relevant-id' => 123]);
您可以为当前正在发生的事情添加 字符串 来解释,或者添加 关联数组 来显示代码当前正在处理的特定细节。
在代码的相关位置添加上下文。选择在追踪问题时能提供最多洞察力的位置。根据需要添加尽可能多的内容。
您可以一次性传递多个值
Clarity::context("Processing csv file", ['file' => $file, 'category' => $categoryId]);
注意: 不要添加您不希望被记录的敏感细节!
如果您使用跟踪标识符来标识请求,也可以添加这些标识符。一个很好的添加位置是在 服务提供者 或 请求中间件 中。
Clarity::traceIdentifier($traceId);
异常记录
要记录您的异常,安装一个了解 Clarity Context 的包,如 Clarity Logger。按照其安装说明将记录添加到您的项目中。
Clarity Logger 将自动将您的上下文详细信息与其通常记录的详细信息一起包含在内。例如。
EXCEPTION (UNCAUGHT):
exception Illuminate\Http\Client\ConnectionException: "cURL error 6: Could not resolve host: api.example-gateway.com (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for https://api.example-gateway.com"
- location app/Http/Controllers/CheckoutController.php on line 50 (method "submit")
- vendor vendor/laravel/framework/src/Illuminate/Http/Client/PendingRequest.php on line 856 (closure)
request POST https://my-website.com/checkout
- referrer https://my-website.com/checkout
- route cart.checkout
- middleware web
- action CheckoutController@submit
- trace-id 1234567890
user 3342 - Bob - bob@example.com (123.123.123.123)
- agent Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36
date/time Sunday 2nd April at 7:08pm (Australia/Sydney) 2023-04-02 19:08:23 AEST +10:00
CONTEXT:
app/Domain/Checkout/PerformCheckoutAction.php on line 20 (method "handle")
- "Performing checkout"
- user-id = 5
- order-id = 123
app/Domain/Payments/MakePaymentAction.php on line 19 (method "handle") (last application frame)
- "Sending payment request to gateway"
- payment-gateway = 'examplexyz.com'
- card-id = 456
- amount = '10.99'
vendor/laravel/framework/src/Illuminate/Http/Client/PendingRequest.php on line 856 (closure)
- The exception was thrown
⚙️ 点击获取更多信息。
记录异常(高级)
Clarity Context 收集并管理您添加到代码中的上下文细节。
当发生异常时,它会构建一个 CodeDistortion\ClarityContext\Context
对象,该对象可以被进行记录的代码使用。这个 Context
对象包含您添加的详细信息(当时在调用栈中存在的)。
如果您想自己处理记录,或者正在构建一个用于此目的的包,则需要更新 Laravel 的 异常处理器 app/Exceptions/Handler.php
以使用这些 Context
值。
本节解释如何使用这个Context
类。
获取上下文对象
使用Clarity::getExceptionContext($e)
来访问为该异常构建的CodeDistortion\ClarityContext\Context
对象。
然后您可以根据Context
对象中的内容选择如何记录异常。
// app/Exceptions/Handler.php namespace App\Exceptions; use CodeDistortion\ClarityContext\Clarity; // <<< use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; use Throwable; class Handler extends ExceptionHandler { … /** * Register the exception handling callbacks for the application. */ public function register(): void { $this->reportable(function (Throwable $e) { $context = Clarity::getExceptionContext($e); // <<< // … perform formatting and logging here }); } }
上下文对象
Context
对象包含有关异常的各种详细信息,包括
- 调用栈/堆栈跟踪(基于
$e->getTrace()
,但文件/行号向上一帧偏移,因此它们更有意义), - 异常发生时的上下文详细信息,
- 异常抛出和捕获的位置引用。
$context->getException(); // the exception that was caught $context->getChannels(); // the intended channels to log to $context->getLevel(); // the intended reporting level (debug, … emergency) $context->getDefault(); // the default value that will be returned $context->getTraceIdentifiers(); // the trace identifiers $context->getKnown(); // "known" issues associated with the exception $context->hasKnown(); // whether the exception has "known" issues or not $context->getReport(); // whether to trigger Laravel's report() method or not $context->getRethrow(); // whether to rethrow, a closure to resolve it, or an exception itself to throw $context->detailsAreWorthListing(); // whether details (other than those you can get by looking at the exception alone) are available $stackTrace = $context->getStackTrace(); // the stack trace frames (most recent at the start) $callStack = $context->getCallStack(); // the same as the stack trace, but in reverse
堆栈跟踪/调用栈,以及帧
您可以使用$context->getStackTrace()
或$context->getCallStack()
检索有关调用栈帧的详细信息。它们包含表示每个帧的对象。
getStackTrace()
按照从最近到最远的顺序包含帧。getCallStack()
与之相同,只是顺序从最远到最近。
它们还包含以下方法来帮助您找到特定的帧和元信息。
$stackTrace = $context->getStackTrace(); // or $context->getCallStack(); $stackTrace->getLastApplicationFrame(); // get the last application (i.e. non-vendor) frame $stackTrace->getLastApplicationFrameIndex(); // get the index of the last application frame $stackTrace->getExceptionThrownFrame(); // get the frame that threw the exception $stackTrace->getExceptionThrownFrameIndex(); // get the index of the frame that threw the exception $stackTrace->getExceptionCaughtFrame(); // get the frame that caught the exception $stackTrace->getExceptionCaughtFrameIndex(); // get the index of the frame that caught the exception $stackTrace->getMeta(); // get the Meta objects - these represent the context details, amongst others $stackTrace->getGroupedMeta(); // get the Meta objects grouped together in MetaGroups - see below
它们是可迭代的,因此可以遍历。
您可以从以下Frame对象中检索以下详细信息
$stackTrace = $context->getStackTrace(); // or $context->getCallStack(); foreach ($stackTrace as $frame) { $frame->getFile(); // the path to the file containing the code being run $frame->getProjectFile(); // the same file, but relative to the project-root's dir $frame->getLine(); // the relevant line number $frame->getFunction(); // the function or method being run at the time $frame->getClass(); // the class being used at the time $frame->getObject(); // the object instance being used at the time $frame->getType(); // the "type" ("::", "->") $frame->getArgs(); // the arguments the function or method was called with $frame->getMeta(); // retrieve the Meta objects, see below $frame->isApplicationFrame(); // is this an application (i.e. non-vendor) frame? $frame->isLastApplicationFrame(); // is this the last application frame (before the exception was thrown)? $frame->isVendorFrame(); // is this a vendor frame? $frame->isLastFrame(); // is this in the last frame in the (where the exception was thown)? $frame->exceptionWasThrownHere(); // was the exception thrown by this frame? $frame->exceptionWasCaughtHere(); // was the exception caught by this frame? }
注意:一些方法如
getFunction()
、getClass()
、getObject()
并不总是返回值。这取决于具体情况。有关更多详细信息,请参阅PHP的debug_backtrace方法。
元对象
有5种类型的元对象
ContextMeta
- 当应用程序调用Clarity::context(…)
添加上下文详细信息时,CallMeta
- 当控制包为应用程序运行一些代码时(例如使用Control::run()
),LastApplicationFrameMeta
- 最后一个应用程序(即非供应商)帧的位置,ExceptionThrownMeta
- 异常被抛出的位置,ExceptionCaughtMeta
- 异常被捕获的位置。
您可以从元对象中检索以下详细信息
// all Meta classes $meta->getFile(); // the relevant file $meta->getProjectFile(); // the same file, but relative to the project-root's dir $meta->getLine(); // the relevant line number $meta->getFunction(); // the function or method being run at the time $meta->getClass(); // the class being used at the time $meta->getType(); // the "type" ("::", "->") // ContextMeta only $meta->getContext(); // the context array or sentence // CallMeta only $meta->wasCaughtHere(); // whether the excepton was caught here or not $meta->getKnown(); // the "known" issues associated to the exception
有几种方法可以检索元对象
$context->getStackTrace()->getMeta(); // all the Meta objects, in stack trace order $context->getCallStack()->getMeta(); // all the Meta objects, in call stack order $frame->getMeta(); // the Meta objects present in a particular frame $metaGroup->getMeta(); // related Meta objects, grouped togther (see below)
这些方法中的每一个都接受一个元类字符串,或者多个它们,这限制了结果。例如。
$context->getStackTrace()->getMeta(ContextMeta::class); // only ContextMeta objects will be returned
元组对象
在报告异常详细信息时,将元对象分组在一起非常有用。MetaGroup
对象提供了一种以逻辑方式分组元对象的方法。
组内的元对象相关联,即在同一个帧和附近行。
$context->getStackTrace()->getMetaGroups(); $context->getCallStack()->getMetaGroups();
每个MetaGroup包含与Frame
对象相似的详细信息。
$metaGroup->getFile(); // the path to the file containing the code being run $metaGroup->getProjectFile(); // the same file, but relative to the project-root's dir $metaGroup->getLine(); // the relevant line number $metaGroup->getFunction(); // the function or method being run at the time $metaGroup->getClass(); // the class being used at the time $metaGroup->getType(); // the "type" ("::", "->") $metaGroup->getMeta(); // the meta objects contained within $metaGroup->isInApplicationFrame(); // is this in an application (i.e. non-vendor) frame? $metaGroup->isInLastApplicationFrame(); // is this in the last application frame (before the exception was thrown)? $metaGroup->isInVendorFrame(); // is this in a vendor frame? $metaGroup->isInLastFrame(); // is this in the last frame (where the exception was thown)? $metaGroup->exceptionThrownInThisFrame(); // is this in the frame the exception was thrown from? $metaGroup->exceptionCaughtInThisFrame(); // is this in the frame the exception was caught in?
没有异常的上下文对象
您可以在不需要异常的情况下任意生成上下文对象。
返回的上下文对象将包含当前上下文详细信息,就像它通常那样。
$context = Clarity::buildContextHere();
测试此包
- 克隆此包:
git clone https://github.com/code-distortion/clarity-context.git .
- 运行
composer install
以安装依赖项 - 运行测试:
composer test
变更日志
请参阅CHANGELOG以获取有关最近更改的更多信息。
语义版本
此库使用SemVer 2.0.0版本控制。这意味着对X
的更改表示破坏性更改:0.0.X
、0.X.y
、X.y.z
。当此库更改为版本1.0.0、2.0.0以及如此类时,它并不表示它是一个值得注意的版本发布,它只是表示更改是破坏性的。
实物
本软件包为Treeware。如果您在生产环境中使用它,我们请求您为世界买一棵树以感谢我们的工作。通过为Treeware森林贡献力量,您将帮助当地家庭创造就业机会并恢复野生动物栖息地。
贡献
有关详细信息,请参阅CONTRIBUTING。
行为准则
有关详细信息,请参阅CODE_OF_CONDUCT。
安全
如果您发现任何安全相关的问题,请发送电子邮件至tim@code-distortion.net,而不是使用问题跟踪器。
鸣谢
许可证
MIT许可证(MIT)。有关更多信息,请参阅许可证文件。