The GitHub Actions job "Groovy Snapshot Canary Build" on grails-core.git/feat/sql-tail-command has succeeded. Run started by GitHub user jdaugherty (triggered by jdaugherty).
Head commit for run: 6306f94ef79064cf373c069b9ee8534784a91829 / James Daugherty <[email protected]> Add the query-tail command to find query-heavy pages A page that is slow because it runs hundreds of queries is easy to miss in a log: logSql prints every statement, but not which page ran it or how many a request added up to. query-tail shows the pages of a running application ranked by the statements they run per request, and for each page the statement that repeats most within one request, which is what an N+1 looks like. It covers every store GORM runs statements on: SQL through Hibernate 5 and 7, Cypher through Neo4j and commands through MongoDB. Capture is on only when grails.gorm.queryTail.enabled is set at startup (grails run-app --query-tail, ./gradlew bootRun -Pgrails.gorm.queryTail.enabled, or configuration); an application started without it carries nothing that records. The Hibernate connection source factories install a statement inspector, the Neo4j factory wraps the driver, and the MongoDB factory registers a command listener, each recording on the thread that runs the statement, so a QueryTailRequestAttribution can attribute it to the controller and action Grails resolved for the request. The writer, record format, settings and redaction live in grails-datamapping-core, in org.apache.grails.data.core.querytail; the command is a script command in the grails-datamapping-core-cli companion, so the shell runs it without booting the application. The Grails Gradle plugin hands the -Pgrails.gorm.queryTail.* properties to forked application and test JVMs. Statements are captured without their values. Every literal is recorded as ? and every comment is dropped by a redactor that scans the statement under the lexical rules of its database, each a QueryTailSyntax verified against the database itself: H2, PostgreSQL, CockroachDB, Oracle, Db2, HSQLDB, Informix, MySQL and MariaDB, SQL Server and Sybase, GoogleSQL, SAP HANA from its documentation, and Cypher against Neo4j 5 and 3.5. A rule that depends on a server setting the capture cannot see is read every way the setting allows, and a statement is recorded only when every reading finds the same values; one that fails that, or whose literal or comment never ends, is withheld. A MongoDB command is a document, so its values are replaced field by field, and a key below the top of a document is kept only where the mapping knows it as a field, so that the keys of a map property never reach the capture. The request a statement is attributed to is recorded as its method and path with the values in the path replaced, those of its mapped parameters and any number, UUID or hexadecimal token among them. The capture file is written a line at a time through a channel, and a lock file beside it tells the JVMs that run at the same time with the flag, such as the parallel forks of a test task, which of them starts the run and which join it, with their requests numbered apart. The guide gains a section under The DataSource, the command reference a query-tail page and the --query-tail flag on run-app, and the configuration metadata the two settings. Report URL: https://github.com/apache/grails-core/actions/runs/40299051847 With regards, GitHub Actions via GitBox
