Skip to main content
Version: 3.2.0

Server Configuration File

ChronoLog server executables share a single JSON configuration file. The repository ships a template at default_conf.json.in; a fully expanded example is installed as conf/default-chrono-conf.json and is used by tools/deploy/deploy_local.sh.

The file is organized into two shared blocks (clock, authentication) and four per-component sections (chrono_visor, chrono_keeper, chrono_grapher, chrono_player). See the Overview page for the loader architecture behind these sections.

{
"clock": { ... },
"authentication": { ... },
"chrono_visor": { ... },
"chrono_keeper": { ... },
"chrono_grapher": { ... },
"chrono_player": { ... }
}

Shared Blocks​

These blocks are parsed once by ConfigurationManager and are visible to every process.

clock​

Controls the clock source used for event timestamping. See Performance Tuning → Clock Source for the effect of each option.

FieldTypeDefaultDescription
clocksource_typestring"CPP_STYLE"One of "C_STYLE", "CPP_STYLE", "TSC".
drift_cal_sleep_secinteger10Seconds between clock drift calibrations.
drift_cal_sleep_nsecinteger0Additional nanoseconds added to the calibration interval.

Backed by ClockConf in src/chrono-common/include/ConfigurationBlocks.h.

authentication​

FieldTypeDefaultDescription
auth_typestring"RBAC"Authentication mechanism. Currently only "RBAC" is used.
module_locationstring""Path to the authentication module shared object.

Backed by AuthConf in src/chrono-common/include/ConfigurationBlocks.h.


Common Per-Component Sub-Blocks​

Several JSON sub-blocks appear in more than one component. They always have the same shape, parsed by the same C++ building block.

rpc — Thallium endpoint​

Every service endpoint is described by an rpc block, parsed by RPCProviderConf.

FieldTypeExampleDescription
protocol_confstring"ofi+sockets"Thallium/Mercury transport string. See Network & RPC.
service_ipstring"127.0.0.1"IP the service binds to (servers) or connects to (clients).
service_base_portinteger5555TCP port.
service_provider_idinteger55Thallium provider ID; multiplexes services on the same address.

Monitoring — logging​

Per-component log sink. Wrapped under a monitor key and parsed by LogConf.

"Monitoring": {
"monitor": {
"type": "file",
"file": "chrono-visor-1.log",
"level": "debug",
"name": "ChronoVisor",
"filesize": 104857600,
"filenum": 3,
"flushlevel": "warning"
}
}
FieldTypeDescription
typestringLog sink type. Currently only "file" is supported.
filestringLog file name.
levelstringMinimum log level: trace, debug, info, warning, error, critical, off.
namestringLogger name that appears in log lines.
filesizeintegerMaximum file size in bytes before rotation.
filenumintegerNumber of rotated files to keep.
flushlevelstringMinimum level that triggers an immediate flush to disk.

DataStoreInternals — story-chunk, tail and retention tuning​

Appears in chrono_keeper, chrono_grapher, and chrono_player. Parsed by DataStoreConf. See Performance Tuning → Story Chunk Settings for the semantics of each field.

FieldTypeDefaultDescription
max_story_chunk_sizeinteger64Maximum number of events in a single chunk.
story_chunk_duration_secsinteger30How long a chunk remains open.
acceptance_window_secsinteger60Maximum allowed age of an incoming event relative to wall-clock time.
inactive_story_delay_secsinteger180Idle time before an in-memory story is evicted.
tail_capacityinteger65536(Keeper only) Maximum most-recent sealed events indexed per story for tail reads. A chunk with events in the index stays in memory; the index is released when the story retires. Must be $>0$.
live_tail_readbooleanfalse(Keeper only) When true, tail reads also serve unsealed events from the active timeline in addition to sealed chunks, dropping visibility latency to sub-second.
retention_cap_mbinteger4096(Keeper only) Retained-chunk memory, in MB, above which the keeper logs a warning while it waits for ChronoGrapher to persist chunks. Nothing is dropped. Set it above the memory a healthy keeper holds, or the warning fires in normal operation: about 3 × 125 s × peak per-keeper MB/s with the template's windows. 0 turns the warning off. See Durable Chunk Retention.
watermark_resend_timeout_secsinteger300(Keeper only) Seconds a keeper waits for ChronoGrapher to confirm a chunk written before sending it again. Keep it at least twice ChronoGrapher's story_chunk_duration_secs plus acceptance_window_secs; see Timing rules across components. Must be positive.
archive_visibility_delay_secsinteger10(Keeper only) Seconds a keeper keeps a chunk after ChronoGrapher confirms it written, so replays take its events from the keeper until players can read the new archive file. A replay looks the newest windows up by name, which skips a shared file system's directory listing cache but not its cache of failed lookups, which NFS keeps by default (lookupcache=all) for up to acdirmax: mount the archive with lookupcache=positive, or raise this above acdirmax. A window written late at an older start time, after a lost chunk was sent again, is found only by the player's directory scan, so for those this has to cover archive_scan_interval_secs plus the listing cache; see Timing rules across components and Archive on a Shared File System. 0 frees on confirmation. See Durable Chunk Retention.
shutdown_confirm_timeout_secsinteger150(Keeper only) Seconds a keeper stopped with SIGTERM waits for ChronoGrapher to confirm its chunks written before it exits. Cover ChronoGrapher's story_chunk_duration_secs plus acceptance_window_secs; see Timing rules across components. 0 exits without waiting.
watermark_report_interval_secsinteger1(Grapher only) How often ChronoGrapher sends changed persisted watermarks and unwritten receipts to the keepers.

Timing rules across components​

Several timing settings only work together with a setting of another component: a keeper waits for ChronoGrapher to write its chunks, and a player has to find a file before the keeper lets its copy go. Each component reads only its own settings, so nothing checks these relations when a component starts. If you change any of the settings below, keep the rules. The values are the template's.

RuleTemplate valuesWhyIf it is broken
player archive_window_secs = grapher story_chunk_duration_secs30 = 30The player builds the names of the newest archive files from the grapher's window length.Lookups by name never match; new files are found only by the next directory scan, and a replay in between can miss events the keepers have freed.
grapher acceptance_window_secs > keeper story_chunk_duration_secs + keeper acceptance_window_secs60 > 10 + 15A keeper ships a chunk that long after its first event; it has to reach the grapher before the grapher's window for that time closes.Every keeper chunk arrives after its window was written and lands in a second, numbered file for that window.
grapher story_chunk_duration_secs + acceptance_window_secs (the write window) stays short30 + 60 = 90 sAn event reaches the archive within the write window, and a keeper holds each chunk at least that long.Keepers hold more memory and replays read more from the keepers.
keeper watermark_resend_timeout_secs ≥ 2 × the grapher's write window300 ≥ 180A keeper sends a chunk again only when the grapher has had time to write it.A delivery about to be confirmed is replaced by a new one that has to be confirmed from the start; chunks are sent and written again, and a keeper can wait indefinitely.
keeper shutdown_confirm_timeout_secs ≥ the grapher's write window150 ≥ 90A keeper stopped with SIGTERM waits for the grapher to write the chunks it just sent.The keeper exits before its last chunks are confirmed, and frees them unconfirmed with a warning.
keeper archive_visibility_delay_secs ≥ player archive_scan_interval_secs + the archive mount's acdirmax10 vs 5 + 5 with the recommended mountA window written late at an older start time is found only by the player's directory scan, which lags by the mount's directory cache.A replay issued between the keeper freeing such a chunk and the next listing that shows its file misses those events and still reports success.
keeper retention_cap_mb ≥ 3 × peak per-keeper MB/s × (keeper story_chunk_duration_secs + acceptance_window_secs + the grapher's write window + grapher watermark_report_interval_secs + keeper archive_visibility_delay_secs)4096 ≥ 3 × 10 × 126That is how long a healthy keeper holds each chunk; the factor 3 leaves room for a short grapher stall.The retention warning fires in normal operation and stops meaning anything. Nothing is dropped.
grapher watermark_report_interval_secs well below keeper archive_visibility_delay_secs1 vs 10Keepers learn that a chunk is written from these reports.Chunks stay on the keepers longer than they need to.
grapher inactive_story_delay_secs > keeper story_chunk_duration_secs + keeper acceptance_window_secs300 > 25After a story is released, a keeper seals its last chunk that long later; the grapher's pipeline for the story should still be there.The last chunks arrive after the pipeline retired and are written as reopened windows.

It also helps to make the grapher's story_chunk_duration_secs a multiple of the keeper's (30 and 10), so that a keeper's chunk does not straddle two grapher windows.

A client waits up to 180 s for a replay (fixed in the client library). A player gives each keeper 5 s to answer before it returns a partial result, so this leaves the archive read most of that time.

ExtractionModule​

Present under chrono_keeper and chrono_grapher. Parsed by ExtractionModuleConfiguration (src/chrono-common/include/ExtractionModuleConfiguration.h). Defines the configurable pipeline of extractors that drains retired StoryChunks. See Architecture → ChronoKeeper for the concept and Performance Tuning → Extraction Pipeline for tuning guidance.

FieldTypeDescription
extraction_stream_countintegerNumber of parallel extraction-stream threads draining the extraction queue. Default: 2.
extraction_protocolstringThallium protocol used by RDMA-based extractors. Default: "ofi+sockets".
extractorsobjectMap of extractor instances keyed by an arbitrary label. Each entry must set "type" to one of the supported extractor types listed below; additional fields depend on the type.

Supported extractor types

typeAvailable inRequired fieldsBehavior
csv_extractorkeeper, graphercsv_archive_dir (string)Writes each StoryChunk as a CSV file under csv_archive_dir.
single_endpoint_rdma_extractorkeeper, grapherreceiving_endpoint (object: protocol_conf, service_ip, service_base_port, service_provider_id)Drains each StoryChunk to one RDMA endpoint (typically a ChronoGrapher's KeeperGrapherDrainService).
dual_endpoint_rdma_extractorkeeperTwo receiving_endpoint entriesFans each StoryChunk out to two RDMA endpoints simultaneously (e.g. ChronoGrapher + ChronoPlayer).
hdf5_extractorgrapher (required)hdf5_archive_dir (string)Serializes each StoryChunk into the HDF5 archive under hdf5_archive_dir.

A ChronoGrapher's chain must include hdf5_extractor: it is the only extractor that confirms chunks written, and keepers free a chunk only once the grapher confirms it. A grapher whose extractors list is empty or absent gets an hdf5_extractor with hdf5_archive_dir /tmp; one whose list leaves it out, such as a csv_extractor alone, fails to start. Other extractors may run alongside it.

Keepers ship with single_endpoint_rdma_extractor to ChronoGrapher. Replay reads recent events from the keepers directly, so the ChronoPlayer copy that dual_endpoint_rdma_extractor sends is no longer needed.

See the keeper and grapher blocks in conf/default_conf.json.in for fully expanded examples.

ArchiveReaders — story files directory​

Present under chrono_player. Parsed by ExtractorReaderConf.

FieldTypeDescription
story_files_dirstringFilesystem directory where archived story files are read from by the player. On NFS, mount it with lookupcache=positive and a short acdirmin/acdirmax; see Archive on a Shared File System.
archive_scan_interval_secsintegerSeconds between the player's listings of story_files_dir. A file written since the last listing is found by a lookup by name if it is one of the newest windows, and otherwise only by the next listing. Default: 5.
archive_window_secsintegerLength of ChronoGrapher's windows, used to build the names of the newest archive files for a lookup by name. Must equal the grapher's story_chunk_duration_secs. 0 turns the lookup off. Default: 30.

IngestionThreadCount — ingestion-thread parallelism​

A scalar field that sits inside the ingestion service object of each component:

ComponentPathDefaultDescription
ChronoKeeperchrono_keeper.KeeperRecordingService.IngestionThreadCount4Number of worker threads serving the Keeper recording RPC.
ChronoGrapherchrono_grapher.KeeperGrapherDrainService.IngestionThreadCount1Number of worker threads serving the Grapher drain RPC.
ChronoPlayerchrono_player.PlaybackQueryService.IngestionThreadCount1Number of worker threads serving the Player playback-query RPC.

chrono_visor​

Parsed by VisorConfiguration (src/chrono-visor/include/ChronoVisorConfiguration.h).

FieldTypeDescription
VisorClientPortalServiceobject{ "rpc": { ... } } — endpoint used by clients to connect to ChronoVisor.
VisorKeeperRegistryServiceobject{ "rpc": { ... } } — endpoint where ChronoKeeper/Grapher/Player register and heartbeat.
MonitoringobjectSee Monitoring.
delayed_data_admin_exit_in_secsintegerShutdown grace period for the data administration service. Clamped to (0, 60); default 5.

chrono_keeper​

Parsed by KeeperConfiguration (src/chrono-keeper/include/ChronoKeeperConfiguration.h).

FieldTypeDescription
RecordingGroupintegerLogical group this keeper belongs to. Must match its paired ChronoGrapher.
KeeperRecordingServiceobject{ "rpc": { ... } } — endpoint that receives events from ChronoVisor for recording.
KeeperDataStoreAdminServiceobject{ "rpc": { ... } } — endpoint for admin actions on the keeper's data store.
VisorKeeperRegistryServiceobject{ "rpc": { ... } } — endpoint on ChronoVisor where this keeper registers.
KeeperGrapherDrainServiceobject{ "rpc": { ... } } — endpoint on ChronoGrapher where drained chunks are delivered.
MonitoringobjectSee Monitoring.
DataStoreInternalsobjectSee DataStoreInternals.
ExtractionModuleobjectSee ExtractionModule.

KeeperRecordingService carries an IngestionThreadCount field — see IngestionThreadCount.

chrono_grapher​

Parsed by GrapherConfiguration (src/chrono-grapher/include/ChronoGrapherConfiguration.h).

FieldTypeDescription
RecordingGroupintegerLogical group this grapher serves.
KeeperGrapherDrainServiceobject{ "rpc": { ... } } — endpoint where this grapher receives drained chunks from a keeper.
DataStoreAdminServiceobject{ "rpc": { ... } } — endpoint for admin actions on the grapher's data store.
VisorRegistryServiceobject{ "rpc": { ... } } — endpoint on ChronoVisor where this grapher registers.
MonitoringobjectSee Monitoring.
DataStoreInternalsobjectSee DataStoreInternals.
ExtractionModuleobjectSee ExtractionModule.

KeeperGrapherDrainService carries an IngestionThreadCount field — see IngestionThreadCount.

chrono_player​

Parsed by PlayerConfiguration (src/chrono-player/include/ChronoPlayerConfiguration.h).

FieldTypeDescription
RecordingGroupintegerLogical group this player serves.
PlayerStoreAdminServiceobject{ "rpc": { ... } } — endpoint for admin actions on the player's data store.
PlaybackQueryServiceobject{ "rpc": { ... } } — endpoint that receives playback queries from clients.
VisorRegistryServiceobject{ "rpc": { ... } } — endpoint on ChronoVisor where this player registers.
MonitoringobjectSee Monitoring.
DataStoreInternalsobjectSee DataStoreInternals.
ArchiveReadersobjectSee ArchiveReaders.

PlaybackQueryService carries an IngestionThreadCount field — see IngestionThreadCount.


Full Example​

The repository ships a fully expanded example at conf/default_conf.json.in. Default values for every field are defined in the constructors of the configuration classes listed above.