Skip to main content

Events

Gravitino emits an event around every metadata operation, and event listeners receive them. A listener is how another system follows changes to the catalog without polling it. The server itself uses listeners to write the audit log, keep the search index current, and feed the dashboard counts, and you can register your own alongside them.

The UI lists the listeners registered on the server, with the dispatch mode of each, and the two queue settings that govern asynchronous delivery.

Quick Start

1. Build a listener. Implement EventListenerPlugin, choose its dispatch mode, and put the jar on the server classpath.

2. Register it by name. Add the name to the end of gravitino.eventListener.names and point {name}.class at the implementation. Replacing the list instead of extending it removes any listener already named there.

gravitino.eventListener.names = {existing_names},{listener_name}
gravitino.eventListener.{listener_name}.class = {listener_class}

3. Restart the server and confirm the listener appears in the UI. A name without a matching class stops the server from building that listener.

Events

Each operation emits up to three events: a pre-event before it runs, a post-event after it succeeds, and a failure event after it throws. The names follow the operation, so createTable produces CreateTablePreEvent, CreateTableEvent, and CreateTableFailureEvent. Operations served by the Gravitino IRC endpoint carry an Iceberg prefix, as in IcebergCreateTableEvent.

A pre-event handler that throws ForbiddenException stops the operation before it runs, so a synchronous listener can act as a veto rather than only an observer.

Listeners

Dispatch Modes

Every listener declares how its events reach it.

ModeBehavior
SYNCCalled inline, before the operation's result reaches the client. A slow listener slows every request.
ASYNC_ISOLATEDCalled from a queue and dispatcher thread of its own, so one slow listener cannot hold up another.
ASYNC_SHAREDCalled from one queue and dispatcher shared by every listener in this mode, so a slow listener delays the others on the same queue.

The listeners the server registers for itself all run ASYNC_ISOLATED, so none of them adds latency to a request.

Configuration

Configuration ItemDescriptionDefault Value
gravitino.eventListener.namesComma-separated listener names.(empty)
gravitino.eventListener.{name}.classClass of the listener registered under {name}.(none)
gravitino.eventListener.{name}.{key}Any other property under a listener's name, passed to that listener unchanged.(none)
gravitino.eventListener.queueCapacityEvents each asynchronous queue holds before it starts dropping them.3000
gravitino.eventListener.dispatcherJoinSecondsSeconds shutdown waits for each dispatcher thread to exit.3

Queue Behavior

Each ASYNC_ISOLATED listener has its own queue of queueCapacity events, and all ASYNC_SHARED listeners share one more. When a queue is full, a new event is dropped rather than waited for, so the operation that produced it is never slowed. The server logs a warning with the number dropped, at most once a minute per queue.

A dropped event never reaches its listener. For the audit log that is a gap in the record, and for the search index it is a change that search does not reflect until the object changes again. Warnings about dropped events mean a listener cannot keep up, and the fix is a faster listener or a larger queue.

At shutdown the server stops each dispatcher and waits up to dispatcherJoinSeconds for the thread to exit. Events still queued at that point are dropped and counted in a warning, so a listener that must see every event needs its own durable delivery rather than relying on the queue.