v1.1.0
New Features
-
RTR protocol support: Added support for fetching ROAs via RTR (RPKI-to-Router) protocol
- Configure RTR endpoint in
~/.monocle/monocle.toml:rpki_rtr_host = "rtr.rpki.cloudflare.com" rpki_rtr_port = 8282 rpki_rtr_timeout_secs = 10 rpki_rtr_no_fallback = false
- Or use environment variables:
MONOCLE_RPKI_RTR_HOST,MONOCLE_RPKI_RTR_PORT,MONOCLE_RPKI_RTR_TIMEOUT_SECS,MONOCLE_RPKI_RTR_NO_FALLBACK - Or use CLI flag for one-time override:
monocle config update --rpki --rtr-endpoint rtr.rpki.cloudflare.com:8282 - ROAs are fetched via RTR, ASPAs always from Cloudflare (RTR v1 per RFC 8210 doesn't support ASPA)
- Automatic fallback to Cloudflare if RTR connection fails, with warning message (set
rpki_rtr_no_fallback = trueto disable fallback and error out instead) - Connection timeout defaults to 10 seconds
- Supports RTR protocol version negotiation (v1 with v0 fallback)
- Configure RTR endpoint in
-
--cache-dir: Added local caching support to thesearchcommand- Download MRT files to a local directory before parsing
- Files are cached as
{cache-dir}/{collector}/{path}(e.g.,cache/rrc00/2024.01/updates.20240101.0000.gz) - Cached files are reused on subsequent runs, avoiding redundant downloads
- Uses
.partialextension during downloads to handle interrupted transfers - Cache directory access is validated upfront before processing begins
- Broker query caching: When
--cache-diris specified, broker API query results are cached in SQLite- Cache stored at
{cache-dir}/broker-cache.sqlite3 - Only queries with end time >2 hours in the past are cached (recent data may still change)
- Subsequent identical queries use cached results, enabling offline operation
- Tested: run search once, disable network, run same search again - results returned from cache
- Cache stored at
- Example:
monocle search -t 2024-01-01 -d 1h --cache-dir /tmp/mrt-cache
-
Multi-value filters:
parseandsearchcommands now support filtering by multiple values with OR logic- Example:
-o 13335,15169,8075matches elements from ANY of the specified origin ASNs - Example:
-p 1.1.1.0/24,8.8.8.0/24matches ANY of the specified prefixes - Example:
-J 174,2914matches elements from ANY of the specified peer ASNs
- Example:
-
Negative filters: Support for exclusion filters using
!prefix- Example:
-o '!13335'excludes elements from AS13335 - Example:
-o '!13335,!15169'excludes elements from AS13335 AND AS15169 - Note: Cannot mix positive and negative values in the same filter
- Example:
-
Added validation for ASN format, prefix CIDR notation, and negation consistency
-
--time-format: Added timestamp output format option toparseandsearchcommands--time-format unix(default): Output timestamps as Unix epoch (integer/float)--time-format rfc3339: Output timestamps in ISO 8601/RFC3339 format (e.g.,2023-10-11T17:00:00+00:00)- Applies to non-JSON output formats (table, psv, markdown)
- JSON output always uses numeric Unix timestamps for backward compatibility
- Example:
monocle parse file.mrt --time-format rfc3339 - Example:
monocle search -t 2024-01-01 -d 1h -p 1.1.1.0/24 --time-format rfc3339
-
Added
--fields(-f) option toparseandsearchcommands for selecting output fields (#99, #101)- Choose which columns to display with comma-separated field names
- Available fields:
type,timestamp,peer_ip,peer_asn,prefix,as_path,origin,next_hop,local_pref,med,communities,atomic,aggr_asn,aggr_ip,collector - Parse command defaults exclude
collectorfield (not applicable) - Search command defaults include
collectorfield - Example:
monocle search -t 2024-01-01 -d 1h -f prefix,as_path,collector
-
Added proper table formatting with borders using
tabledcrate for--format table(#99, #101)- Table output now uses rounded borders instead of tab-separated values
- Markdown format includes proper header row with separator
-
Added
--order-byand--orderparameters toparseandsearchcommands (#98)- Sort output by:
timestamp,prefix,peer_ip,peer_asn,as_path, ornext_hop - Direction:
asc(ascending, default) ordesc(descending) - When ordering is specified, output is buffered and sorted before display
- Example:
monocle parse file.mrt --order-by timestamp --order asc - Example:
monocle search -t 2024-01-01 -d 1h -p 1.1.1.0/24 --order-by timestamp --order desc
- Sort output by:
-
monocle config sources: Shows staleness status based on TTL for all data sources- "Stale" column shows whether each source needs updating based on its configured TTL
- Configuration section shows current TTL values for all sources
Bug Fixes
- Avoid creating a new SQLite database when
monocle config sourcesinspects staleness
Code Improvements
- Data refresh logging: CLI now shows specific reason for data refresh ("data is empty" vs "data is outdated") instead of generic "empty or outdated" message
- AS name display: ASN names are now displayed using a preferred source hierarchy:
- Priority order: PeeringDB
akaβ PeeringDBname_longβ PeeringDBnameβ AS2Orgorg_nameβ AS2Orgnameβ Corename - This provides more recognizable, commonly-used AS names from PeeringDB when available
- Affects all commands that display AS names:
inspect,as2rel,rpki,pfx2as
- Priority order: PeeringDB
- Feature gate cleanup: Simplified feature gating for the
databasemodule- The entire
databasemodule is now gated atlib.rslevel with#[cfg(feature = "lib")] - Removed redundant feature gates from internal submodules
- Added detailed feature documentation to
ARCHITECTURE.mdwith use case scenarios
- The entire
Breaking Changes
-
Simplified feature flags: Replaced 6-tier feature system with 3 clear features
- Old:
database,lens-core,lens-bgpkit,lens-full,display,cli - New:
lib,server,cli - Quick guide:
- Need CLI binary? Use
cli(includes everything) - Need WebSocket server without CLI? Use
server(includes lib) - Need only library/data access? Use
lib(database + all lenses + display)
- Need CLI binary? Use
- Display (tabled) now always included with
libfeature
- Old:
-
CLI flag renamed:
--no-refreshrenamed to--no-updatefor consistency with "update" terminology- Old:
monocle --no-refresh <command> - New:
monocle --no-update <command>
- Old:
-
Config subcommands renamed: Removed
db-prefix from config subcommands for cleaner syntaxmonocle config db-refreshβmonocle config updatemonocle config db-backupβmonocle config backupmonocle config db-sourcesβmonocle config sources
-
Configurable TTL for all data sources: All data sources now have configurable cache TTL with 7-day default
- Added
asinfo_cache_ttl_secsconfig option (default: 7 days) - Added
as2rel_cache_ttl_secsconfig option (default: 7 days) - Changed
rpki_cache_ttl_secsdefault from 1 hour to 7 days - Changed
pfx2as_cache_ttl_secsdefault from 24 hours to 7 days - Configure via
~/.monocle/monocle.tomlor environment variables (MONOCLE_ASINFO_CACHE_TTL_SECS, etc.)
- Added
-
Standardized database refresh API: Consistent interface for all data sources
- New
RefreshResultstruct withrecords_loaded,source,timestamp,details - Renamed methods for consistency:
bootstrap_asinfo()βrefresh_asinfo()(with deprecated alias)update_as2rel()βrefresh_as2rel()(with deprecated alias)
- Added missing methods:
refresh_asinfo_from(path)- Load ASInfo from custom pathrefresh_rpki()- Load RPKI data from recordsrefresh_pfx2as()- Load Pfx2as data from records
- All repositories now use consistent
needs_*_refresh(ttl)pattern - Removed hardcoded TTL methods (
should_update()from AS2Rel) - All repositories have both URL and path loading methods
- New
-
Reorganized examples: One example per lens with
_lenssuffix- Flat directory structure:
examples/time_lens.rs,examples/rpki_lens.rs, etc. - Added new examples for IpLens, Pfx2asLens, As2relLens
- Removed verbose multi-example files
- All examples use
libfeature exclusively
- Flat directory structure:
-
ParseFilters: Changed filter field types to support multiple values with OR logic
origin_asn:Option<u32>βVec<String>prefix:Option<String>βVec<String>peer_asn:Option<u32>βVec<String>- Empty
Vecis equivalent to no filter (previousNone) - Values can be prefixed with
!for negation (exclusion) - Library users will need to update code:
Some(13335)βvec!["13335".to_string()]