Install the elodin-db from the releases page.
# Run elodin-db in the foreground:
# - Listening on port 2240
# - Storing data in the default user data directory ($HOME/.local/share/elodin/db)
# - Using the ./examples/db-config.lua config
# - Setting log level to warn (optional)
elodin-db run [::]:2240 $HOME/.local/share/elodin/db --config examples/db-config.lua --log-level warnSee ./examples/client.c for an example C client that streams fake sensor data to the database. Build and run the client:
cc examples/client.c -lm -o /tmp/client; /tmp/client./examples/client.cpp includes an example of how to subscribe to data using C++. It can be built and run using:
This example uses C++23, but the library itself is C++20 compatible.
c++ -std=c++23 examples/client.cpp -o /tmp/client-cpp; /tmp/client-cppLaunch a LUA REPL to interact with the database:
elodin-db luaConnect to the database and dump all of the metadata:
db ❯❯ client = connect("127.0.0.1:2240")
db ❯❯ client:dump_metadata()
Run :help in the REPL to see all available commands:
db ❯❯ :help
Impeller Lua REPL
- `connect(addr)`
Connects to a new database and returns a client
- `Client:dump_metadata()`
Dumps all metadata from the db
...
Install the Elodin Editor if you haven't already. Then, launch the editor by providing the database IP and port:
elodin editor 127.0.0.1:2240The example C client just streams a sine wave component to entity "1". You can view this in the editor by creating a graph for entity "1" and selecting the only component available for that entity.
Follow mode starts a database that replicates all data (components, messages, metadata) from another running elodin-db instance over a single TCP connection. The follower database still accepts its own local connections and data writers.
Start the source database:
elodin-db run [::]:2240 $HOME/.local/share/elodin/source-dbStart the follower database, pointing it at the source:
elodin-db run [::]:2241 $HOME/.local/share/elodin/follower-db --follows 127.0.0.1:2240The follower will:
- Synchronize all existing metadata and schemas from the source.
- Backfill all historical component time-series data and message logs.
- Stream real-time updates as they arrive on the source.
Connect the Elodin Editor to the follower to view the replicated data:
elodin editor 127.0.0.1:2241By default, the source batches outgoing data into ~1500-byte TCP writes (standard Ethernet MTU). This dramatically reduces network overhead when the source has many components. You can tune the target packet size:
elodin-db run [::]:2241 ./follower-db --follows 127.0.0.1:2240 --follow-packet-size 9000Run the video-stream example on the source, follow it on the target, and also connect a local video stream directly to the follower:
# Source machine
elodin editor examples/video-stream/main.py
# Target machine -- follow the source
elodin-db run [::]:2241 ./follower-db --follows SOURCE_IP:2240 --follow-packet-size 1500
# Target machine -- connect the editor
elodin editor 127.0.0.1:2241
# Target machine -- add a second, local video stream
examples/video-stream/stream-video.sh # (pointed at 127.0.0.1:2241)Both the replicated video from the source and the locally-streamed video will be visible in the editor connected to the follower.
If two sources write to the same component, the follower logs a warning to alert you to potential data corruption.
The examples/downlink.lua script is still available for custom replication
workflows, but --follows is the recommended approach for most use cases.
Combine two databases into one with optional component prefixes and time alignment. This is useful for viewing SITL and real-world telemetry side-by-side in the Elodin Editor.
# Basic merge with prefixes
elodin-db merge -o merged --prefix1 sitl --prefix2 real ./sitl-db ./real-db
# Align using timestamps from the Elodin Editor's playback timeline
elodin-db merge -o merged --prefix1 sitl --prefix2 real \
--align1 15000000 --align2 14000000 --from-playback-start ./sitl-db ./real-db| Parameter | Example | Purpose |
|---|---|---|
--prefix1 |
sitl |
Prefix for first database component names |
--prefix2 |
real |
Prefix for second database component names |
--align1 |
15000000 |
Alignment timestamp (microseconds) for an event in DB1 |
--align2 |
14000000 |
Alignment timestamp for the same event in DB2. DB2 is shifted to align with DB1 |
--from-playback-start |
Interpret align values as offsets from each database's playback start | |
--output |
./merged |
Path for the merged output database |
--dry-run |
Show what would be merged without creating output |
Remove data from the beginning or end of a recording. Values are in
microseconds. At least one of --before or --after must be provided.
Without --output, the database is modified in place.
# Remove the first 3 minutes from a recording
elodin-db trim --from-start 180000000 ./my-db
# Remove the last 2 minutes from a recording
elodin-db trim --from-end 120000000 --output ./trimmed ./my-db
# Trim 1 minute from the start and 2 minutes from the end
elodin-db trim --from-start 60000000 --from-end 120000000 --output ./window ./my-db| Parameter | Example | Purpose |
|---|---|---|
--from-start |
180000000 |
Remove the first N microseconds from the start |
--from-end |
120000000 |
Remove the last N microseconds from the end |
--output |
./trimmed |
Write to a new path instead of modifying in place |
--dry-run |
Show what would be trimmed without making changes | |
-y |
Skip the confirmation prompt |
elodin-db ships with a single header C++20 library. The library includes message definitions for communicating with the DB.
NOTE: Not all definitions have been added yet if you need something ASAP please contact us
You can generate the C++ library by running:
cargo run gen-cpp > ./examples/db.hpp
This will generate a C++ header file at ./examples/db.hpp