Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QueryExecuted event not dispatched #3183

Open
kbiits opened this issue Oct 22, 2024 · 3 comments
Open

QueryExecuted event not dispatched #3183

kbiits opened this issue Oct 22, 2024 · 3 comments

Comments

@kbiits
Copy link

kbiits commented Oct 22, 2024

  • 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

@babaduk47
Copy link

babaduk47 commented Oct 25, 2024

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
Copy link
Author

kbiits commented Oct 29, 2024

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

@alcaeus
Copy link
Member

alcaeus commented Nov 7, 2024

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
Projects
None yet
Development

No branches or pull requests

4 participants