blackfireio / php-sdk

The Blackfire PHP SDK
https://blackfire.io
MIT License
150 stars 22 forks source link

Memory profile missing when using the Loop Client in consumers #75

Closed rusakov92 closed 1 month ago

rusakov92 commented 2 months ago

Hello,

It seems that there is something wrong with the configuration of our environments and I could not find anything that can help me resolve the issue.

So we install the blackfire agent on our container responsible for running consumers, and we run it in the background. Here are the configurations that we use:

Agent configuration:

cat /etc/blackfire/agent
[blackfire]
server-id=xxx
server-token=xxx
socket=unix:///var/run/blackfire-agent.sock
log-file=stderr
log-level=2
ca-cert=
collector=https://blackfire.io
timeout=15s

Supervisor configuration:

cat /etc/supervisord.d/supervisord_blackfire-agent.conf
[program:blackfire-agent]
command=/usr/bin/blackfire agent:start
numprocs=1
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stderr_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile_maxbytes=0

PHP module:

cat /etc/php.d/zz-blackfire.ini
extension=blackfire.so

[blackfire]
blackfire.agent_socket = unix:///var/run/blackfire-agent.sock
blackfire.log_level = 2
blackfire.apm_enabled = 0

We use the suggested approach form the documentation for profiling the consumer, we achieve it with extension written for the enqueue/enqueue project.

The extension class looks like this:

<?php

declare(strict_types=1);

namespace RGEventBus\Extensions\Enqueue;

use Blackfire\Client;
use Blackfire\ClientConfiguration;
use Blackfire\LoopClient;
use Blackfire\Profile\Configuration;
use DateTime;
use DateTimeZone;
use Enqueue\Consumption\Context\MessageReceived;
use Enqueue\Consumption\Context\PostMessageReceived;
use Enqueue\Consumption\Context\ProcessorException;
use Enqueue\Consumption\MessageReceivedExtensionInterface;
use Enqueue\Consumption\PostMessageReceivedExtensionInterface;
use Enqueue\Consumption\ProcessorExceptionExtensionInterface;
use RGContracts\ThirdParty\Blackfire\BlackfireIntegrationInterface;

use function sprintf;

/**
 * Blackfire Profiling Extension for enqueue package
 *
 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 */
class BlackfireExtension implements MessageReceivedExtensionInterface, PostMessageReceivedExtensionInterface, ProcessorExceptionExtensionInterface
{
    private LoopClient $blackfire;
    private Configuration $profileConfig;

    public function __construct(
        BlackfireIntegrationInterface $blackfireIntegration,
        int $sampleSize,
        LoopClient $blackfire = null,
        Configuration $profileConfig = null,
    ) {
        $this->blackfire = $blackfire ?: new LoopClient(
            new Client(new ClientConfiguration(
                clientId: $blackfireIntegration->getClientId(),
                clientToken: $blackfireIntegration->getClientToken(),
                env: $blackfireIntegration->getEnvironment(),
                userAgentSuffix: $blackfireIntegration->getUserAgentSuffix(),
            )),
            $sampleSize,
        );
        $this->profileConfig = $profileConfig ?: new Configuration();
    }

    public function onMessageReceived(MessageReceived $context): void
    {
        if (!$this->profileConfig->getTitle()) {
            $this->profileConfig->setTitle(
                sprintf('%s (%d)', $context->getProcessor()::class, (new DateTime(timezone: new DateTimeZone('UTC')))->getTimestamp())
            );
        }

        $this->blackfire->startLoop($this->profileConfig);
    }

    public function onPostMessageReceived(PostMessageReceived $context): void
    {
        $this->endSample();
    }

    public function onProcessorException(ProcessorException $context): void
    {
        $this->endSample();
    }

    private function endSample(): void
    {
        $this->blackfire->endLoop();
    }
}

When running the profiler we manage to generate a path trace but memory usage is not recorded. Is there any additional settings we need to pass?

rusakov92 commented 1 month ago

The issue was resolved by our devops team, turns out by default the extension memprof was enabled for us and this prevented blackfire extension to record properly the memory usage, disabling memprof in the PHP INI solved this for us.