code-distortion/clarity-context

为 Laravel 设计的上下文跟踪器包

0.1.0 2023-12-31 07:37 UTC

This package is auto-updated.

Last update: 2024-08-30 01:44:28 UTC


README

Latest Version on Packagist PHP Version Laravel GitHub Workflow Status Buy The World a Tree Contributor Covenant

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 的一部分,旨在让您更容易地管理异常。


目录

安装

使用 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.X0.X.yX.y.z。当此库更改为版本1.0.0、2.0.0以及如此类时,它并不表示它是一个值得注意的版本发布,它只是表示更改是破坏性的。

实物

本软件包为Treeware。如果您在生产环境中使用它,我们请求您为世界买一棵树以感谢我们的工作。通过为Treeware森林贡献力量,您将帮助当地家庭创造就业机会并恢复野生动物栖息地。

贡献

有关详细信息,请参阅CONTRIBUTING

行为准则

有关详细信息,请参阅CODE_OF_CONDUCT

安全

如果您发现任何安全相关的问题,请发送电子邮件至tim@code-distortion.net,而不是使用问题跟踪器。

鸣谢

许可证

MIT许可证(MIT)。有关更多信息,请参阅许可证文件