Releases: nowo-tech/PerformanceBundle
Release v2.0.7
feat: Enhance access records with route parameters and path
- Added
route_params(JSON) androute_path(VARCHAR 2048) fields toRouteDataRecordfor improved access tracking. - Updated the Access Records UI to display a clickable Path column and include parameters in CSV/JSON exports.
- Modified related services, controllers, and message handlers to support the new fields.
- Updated documentation and changelog to reflect these changes and provide migration instructions.
Changelog
Added
- Access records: route params and path – Each
RouteDataRecordnow stores the route parameters (route_params, JSON) and the request path (route_path, VARCHAR 2048) for the specific access. The Access Records table shows a Path column with a clickable link to the exact URL that was hit (e.g./user/123). When path is not available, params are shown as JSON. CSV and JSON exports includepathandparams. Runphp bin/console nowo:performance:create-records-table --updateornowo:performance:sync-schemaafter updating.
See UPGRADING for migration steps.
Commits
Release v2.0.6
feat: Add symfony/yaml dependency and enhance cache configuration
- Added
symfony/yamlas a required dependency for loading YAML service configurations. - Introduced a dedicated cache configuration option for the performance bundle, allowing users to specify a custom cache pool.
- Updated documentation to reflect the new cache features and configuration options.
- Enhanced the changelog and upgrading guide with details on the new cache pool and its usage.
Changelog
Added
- Dedicated cache pool – The bundle now registers a dedicated filesystem cache pool
nowo_performance.cache(TTL 1h) viaframework.cache.pools.PerformanceCacheServiceuses this pool by default instead ofcache.app, isolating bundle cache from application cache. - Cache configuration – New
nowo_performance.cache.pooloption to override the cache pool (e.g.cache.appto share with the application). See CONFIGURATION. - TableStatusChecker: cache getMissingColumns –
getMissingColumns()results are now cached (filesystem, 5 min TTL) to reduceinformation_schemaqueries. UsesCACHE_TTL_SECONDSconstant (300s) shared withtableExistsandtableIsComplete. - symfony/yaml – Added as explicit
requiredependency forYamlFileLoaderwhen loading services config.
Added (tests)
- TableStatusCheckerTest –
testGetMissingColumnsReturnsCachedValueWhenCacheHit,testTableExistsWhenNoCacheAndDatabaseReturnsTrue,testRecordsTableExistsReturnsFalseWhenConnectionFails, and additional cache/exception path tests. - PerformanceExtensionTest –
testLoadCustomCachePoolConfiguration. - ConfigurationTest – Default
cache.poolassertion. - RouteDataRecordRepositoryTest –
testGetStatisticsByHourWithRouteNameAndStatusCodeFilters. - PerformanceAnalysisServiceTest – Correlations, efficiency with null metrics, traffic distribution with single route.
- RouteDataWithAggregatesTest –
getStatusCodesnull,getStatusCodeCountfor non-existent code,getStatusCodeRatiowith empty codes. - PerformanceMetricsServiceGetRouteDataAndRoutesByEnvTest –
testSetMessageBusAcceptsNull,testSetMessageBusAcceptsObject.
See UPGRADING for migration steps.
Commits
- feat: Add symfony/yaml dependency and enhance cache configuration (189fe1a)
- feat: Add cache configuration to performance bundle (060f8b4)
- test: Enhance unit tests for command help, form submissions, and performance metrics (ee7fdc8)
- Merge branch 'main' of github.com:nowo-tech/PerformanceBundle into main (9767735)
- test: Add unit tests for handling stage and test environments (317d80b)
- Apply PHP CS Fixer fixes [skip ci] (6529834)
- Merge branch 'main' of github.com:nowo-tech/PerformanceBundle into main (7ad358f)
- refactor: Update Makefile and PHPUnit configuration for improved test execution (5bd3cd3)
- Apply PHP CS Fixer fixes [skip ci] (4ba767e)
Release v2.0.5
Release 2.0.5: docs and release notes
Changelog
Added
- Access records: logged-in user – When access records and
track_userare enabled, eachRouteDataRecordcan store the logged-in user:user_identifier(e.g. username, email fromUserInterface::getUserIdentifier()) anduser_id(stringified ID fromUser::getId()if present). New columnsuser_identifier(VARCHAR 255, nullable) anduser_id(VARCHAR 64, nullable) onroutes_data_records. Config:nowo_performance.track_user(defaultfalse). The Access Records UI shows a User column; CSV and JSON exports include both fields. Runphp bin/console nowo:performance:create-table --updateornowo:performance:sync-schemaafter updating. - Makefile: validate-translations – New target
make validate-translationsruns the translation YAML validation script inside the PHP container (starts the container if needed). - Translation validation: block-aware duplicate detection – The script
scripts/validate-translations-yaml.phpnow treats duplicate keys only when they appear in the same parent block. The same key under different parents (e.g.statistics.max_queriesandfilters.max_queries) is no longer reported as a duplicate.
Fixed
- Security autowiring (Symfony 7/8) – Resolved "Cannot autowire service PerformanceMetricsSubscriber: argument $security has type Symfony\Component\Security\Core\Security but this class was not found." The Security dependency is now optional (
?security.helper); the bundle works when SecurityBundle is not installed or when using Symfony 7+ where the old Security class was removed. User tracking is applied only whentrack_useris true and the security helper is available.
Added (tests)
- PerformanceMetricsSubscriberSecurityTest – Tests for
track_userwith security null, with user (identifier/id), and user withoutgetId(). - ValidateTranslationsYamlTest – Nested-block duplicate detection, three-level nesting, comments/blank lines, default dir when no argument, duplicate at root level.
- RecordMetricsMessageTest – getUserIdentifier/getUserId getters; RouteDataRecordTest – userIdentifier/userId setters and getters.
- DeleteRecordsByFilterRequestTest, StatisticsEnvFilterTest, ArrayExtensionTest, PerformanceAlertTest, RecordFiltersTest, NowoPerformanceBundleTest, RouteDataWithAggregatesTest, Event/Twig component tests – Additional edge-case and coverage tests.
See UPGRADING for migration steps.
Commits
- Release 2.0.5: docs and release notes (4948bba)
Release v2.0.4
docs: release 2.0.4 - add HTTP Referer tracking and per-route access record saving option
- Introduced a new column
refererinroutes_data_recordsto store the HTTP Referer header. - Added a feature to disable saving access records for individual routes via a checkbox in the review/config modal.
- Updated documentation to reflect these changes and provided migration steps for upgrading.
Changelog
Added
- Access records: HTTP Referer – When access records are enabled, each
RouteDataRecordnow stores the HTTPRefererheader (page that linked to the request). New columnreferer(VARCHAR 2048, nullable) onroutes_data_records. The Access Records UI shows a Referer column (with link); CSV and JSON exports include the referer. Runphp bin/console nowo:performance:create-table --updateornowo:performance:sync-schemaafter updating. - Per-route: disable saving access records – When access records are enabled, you can now turn off saving access records for individual routes. In the review/config modal for each route (same form as "Mark as reviewed"), a checkbox "Save access records for this route" appears. If unchecked, the bundle still updates aggregate metrics (RouteData) for that route but does not create new
RouteDataRecordrows. Useful for high-traffic or internal routes where you want aggregates but not per-request history. New columnsave_access_records(boolean, default true) onroutes_data. Runphp bin/console nowo:performance:create-table --updateornowo:performance:sync-schemaafter updating.
See UPGRADING for migration steps.
Commits
Release v2.0.3
docs: release 2.0.3 - fix getMainRequest compatibility
Changelog
Fixed
- Request ID on sub-requests – Fixed "undefined method getMainRequest of Request" when running on Symfony or HttpFoundation versions where
Request::getMainRequest()does not exist. The subscriber now usesRequestStack::getMainRequest()(orgetMasterRequest()on older Symfony) to resolve the main request for sharing the request ID with sub-requests. No schema or config changes.
Commits
Release v2.0.2
docs: release 2.0.2 - changelog, upgrading, commands
Changelog
Added
- Request ID deduplication – When access records are enabled, the bundle assigns a unique
request_idper HTTP request (shared between main and sub-requests). At most oneRouteDataRecordis created per logical request, avoiding duplicate entries when multipleTERMINATEevents fire (e.g. main request + fragment). routes_data_records– New optional columnrequest_id(VARCHAR 64, nullable, unique). Existing records keeprequest_id = NULL. Runphp bin/console nowo:performance:sync-schemaor your Doctrine migrations after updating.- Translation YAML validation – Script
scripts/validate-translations-yaml.phpchecks translation YAML files for valid syntax and duplicate keys. CI runs it in the test job. Composer:composer validate-translations; included incomposer qa. - Collector & diagnose: records table status – When
enable_access_recordsis true, the Web Profiler Performance panel shows Access Records Table (exists, complete, missing columns). TableStatusChecker gainsrecordsTableExists(),recordsTableIsComplete(),getRecordsMissingColumns(),getRecordsTableName(),isAccessRecordsEnabled(). CLInowo:performance:diagnoseincludes a Database Tables section (main table + records table) with missing columns. Missingrequest_id(or any entity column) is detected and the UI suggests runningsync-schemaorcreate-records-table --update.
Fixed
- CreateRecordsTableCommand – Creating the records table from scratch now sets
AUTO_INCREMENTon theidcolumn for MySQL/MariaDB.--updatenow creates missing unique constraints (e.g.uniq_record_request_idonrequest_id) and uses the same operation order as the main table (Drop → Add → Update). - CreateTableCommand –
addMissingIndexes()now usesgetSchemaManager()for DBAL 2.x compatibility.
See UPGRADING for migration steps.
Commits
Release v2.0.1
Release 2.0.1: edit review, UI fixes, chart init, docs
Changelog
Added
- Review system: edit existing review – Routes already marked as reviewed can now be edited. An "Edit review" button (pencil icon) appears for reviewed routes; the same modal opens with the form pre-filled with current values (Queries improved, Time improved). Modal title and submit button label differ when editing ("Edit Review" / "Update Review"). Flash message "Review updated" when saving an existing review. New translation keys in all locales:
routes_table.edit_review,review.modal_title_edit,review.edit_review,flash.review_updated.
Fixed
- Routes table: sort by Memory usage – Sorting by the Memory usage column now uses the numeric value (int bytes).
PerformanceController::getSortValue()now includes amemoryUsagecase so the table orders correctly instead of falling back to request time. - Charts: initialization after DOM – Chart scripts (dashboard Performance Trends, Statistics histograms, Charts component) run inside
DOMContentLoadedand check forChartand canvas before use. Avoids console errors when Chart.js is loaded in{% block scripts %}after the inline script in the content.
Changed
- Routes table: Status Codes and Access Count – Removed the "Total responses" line from the Status Codes column (same value as Access Count). Status Codes and Access Count columns are now adjacent for easier reading.
- Routes table: View access records – The link to access records now uses the Symfony UX Icons eye icon (
bi:eye) instead of the 👁 emoji.
Commits
Release v2.0.0
chore: unify CHANGELOG and docs for v2.0.0 release
Changelog
Breaking: Entity normalization. See V2_MIGRATION.md and ENTITY_NORMALIZATION_PLAN.md.
Removed (from RouteData)
totalQueries,requestTime,queryTime,memoryUsage,accessCount,statusCodes,updatedAt— metrics move to aggregates fromRouteDataRecordor a dedicated aggregates layer.
Added (RouteDataRecord)
totalQueries,queryTime,memoryUsageper access record.
Added
- Export access records (CSV / JSON) – On the Access Records page, export individual
RouteDataRecordrows via Export Records (CSV) and Export Records (JSON). Uses the same filters as the records view (env, date range, route, status code, query time, memory). Requiresenable_access_records: true. New routes:nowo_performance.export_records_csv,nowo_performance.export_records_json. - Access Records: query time, memory, filters – Access Records page shows columns Queries, Query Time, Memory (formatted). Form filters: min/max query time (s), min/max memory (MB). Export and pagination preserve these filter params. RecordFilters and RouteDataRecordRepository support
minQueryTime,maxQueryTime,minMemoryUsage,maxMemoryUsage. - Index dashboard: Status Codes column – Routes table shows status codes with percentage and total responses per code (descending), only codes that have records. Total responses and error-rate warning when >10% non-2xx.
- Schema sync command –
nowo:performance:sync-schemasyncs bothroutes_dataandroutes_data_recordswith entity metadata (add missing, alter differing, optional drop with--drop-obsolete). Primary keyidis never dropped. - Drop obsolete option –
--drop-obsoletefornowo:performance:create-table,nowo:performance:create-records-table, andnowo:performance:sync-schema. Drops columns that exist in DB but not in the entity. - Create-records-table column updates –
--updatenow also alters existing columns when type, nullable or default differ (previously only added missing columns). - Translations – New/updated keys for status codes, total responses, error rate, query time, memory usage, min/max query time and memory in all supported locales.
Changed
- RouteData only holds identity (env, name, httpMethod, params) and metadata (createdAt, lastAccessedAt, reviewed, reviewedAt, reviewedBy, queriesImproved, timeImproved). Dashboard, API, notifications and exports use aggregated data or records instead of RouteData getters for metrics.
- Collector diagnostics when disabled – Web Profiler Performance panel shows full diagnostics even when tracking is disabled (route, request time, query count, query time, environment, processing mode, table status, dependency status). Subscriber always sets
configured_environments,current_environment, androute_namein the collector before any early return. - RebuildAggregatesCommand updates RouteData
lastAccessedAtfrom RouteDataRecord; metrics live in records.
Fixed
- Advanced Performance Statistics – Histograms not rendering: chart script moved to
scripts_extrablock so Chart.js is loaded before use; creation wrapped in IIFE withtypeof Chart !== 'undefined'check. - Access statistics with empty route filter – When
route=was present in the URL, the controller passed an empty string and no rows matched. Empty route is now normalized tonullso statistics are returned for all routes.
Added (tests)
- Models:
RecordFiltersTest(query time/memory filters),DeleteRecordsByFilterRequestTest(min/max query time and memory),StatisticsEnvFilterTest,ClearPerformanceDataRequestTest. - Form types:
StatisticsEnvFilterTypeTest,ClearPerformanceDataTypeTest,DeleteRecordTypeTest; extendedRecordFiltersTypeTestandDeleteRecordsByFilterTypeTestfor new fields. - Repository:
RouteDataRecordRepositoryAdvancedTest–getPaginatedRecordsanddeleteByFilterwith query time and memory filters; explicit calls with full parameter list. - DataCollector:
disabledReason,configuredEnvironments/currentEnvironment, diagnostics when disabled, table/dependency status,getProcessingMode. PerformanceMetricsSubscriberCollectorDiagnosticsTest,RouteDataWithAggregatesTest,SyncSchemaCommandTest.
Documentation
- COMMANDS.md:
--drop-obsoleteandnowo:performance:sync-schema. - INSTALLATION.md: Step 5 lists main commands; note on sync-schema after entity changes.
- UPGRADING.md: "Upgrading to 2.0.0" with migration steps; removed duplicate sections.
- PHPDoc: all bundle PHP docblocks and comments in English (constructors, params, returns, form types, models, commands, examples).
Commits
- chore: unify CHANGELOG and docs for v2.0.0 release (6ec2bfc)
Release v1.0.8
feat: Update default environments to include production and enhance configuration
- Changed the default value for
environmentsin the performance tracking configuration to includeprod, ensuring production is tracked by default. - Removed the deprecated
when@dev:condition from the configuration, allowing it to apply to all environments. - Updated demo project configurations to support
APP_ENV=prod. - Added extensive test coverage for environment handling and configuration defaults.
- Updated documentation to reflect changes in default environments and migration steps for upgrading.
Changelog
Changed
- Default environments now include production - Changed default value for
environmentsconfiguration- Default changed from
['dev', 'test']to['prod', 'dev', 'test'] - Bundle now tracks performance in production by default
- This is more appropriate for a performance monitoring bundle
- Existing configurations are not affected (only applies when not explicitly configured)
- Fixes issue where production environments were not tracked by default
- Default changed from
Fixed
- Demo environments configuration - Fixed demo projects to allow
APP_ENV=prod- Updated
docker-compose.ymlin both Symfony 7 and Symfony 8 demos - Changed from hardcoded
APP_ENV=devtoAPP_ENV=${APP_ENV:-dev} - Added
APP_DEBUG=${APP_DEBUG:-0}for better environment control - Updated Makefiles to include
APP_DEBUG=1in default.envcreation - Removed
when@dev:condition fromnowo_performance.yamlin demos - Configuration now applies to all environments, not just
dev
- Updated
Added
- Comprehensive environment configuration tests - Added extensive test coverage for environment handling
- 5 tests for
PerformanceExtensionenvironment defaults and configurations - 6 tests for
Configurationenvironment defaults and edge cases - 4 tests for
PerformanceMetricsSubscriberenvironment filtering - 3 tests for
PerformanceControllerdiagnose suggestions - All tests verify the new default includes
prod - Tests cover edge cases like empty configs, single environments, and custom environments
- Updated existing tests to reflect new default values
- 5 tests for
Commits
Release v1.0.6
chore: Prepare release v1.0.6
- Fix: Symfony 7 compatibility (move help from AsCommand to configure)
- Add: 60+ new tests for improved reliability
- Update: CHANGELOG, UPGRADING, and RELEASE_NOTES
Changelog
Fixed
- Symfony 7 compatibility - Fixed compatibility issue with Symfony 7.x commands
- Moved
helpparameter from#[AsCommand]attribute toconfigure()method usingsetHelp() - Fixed "Unknown named parameter $help" error in all commands
- All commands now use
configure()method for help text (compatible with Symfony 6.x and 7.x) - Commands affected:
check-dependencies,diagnose,create-table,create-records-table,set-route
- Moved
Added
- Comprehensive test coverage - Added 60+ new tests for improved reliability
- 7 tests for
getChartData()method covering all metrics (requestTime, queryTime, totalQueries, memoryUsage) - 5 tests for
accessStatistics()method covering disabled states, exceptions, and date ranges - 7 tests for subscriber detection in diagnose page
- 13 tests for
getAvailableEnvironments()method (already in v1.0.4) - 16 tests for export functionality (CSV and JSON) (already in v1.0.4)
- 12 tests for
buildFiltersFromRequest()method (already in v1.0.4) - Improves code quality and ensures edge cases are properly handled
- 7 tests for