diff --git a/developer_manual/digging_deeper/index.rst b/developer_manual/digging_deeper/index.rst index ef9feadd4..c336f0167 100644 --- a/developer_manual/digging_deeper/index.rst +++ b/developer_manual/digging_deeper/index.rst @@ -32,3 +32,4 @@ Digging deeper security profile user_migration + profiler diff --git a/developer_manual/digging_deeper/profiler.rst b/developer_manual/digging_deeper/profiler.rst new file mode 100644 index 000000000..35da89c13 --- /dev/null +++ b/developer_manual/digging_deeper/profiler.rst @@ -0,0 +1,152 @@ +Profiler +======== + +Nextcloud offers a built-in profiler that can help you identifying performance issues +with your Nextcloud application. This feature is available starting from Nextcloud 24. + +Get the app +----------- + +The profiler application is available on `GitHub `_ +you need to clone the stableX branch if you are using Nextcloud X or master if you are +using the latest development version of Nextcloud. + +Enable the app +-------------- + +.. warning:: + + Do not run this application on production. This will slow down considerably your server + as collection profiling information consume a lot of CPU and memory. + +To enable the app, you can run the following commands: + +.. code-block:: bash + + npm ci && npm run build + occ app:enable profiler + occ profiler:enable # This will also enable the debug mode if not already enabled + +Disable the app +--------------- + +.. code-block:: bash + + occ profiler:disable + occ config:system:set debug --value false --type bool # to also disable the debug mode + + +Using the app +------------- + +When enabled, the profiler application will inject a toolbar at the bottom of the screen. +This toolbar provides you information about the current HTTP request, the time it took to +run, how many database and LDAP requests it did, how often did the cache hit and also +the toolbar track the XHR requests created by the JavaScript frontend. + +.. image:: ../images/profiler-toolbar.png + +You can hover on top of the toolbar information to show more detailed information and also +click on the toolbar to show all the information collected. + +There is for the moment 4 views: + +1. The general request and response view +2. The database queries view +3. The Event view +4. The LDAP queries view + + +The general request and response view +..................................... + +.. image:: ../images/profiler-request.png + +This view gives you general information about the request. For example, +which Controller and method was used, what where the response headers, the +request parameters, ... + +The database queries view +......................... + +This view gives you a list of all the database queries done for your request and +how much time it took for the database to execute. Additionally you can also explain +the query to see if an index was used and also see the backtrace to better understand +why the query was executed. + +.. image:: ../images/profiler-database.png + +It's important to keep the number of queries executed to a minimum since the database +is often a limiting factor in a Nextcloud installation. In particular try to avoid the +`N+1 problem `_ as this can be really slow on big Nextcloud instance and make sure that +your queries are using Database indexes when possible. + +The LDAP View +............. + +This view is very similar to the database queries view and display all the database +queries. + + +The Event View +.............. + +This view display all the logged events and allow you to determine in which part of the +programe the more time is spent. + +.. image:: ../images/profiler-event.png + + +Contributing +------------ + +Contribution to improve the profiler are always welcome. Some future work could include +a way to display Redis queries and not only give a statistic of them. And more type of data +could be collected, e.g. HTTP requests to external APIs, IMAP call for the mail app, usage of +the mailer service, ... + +To extend the profiler app, you will need to provide your own `DataCollector`. + +.. code-block:: php + + data = [ + 'mydata' => 42 + ]; + } + } + + +You also need to register the `DataCollector` in your app `boot` method: + +.. code-block:: php + + getServerContainer(); + + /** @var IProfiler $profiler */ + $profiler = $server->get(IProfiler::class); + $profiler->add(new MyAppDataCollector()); + + +You can find some examples in the `profiler app git repo `_. diff --git a/developer_manual/images/profiler-database.png b/developer_manual/images/profiler-database.png new file mode 100644 index 000000000..ed383d0d7 Binary files /dev/null and b/developer_manual/images/profiler-database.png differ diff --git a/developer_manual/images/profiler-event.png b/developer_manual/images/profiler-event.png new file mode 100644 index 000000000..18f487b1b Binary files /dev/null and b/developer_manual/images/profiler-event.png differ diff --git a/developer_manual/images/profiler-request.png b/developer_manual/images/profiler-request.png new file mode 100644 index 000000000..92178718f Binary files /dev/null and b/developer_manual/images/profiler-request.png differ diff --git a/developer_manual/images/profiler-toolbar.png b/developer_manual/images/profiler-toolbar.png new file mode 100644 index 000000000..95d10588b Binary files /dev/null and b/developer_manual/images/profiler-toolbar.png differ