Module: SecApi::FilingJourney
Overview
Tracks filing lifecycle from detection through processing.
Use accession_no as the correlation key to trace a filing through all processing stages: detection -> query -> extraction -> processing.
Correlation Key: accession_no
The SEC accession number (accession_no) uniquely identifies each filing and serves as the primary correlation key across all journey stages. This enables:
-
Tracing a filing’s complete journey through your system
-
Correlating stream events with subsequent API calls
-
Debugging failed pipelines by filtering logs on accession_no
-
Measuring end-to-end latency for specific filings
Log Query Patterns
ELK Stack / Kibana
# Find all journey events for a specific filing:
accession_no:"0000320193-24-000001" AND event:secapi.filing.journey.*
# Find filings that failed processing:
event:secapi.filing.journey.processed AND success:false
# Find slow extractions (>500ms):
event:secapi.filing.journey.extracted AND duration_ms:>500
Datadog Logs
# All journey stages for a filing:
@accession_no:0000320193-24-000001 @event:secapi.filing.journey.*
# Failed pipelines:
@event:secapi.filing.journey.processed @success:false
# 10-K filings detected:
@event:secapi.filing.journey.detected @form_type:10-K
CloudWatch Logs Insights
fields @timestamp, event, stage, accession_no, duration_ms
| filter accession_no = "0000320193-24-000001"
| filter event like /secapi\.filing\.journey/
| sort @timestamp asc
Splunk
index=production sourcetype=ruby_json
| spath event
| search event="secapi.filing.journey.*"
| search accession_no="0000320193-24-000001"
| table _time event stage duration_ms
Correlating Stream -> Query -> Extraction
The accession_no flows through all stages, enabling correlation:
1. Stream Detection: on_filing receives StreamFiling with accession_no
2. Query Lookup: Use accession_no to find full filing metadata
3. XBRL Extraction: Pass filing with accession_no to xbrl.to_json
4. Processing: Track processing completion with same accession_no
All log entries share the same accession_no, allowing you to reconstruct the complete journey in your log aggregation tool.
Constant Summary collapse
- STAGE_DETECTED =
Filing detected via WebSocket stream
"detected"- STAGE_QUERIED =
Filing metadata fetched via Query API
"queried"- STAGE_EXTRACTED =
XBRL data extracted via XBRL API
"extracted"- STAGE_PROCESSED =
User processing complete (application-defined)
"processed"
Instance Method Summary collapse
-
#calculate_duration_ms(start_time, end_time = Time.now) ⇒ Integer
Calculates duration between two timestamps.
-
#log_detected(logger, level, accession_no:, ticker: nil, form_type: nil, latency_ms: nil) ⇒ void
Logs filing detection from stream.
-
#log_extracted(logger, level, accession_no:, facts_count: nil, request_id: nil, duration_ms: nil) ⇒ void
Logs XBRL data extraction completion.
-
#log_processed(logger, level, accession_no:, success: true, total_duration_ms: nil, error_class: nil) ⇒ void
Logs filing processing completion.
-
#log_queried(logger, level, accession_no:, found: nil, request_id: nil, duration_ms: nil) ⇒ void
Logs filing query/lookup completion.
Instance Method Details
#calculate_duration_ms(start_time, end_time = Time.now) ⇒ Integer
Calculates duration between two timestamps.
Use this method for both stage-to-stage timing and total pipeline duration. The method returns milliseconds for consistency with other duration fields.
449 450 451 |
# File 'lib/sec_api/filing_journey.rb', line 449 def calculate_duration_ms(start_time, end_time = Time.now) ((end_time - start_time) * 1000).round end |
#log_detected(logger, level, accession_no:, ticker: nil, form_type: nil, latency_ms: nil) ⇒ void
This method returns an undefined value.
Logs filing detection from stream.
305 306 307 308 309 310 311 312 |
# File 'lib/sec_api/filing_journey.rb', line 305 def log_detected(logger, level, accession_no:, ticker: nil, form_type: nil, latency_ms: nil) log_stage(logger, level, STAGE_DETECTED, { accession_no: accession_no, ticker: ticker, form_type: form_type, latency_ms: latency_ms }.compact) end |
#log_extracted(logger, level, accession_no:, facts_count: nil, request_id: nil, duration_ms: nil) ⇒ void
This method returns an undefined value.
Logs XBRL data extraction completion.
357 358 359 360 361 362 363 364 |
# File 'lib/sec_api/filing_journey.rb', line 357 def log_extracted(logger, level, accession_no:, facts_count: nil, request_id: nil, duration_ms: nil) log_stage(logger, level, STAGE_EXTRACTED, { accession_no: accession_no, facts_count: facts_count, request_id: request_id, duration_ms: duration_ms }.compact) end |
#log_processed(logger, level, accession_no:, success: true, total_duration_ms: nil, error_class: nil) ⇒ void
This method returns an undefined value.
Logs filing processing completion.
391 392 393 394 395 396 397 398 |
# File 'lib/sec_api/filing_journey.rb', line 391 def log_processed(logger, level, accession_no:, success: true, total_duration_ms: nil, error_class: nil) log_stage(logger, level, STAGE_PROCESSED, { accession_no: accession_no, success: success, total_duration_ms: total_duration_ms, error_class: error_class }.compact) end |
#log_queried(logger, level, accession_no:, found: nil, request_id: nil, duration_ms: nil) ⇒ void
This method returns an undefined value.
Logs filing query/lookup completion.
331 332 333 334 335 336 337 338 |
# File 'lib/sec_api/filing_journey.rb', line 331 def log_queried(logger, level, accession_no:, found: nil, request_id: nil, duration_ms: nil) log_stage(logger, level, STAGE_QUERIED, { accession_no: accession_no, found: found, request_id: request_id, duration_ms: duration_ms }.compact) end |