docs/content/concepts/logging-and-ingestion/importers/overview.md
Internally, the Importer trait takes care of loading files into the Viewer and/or SDK.
There are 3 broad kinds of Importers: builtin, external and custom.
External and custom are the two ways of extending the file loading system that we'll describe below.
When a user attempts to open a file in the Viewer/SDK, all known Importers are notified of the path to be opened, unconditionally.
This gives Importers maximum flexibility to decide what files they are interested in, as opposed to e.g. only being able to look at a file's extension.
Once notified, an Importer can return an ImporterError::Incompatible error to indicate that it doesn't support a given file type.
If, and only if, all importers known to the Viewer/SDK return an Incompatible error code, then an error message is shown to the user indicating that this file type is not (yet) supported.
In these instances of unsupported files, we expose two ways of implementing and registering your Importers, explained below.
The easiest way to create your own Importer is by implementing what we call an "external importer": a stand alone executable written in any language that the Rerun SDK ships for. Any executable on your $PATH with a name that starts with rerun-importer- (or rerun-loader- for backwards compatibility) will be treated as an Importer.
This executable takes a file path as a command line argument and outputs Rerun logs on stdout.
It will be called by the Rerun Viewer/SDK when the user opens a file, and be passed the path to that file.
From there, it can log data as usual, using the stdout logging sink.
The Rerun Viewer/SDK will then automatically load the data streamed to the external importer's standard output.
<picture> <source media="(max-width: 480px)" srcset="https://static.rerun.io/data-loader-external-overview/97e978000c709b78290f50d52c229a91f7543648/480w.png"> <source media="(max-width: 768px)" srcset="https://static.rerun.io/data-loader-external-overview/97e978000c709b78290f50d52c229a91f7543648/768w.png"> <source media="(max-width: 1024px)" srcset="https://static.rerun.io/data-loader-external-overview/97e978000c709b78290f50d52c229a91f7543648/1024w.png"> <source media="(max-width: 1200px)" srcset="https://static.rerun.io/data-loader-external-overview/97e978000c709b78290f50d52c229a91f7543648/1200w.png"> </picture>Like any other Importer, an external importer will be notified of all file openings, unconditionally.
To indicate that it does not support a given file, the importer has to exit with a dedicated status code.
When the Viewer and/or SDK executes an external importer, it will pass to it a set of recommended settings in the form of CLI parameters (in addition to the file path to be loaded, which is passed as the one and only positional argument):
--application-id <application_id>
The recommended ApplicationId to log the data to.
--opened-application-id <opened_application_id> (optional)
The ApplicationId that is currently opened in the viewer, if any.
--recording-id <store_id>
The recommended RecordingId to log the data to.
Log data to this recording if you want it to appear in a new recording shared by all importers for the current loading session.
--opened-recording-id <opened_store_id> (optional)
The RecordingId that is currently opened in the viewer, if any.
--entity-path-prefix <entity_path_prefix> (optional)
Recommended prefix to prepend to all entity paths.
--static (optional)
The data is expected to be logged as static.
--time_sequence <timeline1>=<seq1> <timeline2>=<seq2> … (optional)
The data is expected to be logged at these specific sequence times.
--time_duration_nanos <timeline1>=<duration1> <timeline2>=<duration2> … (optional)
The data is expected to be logged at these specific duration times.
The timestamps are expected to be in nanoseconds: use rr.set_time_duration_nanos (Python) / RecordingStream::set_time_duration_nanos (C++, Rust) appropriately.
--time_timestamp_nanos <timeline1>=<timestamp1> <timeline2>=<timestamp2> … (optional)
The data is expected to be logged at these specific timestamp times.
The timestamps are expected to be in nanoseconds since Unix epoch: use rr.set_time_timestamp_nanos (Python) / RecordingStream::set_time_timestamp_nanos (C++, Rust) appropriately.
Check out our examples for C++, Python and Rust that cover every steps in details.
Another Rust-specific approach is to implement the Importer trait yourself and register it in the Rerun Viewer/SDK.
To do so, you'll need to import rerun as a library, register your Importer and then start the Viewer/SDK from code.
Check out our example that covers all these steps in details.