Skip to content

QueryExecuted event not dispatched #3183

Open
@kbiits

Description

@kbiits
  • Laravel-mongodb Version: 5.1.0
  • PHP Version: 8.2.x
  • Database Driver & Version:

Description:

Steps to reproduce

  1. Listen to QueryExecuted
  2. Log the executed query

Expected behaviour

MongoDB driver should dispatch the QueryExecuted event when there's query executions

Actual behaviour

No query executed event dispatched

I'm using open-telemetry laravel auto instrumentation, and I noticed that the mongodb query not logged after I upgrade the driver version from 4.x to 5.1
image

Activity

babaduk47

babaduk47 commented on Oct 25, 2024

@babaduk47

In version 5 this event will be dispatched only if enableQueryLog is enabled for the connection.

Another problem occurs if you have 2 connections using the mongodb driver and EnableQueryLog is enabled for two of them. There will be 2 QueryExecuted events for one query

For example:

DB::connection('tenant')->enableQueryLog();
DB::connection('central')->enableQueryLog();

Site::query()->count(); // dispatched 2 QueryExecuted
kbiits

kbiits commented on Oct 29, 2024

@kbiits
Author

Is this expected ? I think the behavior is different when we're using another type of databases like MySQL or PostgreSQL in laravel

alcaeus

alcaeus commented on Nov 7, 2024

@alcaeus
Member

Sorry for the delay on this. There are two issues described in this ticket:

Issue number one is that no queries are logged. As explained earlier, this needs to be specifically enabled using DB::enableQueryLog or $connection->enableQueryLog(). This was done to fix a performance regression noted in #3166. Note that we don't recommend enabling this in production, both for performance reasons and to avoid logging potentially sensitive data.

Issue number two is that queries are duplicated when using multiple connections. This can occur when using two Laravel database connections that share the underlying connection to the MongoDB deployment. The details of this connection persistence are explained in the driver documentation, but in short, the following code only creates a single connection to the deployment:

$config = [...];
$conn1 = new Connection($config);
$conn2 = new Connection($config);

Since the query log is populated from APM callbacks initiated by the underlying connection, this connection reuse has a negative impact here. However, we don't want to completely disable is, as this connection persistence improves performance in typical PHP environments: while a PHP request is short-lived, the PHP process is kept alive for longer, and thus reusing connections can make requests faster.

I haave created #3197 to fix this and expect this to be released in a 5.1 patch release in the near future, but until then this particular issue can be worked around manually: make sure that the configuration passed to both connections is not identical. This can be accomplished by adding a unique driver option to each config:

[
    'connections' => [
        'tenant' => [
            'name' => 'mongodb',
            'driver' => 'mongodb',
            'dsn' => env('MONGODB_URI', 'mongodb://127.0.0.1/'),
            'database' => env('MONGODB_DATABASE', 'unittest'),
            'options' => [
                // driver_options is passed to the driver and used to determine connection reuse
                'driver_options' => ['connectionName' => 'tenant'],
            ],
        ],
        'central' => [
            'name' => 'mongodb',
            'driver' => 'mongodb',
            'dsn' => env('MONGODB_URI', 'mongodb://127.0.0.1/'),
            'database' => env('MONGODB_DATABASE', 'unittest'),
            'options' => [
                // driver_options is passed to the driver and used to determine connection reuse
                'driver_options' => ['connectionName' => 'central'],
            ],
        ],
    ],
];

The configuration above replicates what the PR will do out of the box in future. Since the two connections now have different driver options (containing a value that remains constant across multiple requests), two different connections to the MongoDB deployment are established, and the query log is properly separated. At the same time, this continues to leverage connection persistence and reuse across multiple requests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @alcaeus@GromNaN@babaduk47@kbiits

        Issue actions

          QueryExecuted event not dispatched · Issue #3183 · mongodb/laravel-mongodb