> For the complete documentation index, see [llms.txt](https://bxorm.ortusbooks.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bxorm.ortusbooks.com/bxorm-2.x/working-with-entities/observability.md).

# Observability

Listen to ORM queries, flushes and failures from interceptors, and read Hibernate statistics

bx-orm announces events for SQL, flushes and failures so tools (debuggers, monitors, profilers) can listen instead of reaching into Hibernate. Register a normal BoxLang interceptor for the event names below.

There is no cost when nothing is listening. JDBC objects are only wrapped when a listener exists at the moment a connection is acquired, and payloads are built lazily.

## Events

| Event            | Fires                                                                                               | Payload                                                                  |
| ---------------- | --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| `onORMQuery`     | After each JDBC statement. Selects fire when the result set is closed, once the row count is known. | See below                                                                |
| `onORMFlush`     | After each Hibernate session flush.                                                                 | `inserts`, `updates`, `deletes`, `elapsedNanos`, `datasource`, `appName` |
| `onORMException` | When a statement fails.                                                                             | `error`, `sql`, `datasource`, `appName`                                  |

### `onORMQuery` payload

| Key            | Description                                                                                                   |
| -------------- | ------------------------------------------------------------------------------------------------------------- |
| `sql`          | The SQL text sent to the driver.                                                                              |
| `kind`         | `select`, `insert`, `update`, `delete`, `ddl` or `other`.                                                     |
| `elapsedNanos` | Execution time in nanoseconds. Excludes time spent reading rows.                                              |
| `rows`         | Rows returned for selects, rows affected for DML, `-1` when unknown (for example DDL).                        |
| `datasource`   | The datasource name.                                                                                          |
| `appName`      | The unique ORM application name, as used by `ORMService.getORMApp()`.                                         |
| `hql`          | The HQL being run, when the statement came from `ormExecuteQuery()`. Otherwise `null`.                        |
| `entityName`   | The entity being loaded, when the statement came from `entityLoad()` or `entityLoadByPK()`. Otherwise `null`. |
| `error`        | The `Throwable` when the statement failed, otherwise `null`.                                                  |
| `params`       | Ordered array of bound parameter values. Only present when `announceQueryParams` is `true`.                   |

A failed statement announces `onORMQuery` with `error` set, and `onORMException`. This includes SQL the database rejects while the statement is being prepared.

Startup DDL (for example `dbcreate="dropcreate"`) is announced too, as long as the listener is registered before the application starts.

### `onORMFlush` counts

`inserts`, `updates` and `deletes` count the statements run during the flush, not entities. JDBC batching can make them differ from the number of entities changed.

### Example

```javascript
// OrmWatcher.bx
class {

    function onORMQuery( data ) {
        // 100 ms
        if ( data.elapsedNanos > 100000000 ) {
            writeLog( text="Slow ORM #data.kind#: #data.sql#", type="warning" );
        }
    }

    function onORMException( data ) {
        writeLog( text="ORM failure on #data.datasource#: #data.error.getMessage()#", type="error" );
    }

}
```

Register it with `boxRegisterInterceptor()`, naming the events it listens to:

```javascript
boxRegisterInterceptor(
    interceptor : new OrmWatcher(),
    points      : [ "onORMQuery", "onORMException" ]
);
```

## Settings

Set these in `this.ormSettings`. Both default to `false`.

| Setting               | Description                                                                                                          |
| --------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `announceQueryParams` | Include bound parameter values in `onORMQuery`. Values can be sensitive, so they are never announced unless you ask. |
| `generateStatistics`  | Collect Hibernate statistics at startup, for `ORMService.getStatistics()`. Collection has a small cost.              |

## Statistics

`ORMService.getStatistics( appName )` returns a struct of `appName` and a `datasources` struct with one entry per datasource. When statistics are not collected, each entry is just `{ enabled: false }`.

Statistics can also be switched on and off at runtime with `ORMService.setStatisticsEnabled( appName, enabled )`. Counters start from zero when switched on.

Enabled entries contain: `enabled`, `startTime`, `sessionOpenCount`, `sessionCloseCount`, `flushCount`, `connectCount`, `prepareStatementCount`, `transactionCount`, `successfulTransactionCount`, `queryExecutionCount`, `queryExecutionMaxTime`, `queryExecutionMaxTimeQueryString`, `entityLoadCount`, `entityFetchCount`, `entityInsertCount`, `entityUpdateCount`, `entityDeleteCount`, `collectionLoadCount`, `collectionFetchCount`, `secondLevelCacheHitCount`, `secondLevelCacheMissCount`, `secondLevelCachePutCount`, `queryCacheHitCount` and `queryCacheMissCount`.

## Other ORM events

| Event               | When                                                | Payload                           |
| ------------------- | --------------------------------------------------- | --------------------------------- |
| `ORMPreConfigLoad`  | Before bx-orm reads an application's `ormSettings`. | `properties`, `context`           |
| `ORMPostConfigLoad` | After bx-orm reads an application's `ormSettings`.  | `properties`, `context`           |
| `post_new`          | When `entityNew()` creates an entity.               | `entityName`, `entity`, `context` |

`properties` is the `ormSettings` struct of the application.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://bxorm.ortusbooks.com/bxorm-2.x/working-with-entities/observability.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
