{"id":22064573,"url":"https://github.com/padosoft/laravel-querymonitor","last_synced_at":"2025-10-11T15:31:09.942Z","repository":{"id":265345688,"uuid":"895741523","full_name":"padosoft/laravel-querymonitor","owner":"padosoft","description":"Laravel QueryMonitor is a package for Laravel that allows you to monitor and log:  Slow SQL Queries: Monitors the actual execution time of SQL queries on the database. Slow Eloquent Methods: Monitors the total time taken by Eloquent methods, including PHP processing.","archived":false,"fork":false,"pushed_at":"2024-12-10T01:31:56.000Z","size":323,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-10T04:57:38.811Z","etag":null,"topics":["eloquent","laravel","laravel-package","monitor","monitoring","query","query-builder","slowquery"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/padosoft.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-28T19:58:25.000Z","updated_at":"2024-12-10T01:05:41.000Z","dependencies_parsed_at":null,"dependency_job_id":"f9f57803-a289-4e7a-8e42-979e9c4107bd","html_url":"https://github.com/padosoft/laravel-querymonitor","commit_stats":null,"previous_names":["padosoft/laravel-querymonitor"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/padosoft%2Flaravel-querymonitor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/padosoft%2Flaravel-querymonitor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/padosoft%2Flaravel-querymonitor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/padosoft%2Flaravel-querymonitor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/padosoft","download_url":"https://codeload.github.com/padosoft/laravel-querymonitor/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":236108121,"owners_count":19096084,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["eloquent","laravel","laravel-package","monitor","monitoring","query","query-builder","slowquery"],"created_at":"2024-11-30T19:12:45.496Z","updated_at":"2025-10-11T15:31:04.620Z","avatar_url":"https://github.com/padosoft.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Laravel QueryMonitor\n\n![Laravel QueryMonitor](./resources/images/logo.webp)\n\n[![Latest Version on Packagist](https://img.shields.io/packagist/v/padosoft/laravel-querymonitor.svg?style=flat-square)](https://packagist.org/packages/padosoft/laravel-querymonitor)\n[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](LICENSE.md)\n[![CircleCI](https://circleci.com/gh/padosoft/laravel-querymonitor.svg?style=shield)](https://circleci.com/gh/padosoft/laravel-querymonitor)\n[![Quality Score](https://img.shields.io/scrutinizer/g/padosoft/laravel-querymonitor.svg?style=flat-square)](https://scrutinizer-ci.com/g/padosoft/laravel-querymonitor)\n[![Total Downloads](https://img.shields.io/packagist/dt/padosoft/laravel-querymonitor.svg?style=flat-square)](https://packagist.org/packages/padosoft/laravel-querymonitor)\n\nLaravel QueryMonitor is a package for Laravel that allows you to monitor and log:\n- \n- **Slow SQL Queries**: Monitors the actual execution time of SQL queries on the database.\n- **Slow Eloquent Methods**: Monitors the total time taken by Eloquent methods, including PHP processing.\n- **Total Number of Queries**: track the total number of SQL queries executed during a single HTTP request, Artisan command, or CLI execution.\n\n## Requirements\n- \"php\": \"\u003e=8.1\",\n- \"illuminate/support\": \"^10.0|^11.0\",\n- \"illuminate/database\": \"^10.0|^11.0\",\n- \"illuminate/log\": \"^10.0|^11.0\",\n- \"illuminate/config\": \"^10.0|^11.0\"\n\n## Installation\nYou can install the package via Composer:\n\n```bash\ncomposer require padosoft/laravel-querymonitor\n```\nPublish the configuration and migrations:\n\n```bash\nphp artisan vendor:publish --provider=\"Padosoft\\QueryMonitor\\QueryMonitorServiceProvider\" --tag=\"config\"\n```\n\n## Configuration\nThe package configuration file is located at config/querymonitor.php. \nYou can adjust the settings to suit your application's needs:\n```php\nreturn [\n\n    'query' =\u003e [\n        'attiva' =\u003e env('QUERYMONITOR_QUERY_ATTIVA', true),\n        'maxExecutionTime' =\u003e env('QUERYMONITOR_QUERY_MAX_EXECUTION_TIME', 100), // in milliseconds\n        'sqlRegEx' =\u003e env('QUERYMONITOR_QUERY_SQL_REGEX', '^SELECT.*$'),\n    ],\n\n    'query_builder' =\u003e [\n        'attiva' =\u003e env('QUERYMONITOR_BUILDER_ATTIVA', true),\n        'maxExecutionTime' =\u003e env('QUERYMONITOR_BUILDER_MAX_EXECUTION_TIME', 200), // in milliseconds\n        'methodRegEx' =\u003e env('QUERYMONITOR_BUILDER_METHOD_REGEX', '^(get|first)$'),\n    ],\n\n    'total_queries' =\u003e [\n    \n        /*\n         * Whether to enable total query monitoring.\n         */\n        'attiva' =\u003e env('QUERYMONITOR_TOTAL_QUERIES_ATTIVA', true),\n    \n        /*\n         * Maximum allowed total queries per request/command.\n         * If this threshold is exceeded, a warning is logged.\n         */\n        'maxTotalQueries' =\u003e env('QUERYMONITOR_MAX_TOTAL_QUERIES', 500),\n    \n        /*\n         * A regex to filter which contexts to monitor.\n         * - For HTTP requests, this regex will be matched against the full URL (including query string).\n         * - For Artisan commands, it will be matched against the command name.\n         * - For CLI contexts, it can be matched against the script name.\n         * If unset or empty, all contexts are monitored.\n         * Example: '^/api/.*$' to monitor only requests under /api/\n         */\n        'traceRegEx' =\u003e env('QUERYMONITOR_TOTAL_QUERIES_REGEX', null),\n    ],\n];\n```\n\n\n## Usage\n\nOnce installed and configured, the package will automatically monitor and log SQL queries and Eloquent methods based on the provided settings.\nIf you setting query total count to true, the package will automatically monitor and log total queries count.\n\n### Monitoring SQL Queries\n- **What it monitors**: The execution time of SQL queries on the database.\n- **How it works**: Uses DB::listen() to listen to all executed queries.\n- **When it logs**: If the execution time exceeds maxExecutionTime and the query matches sqlRegEx.\n\n**Example Log Entry:**\n\n```bash\n[2024-11-28 12:34:56] local.INFO: QueryMonitor Slow SQL query detected {\"query\":\"SELECT * FROM `users` WHERE `id` = '1'\",\"execution_time\":\"150 ms\"}\n```\n\n### Monitoring Eloquent Methods\n- **What it monitors**: The total execution time of Eloquent methods, including PHP processing.\n- **How it works**: Extends Eloquent's Builder and overrides key methods.\n- **When it logs**: If the execution time exceeds maxExecutionTime and the method name matches methodRegEx.\n\n**Example Log Entry:**\n\n```json\n{\n    \"method\": \"get\",\n    \"execution_time\": \"250 ms\",\n    \"query\": \"SELECT * FROM `articles` WHERE `status` = 'published'\",\n    \"arguments\": [\n        [\"*\"]\n    ],\n    \"stack_trace\": [\n        {\n            \"file\": \"/path/to/your/project/app/Models/QueryBase.php\",\n            \"line\": 123,\n            \"class\": \"App\\\\Models\\\\QueryBase\",\n            \"function\": \"getPublishedArticles\"\n        },\n        {\n            \"file\": \"/path/to/your/project/app/Http/Controllers/ArticleController.php\",\n            \"line\": 45,\n            \"class\": \"App\\\\Http\\\\Controllers\\\\ArticleController\",\n            \"function\": \"index\"\n        },\n        // ... additional frames up to the maximum stack depth\n    ]\n}\n```\n\n## Difference Between Monitoring SQL Queries and Eloquent Methods\n**SQL Queries**\n- **Database-Focused**: Measures the time taken by the database to execute a query.\n- **Usefulness**: Identifies unoptimized queries or database-level issues.\n- **Example**: A query that takes 500 ms to execute on the database will be logged if it exceeds the threshold.\n\n**Eloquent Methods**\n- **Application-Focused**: Measures the total time taken by an Eloquent method, including PHP processing.\n- **Usefulness**: Identifies bottlenecks in the application due to heavy PHP processing.\n- **Example**: A get() method that retrieves many records and takes 800 ms to complete will be logged if it exceeds the threshold, even if the underlying SQL query is fast.\n\n**Why Both?**\n- **Complete Visibility**: By monitoring both SQL queries and Eloquent methods, you get a full view of performance, from the database to the application.\n- **Effective Optimization**: You can identify if performance issues are due to the database or PHP code.\n\n## Practical Example\nSuppose we have the following code:\n\n```php\n$users = User::all();\n```\n\n- **SQL Query Execution Time**: 50 ms.\n- **Total Eloquent Method Time**: 600 ms.\n\n**Analysis:**\n\n- **Fast SQL Query**: The database returns the data quickly.\n- **Slow PHP Processing**: Creating User objects for many records takes time.\n- **Action**: Consider using pagination or limiting the selected fields.\n\n\n## Monitoring the Total Number of Queries\nIn addition to monitoring slow queries and slow Eloquent methods, laravel-querymonitor allows you to track the total number of SQL queries executed during a single HTTP request, Artisan command, or CLI execution. \nThis helps you identify cases where, although each individual query may be performant, the total number of queries is excessively high, potentially causing performance bottlenecks.\n\n**Why Monitor Total Queries?**\nEven if every single query is fast, executing too many queries per request or command can cause unnecessary overhead. \nBy monitoring the total query count, you can quickly identify scenarios where your application issues an excessive number of queries (for example, 2,000 queries in a single request), \npinpointing areas that need optimization (e.g., using eager loading, caching, or refining data retrieval logic).\n\n**How It Works**\n- For HTTP requests, a middleware hooks into the Laravel request lifecycle. It resets a query counter at the start of the request and increments it every time a query is executed. \nAt the end of the request, if the total number of queries exceeds the configured threshold, a warning is logged.\n- For Artisan commands, the package listens to the CommandStarting and CommandFinished events. \nIt resets the counter before the command runs and checks the final count after the command completes.\n- For CLI contexts (other non-command CLI scripts), you can manually integrate by resetting and checking counts in your own script logic.\n\n### Configuration\nAll configuration options are defined in the querymonitor.php config file under the total_queries key:\n```php\n'total_queries' =\u003e [\n\n    /*\n     * Whether to enable total query monitoring.\n     */\n    'attiva' =\u003e env('QUERYMONITOR_TOTAL_QUERIES_ATTIVA', true),\n\n    /*\n     * Maximum allowed total queries per request/command.\n     * If this threshold is exceeded, a warning is logged.\n     */\n    'maxTotalQueries' =\u003e env('QUERYMONITOR_MAX_TOTAL_QUERIES', 500),\n\n    /*\n     * A regex to filter which contexts to monitor.\n     * - For HTTP requests, this regex will be matched against the full URL (including query string).\n     * - For Artisan commands, it will be matched against the command name.\n     * - For CLI contexts, it can be matched against the script name.\n     * If unset or empty, all contexts are monitored.\n     * Example: '^/api/.*$' to monitor only requests under /api/\n     */\n    'traceRegEx' =\u003e env('QUERYMONITOR_TOTAL_QUERIES_REGEX', null),\n],\n```\n\n### Enabling Total Query Monitoring for HTTP Requests\nTo track the total number of queries for HTTP requests, the package provides a `TrackTotalQueriesMiddleware`. \nThis middleware must be added as the first middleware in the global middleware stack. \n\nBy doing so, it can:\n\n- **Set up tracking before any other middleware or controllers run**, ensuring that all queries executed during the request lifecycle are counted.\n- **Perform a final check after the response is generated**, running last in the outbound cycle, so that it includes queries made by all subsequent middleware, controllers, and operations performed downstream.\n\n**How to add it:**\n\nIn your `app/Http/Kernel.php`, ensure that `\\Padosoft\\QueryMonitor\\Middleware\\TrackTotalQueriesMiddleware::class` appears at the top of the `$middleware` array:\n\n```php\nprotected $middleware = [\n                        \\Padosoft\\QueryMonitor\\Middleware\\TrackTotalQueriesMiddleware::class,\n                        // ... other global middleware ...\n                        ];\n```\n\nBy placing the TrackTotalQueriesMiddleware first, you guarantee comprehensive coverage of every query executed during the request lifecycle. \nOnce the request is fully processed, the middleware checks the total query count and logs a warning if it exceeds the configured threshold.\n\n\n### Examples of Logs\n- **1. HTTP Request Exceeding the Query Limit**\n\nIf a request executes more than the allowed number of queries, a log entry is created after the response is generated:\n\n```text\n[2024-12-09 10:23:45] local.WARNING: Exceeded maximum total queries: 2020 queries (max: 500). {\"context\":\"request\",\"url\":\"https://example.com/products?category=shoes\",\"method\":\"GET\"}\n```\n- context: request\n- url: The full URL of the request, including query parameters.\n- method: The HTTP method (e.g., GET, POST).\n\n- **2. Artisan Command Exceeding the Query Limit**\n\nIf an Artisan command triggers more queries than allowed, a warning is logged once the command finishes:\n\n```text\n[2024-12-09 10:25:10] local.WARNING: Exceeded maximum total queries: 1200 queries (max: 500). {\"context\":\"command\",\"command\":\"cache:clear\",\"arguments\":[\"artisan\",\"cache:clear\"]}\n```\n- context: command\n- command: The Artisan command name.\n- arguments: The arguments passed to the command.\n\n- **3. CLI Context Exceeding the Query Limit**\n\nFor CLI contexts (non-Artisan commands), if you set up tracking manually and the query count is exceeded, you'll see a log like:\n\n```text\n[2024-12-09 10:26:00] local.WARNING: Exceeded maximum total queries: 3000 queries (max: 500). {\"context\":\"cli-service\",\"script\":\"myscript.php\",\"arguments\":[\"--option\",\"value\"]}\n```\n- context: cli-service\n- script: The name of the CLI script being executed.\n- arguments: The arguments passed to the script.\n\n**Using the Regex Filter**\nIf you provide a traceRegEx:\n\n- For HTTP requests, the package only monitors requests whose URLs match the regex.\n- For Artisan commands, only the commands that match the regex pattern are monitored.\n- For CLI contexts, only scripts whose name matches the regex are tracked.\n\nFor example, if you set:\n\n```php\n'traceRegEx' =\u003e '^/api/.*$',\n```\nonly requests matching /api/... URLs are monitored.\n\n**Summary**\nBy configuring and enabling total query monitoring, you gain deeper insights into your application's performance, identifying excessive query usage patterns that can be addressed to improve overall efficiency. \nThis is especially useful in complex, large-scale projects where minor optimizations in query counts can lead to significant performance gains.\n\n\n\n## Final Notes\n- **Performance Optimization**: Remember that enabling monitoring can impact performance. It's advisable to use it in development environments or carefully monitor the impact in production.\n- **Dynamic Configuration**: You can modify the settings in real-time using environment variables or by updating the configuration file.\n- **Extensibility**: The package can be extended to include additional features or to suit specific needs.\n\n\n## Testing\nThe package includes unit tests to ensure all components function correctly. \nRun tests using PHPUnit:\n\n```bash\ncomposer test\n```\n\n## Change log\n\nPlease see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.\n\n## Testing\n\n``` bash\ncomposer test\n```\n\n## Contributing\n\nPlease see [CONTRIBUTING](CONTRIBUTING.md) for details.\n\n## Security\n\nIf you discover any security related issues, please email instead of using the issue tracker.\n\n## Credits\n- [Lorenzo Padovani](https://github.com/lopadova)\n- [All Contributors](../../contributors)\n\n## About Padosoft\nPadosoft (https://www.padosoft.com) is a software house based in Florence, Italy. Specialized in E-commerce and web sites.\n\n## License\n\nThe MIT License (MIT). Please see [License File](LICENSE.md) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpadosoft%2Flaravel-querymonitor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpadosoft%2Flaravel-querymonitor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpadosoft%2Flaravel-querymonitor/lists"}