Skip to content

Profiler - #166

Merged
bfoujols merged 10 commits into
2.xfrom
profiler
Oct 20, 2026
Merged

bfoujols merged 10 commits into
2.xfrom
profiler

Conversation

@bfoujols

Copy link
Copy Markdown
Contributor

This pull request introduces a new code profiler feature to the Edu Framework, leveraging the Excimer PHP extension. The profiler measures the time spent in each PHP function during HTTP requests and integrates with the debug bar for on-demand or automatic profiling. The feature is configurable via environment variables, includes Docker support, and comes with comprehensive documentation and UI enhancements for inspecting profiling data.

The most important changes are:

Core Profiler Feature:

  • Added a code profiler using the Excimer extension, configurable via EDU_PROFILER (off, trigger, on) and EDU_PROFILER_KEEP for retention; profiles are stored in the serv_code_profiles table and can be triggered via the debug bar or URL parameter. [1] [2]
  • Implemented a new internal endpoint GET /edu-code-profile (dev mode only) to fetch profiling data in JSON or Speedscope format for flamegraph visualization.
  • Updated the debug bar UI and profiler page to add a "Code" tab, display top functions, and allow detailed exploration and export of profiling data. [1] [2]

Docker and Environment Integration:

  • Docker images now install Excimer by default (can be disabled with EDU_PROFILER_BUILD=0); Docker Compose and .env.example updated to support new profiler-related variables. [1] [2] [3]

Documentation and Developer Experience:

  • Documentation updated with installation instructions, configuration, usage, and API details for the code profiler, including new sections in the debug bar and installation guides. [1] [2] [3]
  • The CLI config check now reports Excimer as an optional but recommended extension.

Testing and CI:

  • CI workflow updated to install the Excimer extension during testing to ensure profiler compatibility.

Changelog:

  • Both CHANGELOG.md and docs/changelog.md updated to document the new profiler feature and related changes. [1] [2]

bfoujols and others added 3 commits October 17, 2026 22:09
docs(changelog): ajout des versions v2.7.1 à v2.7.3 dans le changelog…
Profilage à la demande du code PHP exécuté par requête HTTP, avec
l'extension Excimer (échantillonnage 0,1 ms, compatible FrankenPHP).

- Docker : extension excimer installée (ARG EDU_PROFILER), variables
  EDU_PROFILER (off|trigger|on) et EDU_PROFILER_KEEP
- CodeProfiler démarré/arrêté par LoadCouchCore, profil rattaché au
  token de la requête et stocké dans serv_code_profiles
- Endpoint /edu-code-profile (résumé, full=1, export Speedscope)
- Bloc Code dans la barre de debug (cookie edu_profile) et onglet Code
  dans le profiler (temps propre/inclusif, appelants/appelés)
- Tests, CI (extension excimer), documentation et CHANGELOG

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017anBiidLUwUBVStBQuAbVn
@deepsource-io

deepsource-io Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

DeepSource Code Review

We reviewed changes in 464ddb0...64e01b1 on this pull request. Below is the summary for the review, and you can see the individual issues we found as inline review comments.

See full review on DeepSource ↗

PR Report Card

Overall Grade   Security  

Reliability  

Complexity  

Hygiene  

Code Review Summary

Analyzer Status Updated (UTC) Details
PHP Oct 20, 2026 6:20p.m. Review ↗
Shell Oct 20, 2026 6:20p.m. Review ↗

Important

AI Review is run only on demand for your team. We're only showing results of static analysis review right now. To trigger AI Review, comment @deepsourcebot review on this thread.

@codacy-production

codacy-production Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 105 complexity · 0 duplication

Metric Results
Complexity 105
Duplication 0

View in Codacy

🟢 Coverage 94.54% diff coverage · +2.27% coverage variation

Metric Results
Coverage variation ✅ +2.27% coverage variation (-1.00%)
Diff coverage ✅ 94.54% diff coverage

View coverage diff in Codacy

Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (1582d9c) 1530 1223 79.93%
Head commit (64e01b1) 1815 (+285) 1492 (+269) 82.20% (+2.27%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#166) 293 277 94.54%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

La décompression d'un profil corrompu convertit l'avertissement en
exception, l'envoie dans les logs PHP et retourne des données vides,
au lieu de le masquer avec l'opérateur @.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017anBiidLUwUBVStBQuAbVn

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Timing accuracy, profiling controls, URL safety, asynchronous rendering, and keyboard accessibility need correction.

8 open issues
What changed in this PR

Adds Excimer-based PHP request profiling to Edu Framework’s debugging tools, with retained profiles and Speedscope export.

Changes:

  • Adds profiling drivers, aggregation, storage, and a development-only endpoint.
  • Integrates profile controls and function inspection into the debug UI.
  • Adds tests, Docker/CI support, configuration, and documentation.
File Description
tests/​Core/​View/​StudooBarreDebugTest.php Tests profiler toolbar states.
tests/​Core/​Profiler/​ExcimerDriverTest.php Tests sampling and request isolation.
tests/​Core/​Profiler/​CodeProfilerTest.php Tests activation and error handling.
tests/​Core/​Profiler/​CodeProfileLoggerTest.php Tests storage and retention.
tests/​Core/​Profiler/​CodeProfileAggregatorTest.php Tests aggregation and call graphs.
tests/​Controller/​DebugCodeProfileControllerTest.php Tests profile responses and exports.
src/​EduFramework/​Core/​View/​studooBarreDebug.php Adds profiling controls and summaries.
src/​EduFramework/​Core/​Profiler/​ProfilerDriverInterface.php Defines the profiling driver contract.
src/​EduFramework/​Core/​Profiler/​NullDriver.php Provides an unavailable-driver fallback.
src/​EduFramework/​Core/​Profiler/​ExcimerDriver.php Implements Excimer sampling.
src/​EduFramework/​Core/​Profiler/​CodeProfiler.php Coordinates request profiling.
src/​EduFramework/​Core/​Profiler/​CodeProfileLogger.php Stores compressed profiles with retention.
src/​EduFramework/​Core/​Profiler/​CodeProfileAggregator.php Computes function metrics and call graphs.
src/​EduFramework/​Core/​Logs/​LogsService.php Retrieves profiles and flags profiled requests.
src/​EduFramework/​Core/​Logs/​LogsInitialiser.php Creates profile storage.
src/​EduFramework/​Core/​Logs/​HttpRequestLogger.php Excludes profile endpoint requests.
src/​EduFramework/​Core/​LoadCouchCore.php Integrates profiling lifecycle and routing.
src/​EduFramework/​Core/​Controller/​Template/​profiler.html.twig Adds the Code inspection view.
src/​EduFramework/​Core/​Controller/​Debug/​DebugCodeProfileController.php Serves profile data and exports.
src/​EduFramework/​Commands/​Extends/​CkeckStack.php Checks Excimer availability.
docs/​installation/​prerequis.md Documents Excimer installation.
docs/​installation/​docker.md Documents Docker profiler settings.
docs/​changelog.md Announces profiling support.
docs/​boost/​debug-bar.md Documents profiling usage and API.
Dockerfile Adds optional Excimer installation.
compose.yaml Passes build and runtime settings.
CHANGELOG.md Announces profiling support.
.github/​workflows/​testing.yml Installs Excimer in CI.
.env.example Adds profiler configuration examples.

Review effort: Balanced

Comment thread src/EduFramework/Core/Controller/Template/profiler.html.twig Outdated
Comment thread src/EduFramework/Core/Controller/Template/profiler.html.twig Outdated
Comment thread src/EduFramework/Core/Controller/Template/profiler.html.twig Outdated
Comment thread src/EduFramework/Core/Controller/Template/profiler.html.twig Outdated
Comment thread src/EduFramework/Core/Controller/Template/profiler.html.twig
Comment thread src/EduFramework/Core/Profiler/CodeProfiler.php Outdated
Comment thread src/EduFramework/Core/View/studooBarreDebug.php
Comment thread src/EduFramework/Core/View/studooBarreDebug.php Outdated
…ocole

Reprend le changement de 2.x (texte des liens Mailpit, DbGate et
phpMyAdmin sans http://) et met à jour le test qui échouait sur la PR.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017anBiidLUwUBVStBQuAbVn
- Temps profilé mesuré avant l'arrêt du driver (agrégation exclue)
- « Désactiver » retire aussi ?_profile=1 de l'URL
- Bloc Code : vrai bouton Désactiver hors du lien, panneau ouvert au focus
- Onglet Code : tri, sélection de fonction et graphe accessibles au clavier
  (boutons natifs)
- Réponses d'un profil qui n'est plus affiché ignorées
- Réouverture de page limitée aux URL du site, avec noopener

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017anBiidLUwUBVStBQuAbVn
…D1002)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017anBiidLUwUBVStBQuAbVn
…PHP-D1002)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017anBiidLUwUBVStBQuAbVn
- DebugCodeProfileController::execute() découpé (export Speedscope et
  détail complet dans des méthodes privées) : complexité sous le seuil
- Variables courtes renommées dans CodeProfileAggregator
- Lecture des superglobales dans CodeProfiler::isRequested() justifiée
  (le profilage démarre avant le routage) et annotée pour PHPMD

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017anBiidLUwUBVStBQuAbVn
…1076)

DeepSource ne voyait pas les appels à la méthode privée fakeDriver(),
qui retournait une classe anonyme. Les deux copies sont remplacées par
une classe FakeProfilerDriver chargée par le bootstrap des tests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017anBiidLUwUBVStBQuAbVn
@bfoujols
bfoujols merged commit 698b838 into 2.x Oct 20, 2026
10 checks passed
@bfoujols
bfoujols deleted the profiler branch October 20, 2026 18:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants