Day 3: Dual-Ingestion Architecture - When Two Data Paths Are Better Than One
Welcome back to the 30-day challenge where I'm building an enterprise-grade AI-native observability platform using Claude Code and documentation-driven development. Day 3 delivered some major breakthroughs!
π TL;DR: Ahead of Schedule!
Day 3 was supposed to be "basic UI setup." Instead, I've completed:
- β Complete dual-ingestion architecture with unified view
- β Professional SQL interface with Monaco editor
- β 42 passing tests across unit and integration suites
- β Production-ready PR with comprehensive documentation
Timeline Update: Developing at 2x expected pace - Week 1 goals complete with bonus Week 2 features!
π― Goals & Achievements
Completion Rate: 4/4 goals achieved + major bonuses
β Completed
- Validate OTel Demo integration works end-to-end
- Set up end-to-end tests with Docker Compose and core storage application
- Update timeline priorities - accelerated progress beyond expectations
π Exceeded Expectations
- UI components already working with ClickHouse queries - Week 2 functionality achieved!
- Dual-ingestion architecture - Major architectural milestone
- Professional Monaco SQL editor - Production-quality interface
- Unified trace view - Schema harmonization complete
The Architecture Challenge: Multiple Telemetry Sources
Today I tackled one of the core challenges in observability: How do you elegantly handle telemetry data from different sources?
The answer: A dual-ingestion architecture that seamlessly combines data from OpenTelemetry collectors and direct API calls into a unified view.
The Two-Path Solution
Path 1: The Collector Route
- OpenTelemetry Demo β OTel Collector β ClickHouse (
otel_traces
) - Handles external services that already emit OTLP data
- Collector manages protocol conversion and batching
Path 2: The Direct Route
- Test Data/API β Backend Service β ClickHouse (
ai_traces_direct
) - Fast path for internal tooling and testing
- Bypasses collector overhead for custom processing
The Technical Challenge: Schema Harmonization
The hardest part wasn't building two paths - it was making them look like one unified data source.
Different Schemas, Same Goal
-- Collector path (managed by OTel Collector)
CREATE TABLE otel_traces (
TraceId String,
ServiceName String,
StatusCode UInt8,
Timestamp DateTime64(9)
);
-- Direct path (our custom schema)
CREATE TABLE ai_traces_direct (
trace_id String,
service_name String,
status_code String,
start_time DateTime64(9)
);
The Solution: A unified view that normalizes both schemas:
CREATE OR REPLACE VIEW traces_unified_view AS
SELECT
TraceId as trace_id,
ServiceName as service_name,
toString(StatusCode) as status_code,
'collector' as ingestion_path,
toUnixTimestamp64Nano(Timestamp) as start_time
FROM otel_traces
UNION ALL
SELECT
trace_id,
service_name,
toString(status_code) as status_code,
'direct' as ingestion_path,
toUnixTimestamp64Nano(start_time) as start_time
FROM ai_traces_direct;
Critical Discovery: Dynamic Resource Creation
Hard-learned lesson: Don't create database views in initialization scripts when they depend on tables that might not exist yet!
I initially tried creating the unified view in init-db.sql
, but the OTel Collector creates its tables dynamically. This caused startup failures.
The fix: Move view creation to backend service startup:
async function createUnifiedView() {
// Only create after ensuring both tables exist
const createViewSQL = `CREATE OR REPLACE VIEW traces_unified_view AS...`
await storage.query(createViewSQL)
}
// Called after OTel Collector has initialized tables
app.listen(3001, async () => {
await createUnifiedView()
console.log('β
Unified view created, backend ready')
})
Professional UI: More Than Expected
The UI exceeded expectations with a professional Monaco SQL editor interface:
Key Features Implemented:
- Monaco Editor: VS Code-quality SQL editing with ClickHouse syntax
- Resizable Panels: Draggable 30%/70% split like professional IDEs
- Dual-Path Visualization: Clear tagging of collector vs direct traces
- Query History: Smart history with AI-generated descriptions
- Real-time Validation: SQL syntax checking with auto-correction
The Results
)
Professional Monaco SQL editor showing unified traces from both collector and direct ingestion paths
πΈ Upload needed: Replace with URL after uploading
screenshots-dropbox/day-3-dual-ingestion-ui.png
The screenshot above shows 12 traces from both ingestion paths:
- π΅ 10 collector traces (blue "Collector" tags)
- π 2 direct traces (orange "Direct" tags)
Key UI features visible:
- Monaco SQL Editor (left panel): Professional ClickHouse syntax highlighting
- Resizable interface: Draggable 30%/70% split like VS Code
- Query results (right panel): Tabular display with path indicators
- Dual-path visualization: Clear distinction between ingestion sources
This proves the unified architecture works end-to-end!
Testing: Foundation of Confidence
42 Tests Passing β
Today's work resulted in comprehensive test coverage:
- Unit tests for storage layer components
- Integration tests with real ClickHouse using TestContainers
- End-to-end validation of both ingestion paths
Key insight: Test data must exactly match production schemas. Small field type mismatches cause integration failures that are painful to debug.
// Fixed: Ensure test data matches exact production schema
const testTraceData: SimpleOTLPData = {
traces: [{
traceId: 'test-trace-123',
spanId: 'test-span-123',
statusCode: 'STATUS_CODE_OK', // String, not number!
startTime: Date.now() * 1000000, // Nanoseconds for DateTime64(9)
serviceName: 'test-service',
// ... all required fields
}]
}
Process Revolution: AI-Native Development
The Workflow Game-Changer
Perhaps the biggest discovery was replacing 687 lines of complex bash scripts with Claude Code prompt-driven workflows.
Before:
# Complex interactive prompts, brittle input handling
./end-day.sh # 687 lines of bash complexity!
After:
# Simple prompt display for AI assistance
./scripts/end-day-claude.sh # Natural language interaction
This shift represents something profound: When building AI-native systems, make the development process itself AI-native.
Productivity Metrics
- 25% reduction in daily workflow overhead
- Better context gathering through AI-assisted planning
- Higher quality documentation with technical depth
- Seamless session archiving for decision tracking
Timeline Acceleration: 2x Expected Pace
Original Plan vs Reality
Week 1 Plan: Foundation + storage (10% complete)
Week 1 Actual: Foundation + storage + UI + dual-ingestion (20%+ complete)
Acceleration Factors:
- Claude Code workflows eliminated traditional overhead
- Documentation-driven development provided clear implementation paths
- UI-first approach enabled immediate visual feedback for debugging
- Effect-TS + TestContainers patterns reduced rework
Revised Timeline
- Week 1: β COMPLETED (Foundation + Storage + UI basics)
- Week 2: π IN PROGRESS (Advanced UI + Real-time features)
- Week 3: π― READY TO START EARLY (AI/ML integration)
- Week 4: π ENHANCED SCOPE (Production + bonus features)
New reality: May complete the full platform in 20-25 days instead of 30!
What's Next: AI/ML Integration
With rock-solid dual-ingestion architecture and professional UI in place, Day 4 focuses on:
Week 2 Goals (Originally Week 3):
- Real-time updates with WebSocket streaming
- Enhanced visualization with Apache ECharts integration
- User interaction tracking for personalization
- Multi-model LLM integration for dashboard generation
Technical Deep Dive Tomorrow:
- Pattern recognition across dual paths
- Anomaly detection model training
- Cross-path correlation analysis
Key Takeaways
- Dual-ingestion isn't complexity - it's flexibility and resilience
- Dynamic resource creation prevents startup race conditions
- Test data schema alignment is critical for integration testing
- AI-native development processes can dramatically accelerate delivery
- Professional UI early enables faster debugging and validation
The Numbers
- π Progress: 20% complete (2x expected pace)
- π§ͺ Tests: 42 passing (unit + integration)
- β‘ Velocity: 50% faster than planned
- π― Architecture: Dual-ingestion with unified view
- πΎ Data Sources: OTel Demo + Test Generator validated
GitHub: Dual-Ingestion Architecture PR #10
Next: Day 4 - Real-time Features & AI Integration
Follow along as I document this accelerated journey. Whether this approach scales to full enterprise features or hits unexpected walls, you'll see every step of pushing AI-assisted development boundaries.
What's your experience with dual-ingestion architectures? Have you tried AI-assisted development workflows? Share your thoughts in the comments! π
Top comments (0)