Geth v1.14.0 introduces a new optional feature, allowing users to stream (a subset of) all observable blockchain data in real-time. By writing some Go code you can develop a data indexing solution which will receive events from Geth as it is syncing and processing blocks. You may find the full list of events in the source code [here](https://github.com/ethereum/go-ethereum/blob/master/core/tracing/hooks.go), but below is a summary:
- Initialization: receives chain configuration including hard forks and chain ID. Also receives the genesis block.
- Block processing: receives the block which geth will process next and any error encountered during processing.
- Transaction processing: receives the transaction which geth will process next and the receipt post-execution.
- EVM:
- Call frame level events
- Opcode level events
- Logs
- Gas changes
- For more transparency into gas changes we have assigned a reason to each gas change.
- State modifications: receives any changes to the accounts.
- Balance changes come with a reason for more transparency into the change.
As this is a real-time stream, the data indexing solution must be able to handle chain reorgs. Upon receiving `OnBlock` events, it should check the chain of hashes it has already processed and unroll internal state that will be invalidated by the reorg.
<Note>A live tracer can impact the performance of your node as it is run synchronously within the sync process. It is better to keep the tracer code minimal and only with the purpose of getting raw data out and doing heavy post-processing of data in a later stage.</Note>
## Implementing a live tracer
The process is very similar to implementing a [custom native tracer](/docs/developers/evm-tracing/custom-tracer). These are the main differences:
- Custom native tracers are invoked through the API and will be instantiated for each request. Live tracers are instantiated once on startup and used throughout the lifetime of Geth.
- Live tracers will receive chain-related events as opposed to custom native tracers.
- The constructor for each of these types has a different signature. Live tracer constructors must return a `*tracing.Hooks` object, while custom native tracers must return a `*tracers.Tracer` object.
Below is a tracer that tracks changes of Ether supply across blocks.
### Set-up
First follow the instructions to [clone and build](/docs/getting-started/installing-geth) Geth from source code.
### Tracer code
Save the following snippet to a file under `eth/tracers/live/`.
- Tracer is registered in the Live Tracer directory as part of the `init()` function.
- It is possible to configure the tracer, e.g. pass in the path where the logs will be stored.
- Tracers don't have access to Geth's database. They will have to implement their own persistence layer or a way to extract data. In this example, the tracer logs the data to a file.
- Note that we are resetting the delta on every new block, because the same tracer instance will be used all the time.
### Running the tracer
First compile the source by running `make geth`. Then run the following command: