PHP8 應(yīng)用程序性能監(jiān)控

2024-04-08 10:15 更新

MongoDB 驅(qū)動(dòng)程序包含一個(gè)事件訂閱者 API,它允許應(yīng)用程序 監(jiān)視與 ? 服務(wù)器發(fā)現(xiàn)和監(jiān)視規(guī)范相關(guān)的命令和內(nèi)部活動(dòng)。 本教程將演示使用 MongoDB\Driver\Monitoring\CommandSubscriber 接口進(jìn)行命令監(jiān)視。

MongoDB\Driver\Monitoring\CommandSubscriber 接口定義了三種方法:、 和 。 這三種方法中的每一種都接受相應(yīng)事件的特定類的單個(gè)參數(shù)。例如,的參數(shù) 是 MongoDB\Driver\Monitoring\CommandSucceededEvent 對(duì)象。commandStartedcommandSucceededcommandFailedeventcommandSucceeded$event

在本教程中,我們將實(shí)現(xiàn)一個(gè)訂閱服務(wù)器,該訂閱服務(wù)器創(chuàng)建所有列表 查詢配置文件及其花費(fèi)的平均時(shí)間。

訂戶類基架

我們從訂閱者的框架開始:

<?php

class QueryTimeCollector implements \MongoDB\Driver\Monitoring\CommandSubscriber
{
    public function commandStarted( \MongoDB\Driver\Monitoring\CommandStartedEvent $event ): void
    {
    }

    public function commandSucceeded( \MongoDB\Driver\Monitoring\CommandSucceededEvent $event ): void
    {
    }

    public function commandFailed( \MongoDB\Driver\Monitoring\CommandFailedEvent $event ): void
    {
    }
}

?>

注冊(cè)訂閱者

實(shí)例化 subscriber 對(duì)象后,需要向 駕駛員監(jiān)控系統(tǒng)。這是通過調(diào)用MongoDB\Driver\Monitoring\addSubscriber()或MongoDB\Driver\Manager::addSubscriber()進(jìn)行注冊(cè)來完成的 分別是全局訂閱者或具有特定經(jīng)理的訂閱者。

<?php

\MongoDB\Driver\Monitoring\addSubscriber( new QueryTimeCollector() );

?>

實(shí)現(xiàn)邏輯

注冊(cè)對(duì)象后,剩下的唯一事情就是實(shí)現(xiàn)邏輯 在 subscriber 類中。關(guān)聯(lián)構(gòu)成 成功執(zhí)行的命令(commandStarted 和 commandSucceeded),每個(gè) Event 對(duì)象公開一個(gè)字段。requestId

為了記錄每個(gè)查詢形狀的平均時(shí)間,我們將首先檢查 commandStarted 事件中的命令。然后,我們將添加 屬性的項(xiàng),由 its 和 索引,其值表示查詢形狀。findpendingCommandsrequestId

如果我們收到一個(gè)相同的對(duì)應(yīng) commandSucceeded 事件,我們將事件的持續(xù)時(shí)間 (from ) 添加到總時(shí)間中,并遞增 操作計(jì)數(shù)。requestIddurationMicros

如果遇到相應(yīng)的 commandFailed 事件,我們只需刪除 從酒店進(jìn)入。pendingCommands

<?php

class QueryTimeCollector implements \MongoDB\Driver\Monitoring\CommandSubscriber
{
    private $pendingCommands = [];
    private $queryShapeStats = [];

    /* Creates a query shape out of the filter argument. Right now it only
     * takes the top level fields into account */
    private function createQueryShape( array $filter )
    {
        return json_encode( array_keys( $filter ) );
    }

    public function commandStarted( \MongoDB\Driver\Monitoring\CommandStartedEvent $event ): void
    {
        if ( array_key_exists( 'find', (array) $event->getCommand() ) )
        {
            $queryShape = $this->createQueryShape( (array) $event->getCommand()->filter );
            $this->pendingCommands[$event->getRequestId()] = $queryShape;
        }
    }

    public function commandSucceeded( \MongoDB\Driver\Monitoring\CommandSucceededEvent $event ): void
    {
        $requestId = $event->getRequestId();
        if ( array_key_exists( $requestId, $this->pendingCommands ) )
        {
            $this->queryShapeStats[$this->pendingCommands[$requestId]]['count']++;
            $this->queryShapeStats[$this->pendingCommands[$requestId]]['duration'] += $event->getDurationMicros();
            unset( $this->pendingCommands[$requestId] );
        }
    }

    public function commandFailed( \MongoDB\Driver\Monitoring\CommandFailedEvent $event ): void
    {
        if ( array_key_exists( $event->getRequestId(), $this->pendingCommands ) )
        {
            unset( $this->pendingCommands[$event->getRequestId()] );
        }
    }

    public function __destruct()
    {
        foreach( $this->queryShapeStats as $shape => $stats )
        {
            echo "Shape: ", $shape, " (", $stats['count'], ")\n  ",
                $stats['duration'] / $stats['count'], "μs\n\n";
        }
    }
}

$m = new \MongoDB\Driver\Manager( 'mongodb://localhost:27016' );

/* Add the subscriber */
\MongoDB\Driver\Monitoring\addSubscriber( new QueryTimeCollector() );

/* Do a bunch of queries */
$query = new \MongoDB\Driver\Query( [
    'region_slug' => 'scotland-highlands', 'age' => [ '$gte' => 20 ]
] );
$cursor = $m->executeQuery( 'dramio.whisky', $query );

$query = new \MongoDB\Driver\Query( [
    'region_slug' => 'scotland-lowlands', 'age' => [ '$gte' => 15 ]
] );
$cursor = $m->executeQuery( 'dramio.whisky', $query );

$query = new \MongoDB\Driver\Query( [ 'region_slug' => 'scotland-lowlands' ] );
$cursor = $m->executeQuery( 'dramio.whisky', $query );

?>


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)