Reduzer Technologies Training Institute
Our commitments
Online pilotApply
01
ReduzerPublic projectsProject 01
Engineering briefNo. 01

Build a logingestion engine.

Implement a centralised backend service that accepts logs over HTTP, validates and enriches them, routes them through RabbitMQ, stores them in SQLite and reports operational metrics.

Go to project requirements

Duration

7 days

Format

Solo

Review

Required

Base brief

11 requirements

RabbitMQHTTPSQLiteREST
BriefRequirementsInjectionsBuild planReview

Project summary

TYPE: BACKEND SYSTEM
DURATION: 7 DAYS
DELIVERY: SOLO
REVIEW: MANDATORY PEER REVIEW

This page is the source of truth for the project. Where a summary and an acceptance criterion differ, follow the acceptance criterion.

Problem context

InsureTech Corp cannot search or monitor logs centrally.

You arrive at InsureTech Corp as a junior backend engineer and discover that 12 microservices write logs to local files across different servers in inconsistent formats. Last week, a claims outage took three hours to resolve because engineers spent two hours SSH’ing into servers and grepping log files just to find the error. The monitoring dashboard has no visibility into application errors, nobody can tell which service is failing most, and the compliance team is demanding audit trails that do not exist.

Required outcome

Build the centralised system the team needed: one ingestion API that validates and enriches logs, routes them by service, writes them reliably, and surfaces live operational signals before customers notice the next outage.

Architecture boundary

Required processing pipeline

All valid logs must pass through the in-memory channel, enrichment and service routing before queueing and storage. Failed writes must be retried and then persisted to the dead letter file; logs must never be silently discarded.

Required data path

  1. 01

    HTTP

    POST /logs

  2. 02

    Buffer

    raw_logs

  3. 03

    Route

    enrich + map

  4. 04

    Queue

    RabbitMQ

  5. 05

    Store

    3 × SQLite

  6. 06

    Observe

    metrics + UI

Learning objectives

What the project is designed to assess

01

Protect an ingestion boundary under load

02

Move data through an asynchronous pipeline

03

Design for queue and storage failure

04

Turn raw events into operational signals

Base specification

Requirements

All acceptance criteria are mandatory unless an injected requirement explicitly changes them. Expand each requirement to read the complete criteria.

Phase 01

Ingestion & validation

3 requirements

REQ-001HTTP endpoint for log ingestionCreate a bounded JSON ingestion endpoint that acknowledges accepted work without waiting for storage.

Acceptance criteria

  • POST /logs accepts a JSON array of log entries.
  • Success returns 202 Accepted with { "status": "accepted", "batchId": "uuid" }.
  • Malformed JSON returns 400 Bad Request with useful error details.
  • Any Content-Type other than application/json returns 415 Unsupported Media Type.
  • Payloads over 1MB return 413 Payload Too Large.
REQ-002Log validationValidate every record independently so a bad log does not erase the useful part of a batch.

Acceptance criteria

  • Required fields are timestamp, service, level and message.
  • timestamp is a valid ISO 8601 value.
  • service is a string no longer than 100 characters.
  • level is one of INFO, WARN, ERROR or DEBUG.
  • message is a string no longer than 10,000 characters.
  • Invalid entries return field-level details using the documented validation error shape.
  • Partial batches are accepted: valid logs proceed and invalid logs receive individual errors.
REQ-003Rate limitingReuse your Sprint 3 token bucket to prevent a noisy producer from overwhelming the service.

Acceptance criteria

  • The token bucket implementation from Sprint 3 is reused; no third-party rate limiting library is used.
  • RATE_LIMIT configures the limit and defaults to 1,000 requests per second.
  • The limit is applied per source IP address and resets every second; a sliding window is not required.
  • Exceeded limits return 429 Too Many Requests with a Retry-After header.

Phase 02

Routing & enrichment

3 requirements

REQ-004In-memory channel queuingDecouple HTTP ingestion from downstream work with a bounded raw_logs channel.

Acceptance criteria

  • Validated logs are pushed to the raw_logs channel.
  • The channel buffer defaults to 10,000 logs and is configurable.
  • A consumer reads configurable batches that default to 50 logs.
  • A full channel returns 503 Service Unavailable with { "error": "ingestion overloaded" }.
  • Channel operations are non-blocking with a 100ms timeout.
REQ-005Log enrichmentAttach the operational context required to search and audit every accepted event.

Acceptance criteria

  • received_at is added in ISO 8601 format with microsecond precision.
  • source_ip comes from X-Forwarded-For or the request socket address.
  • env comes from configuration and defaults to production.
  • Enrichment completes in under 1ms per log.
  • Missing source information falls back to source_ip = "unknown".
REQ-006Service-based routingRoute every enriched event to one configured destination before it enters the write queue.

Acceptance criteria

  • Static service-to-destination rules are loaded from configuration, not hardcoded in the router.
  • Configured destinations are service1, service2 and service3.
  • Every log passes through enrichment and routing before queueing or storage.
  • An unmatched service uses a configurable default destination and emits a warning.
  • Routing logic is isolated from HTTP ingestion and storage modules.

Phase 03

Storage & queuing

3 requirements

REQ-007RabbitMQ queuing for writesPublish enriched logs to durable, service-specific queues and keep ingesting when RabbitMQ is unavailable.

Acceptance criteria

  • Direct exchanges exchange_service1, exchange_service2 and exchange_service3 are declared.
  • Durable queues queue_service1, queue_service2 and queue_service3 bind to their matching exchanges with routing key log.write.
  • RABBITMQ_HOST, RABBITMQ_PORT, RABBITMQ_USER and RABBITMQ_PASS supply connection settings.
  • A failed RabbitMQ connection activates an in-memory fallback and logs a warning.
  • Publishing times out after five seconds; failure is logged without blocking HTTP ingestion.
REQ-008SQLite batch writingConsume queued records in bounded batches and write them to service-specific databases efficiently.

Acceptance criteria

  • Consumers read from RabbitMQ queues or the in-memory fallback.
  • A batch flushes at 100 logs or after one second, whichever happens first.
  • logs_service1.db, logs_service2.db and logs_service3.db are created when missing.
  • Each database has a logs table with id, timestamp, service, level, message, received_at, source_ip and env columns.
  • Writes use prepared statements.
  • Write failures are logged with error details.
REQ-009Retry logic & dead letterMake failed writes visible and recoverable instead of silently discarding data.

Acceptance criteria

  • Failed writes are retried three times with backoff intervals of 1s, 5s and 10s.
  • Retry count is tracked per log and is visible in application logs.
  • After the final failure, the log is written to logs-failed.json.
  • Every dead letter entry includes the original log, error message and failure timestamp.
  • The dead letter file rotates after it exceeds 10MB.

Phase 04

Monitoring & reporting

2 requirements

REQ-010Metrics collectionBuild the operational counters and gauges from scratch and expose them as JSON.

Acceptance criteria

  • Track total_logs_received, logs_by_level, logs_by_service, error_rate and throughput.
  • Track queue_backlog using the RabbitMQ management API or a fallback counter.
  • Metrics live in memory and reset when the service restarts.
  • GET /metrics returns the documented JSON representation.
REQ-011Operational dashboardGive the team a dependency-free, auto-refreshing view of the system’s current health.

Acceptance criteria

  • GET /dashboard returns an HTML page that refreshes every five seconds.
  • Display total logs, logs per second, error rate, the top five services by volume and queue backlog.
  • Use server-sent events or polling without external JavaScript dependencies.
  • Style the dashboard with plain CSS; no UI framework is required.

Injected requirements

Scheduled changes to the specification

Additional requirements are released during the project. Once a requirement is released, it becomes mandatory and is included in the grading criteria. Check this section at the indicated release time.

Requirement drop 01

Unlocks Day 4

The requirement details remain hidden until Day 4. Continue with the base specification until this section unlocks.

Release schedule coming soon

Requirement drop 02

Unlocks Day 6

The requirement details remain hidden until Day 6. Continue with the base specification until this section unlocks.

Release schedule coming soon

Release times are calculated from the public campaign start date. All participants receive each injected requirement at the same time.

Technical rules

Technical constraints

These constraints are assessed alongside functional behavior. A solution that bypasses them does not meet the specification.

  1. 01Build metrics collection from scratch; do not use Prometheus, StatsD or another monitoring library.
  2. 02Reuse the Sprint 3 token bucket; do not use a third-party rate limiting library.
  3. 03Write raw SQL with prepared statements; do not use an ORM.
  4. 04Put every setting in environment variables or configuration files.
  5. 05Never silently drop a log. Exhausted writes must reach the dead letter file.
  6. 06Do not bypass enrichment and routing on the way to storage.
  7. 07Keep ingestion, routing, storage and monitoring in separate modules.
  8. 08Keep blocking file operations out of the ingestion path.
  9. 09Read credentials from environment variables only.
  10. 10Do not exceed configured concurrency; the rate limit is authoritative.

Suggested build order

Suggested 7-day build order

You may use a different sequence, but all requirements, tests, documentation and peer review are due by the end of Day 7.

Days 1–2

01 / 05

Ingestion & routing

  • Build POST /logs, validation and the token bucket.
  • Add raw_logs, batch consumption, enrichment and routing.
  • Test valid, invalid and partially accepted batches.
Days 3–4

02 / 05

Storage & queuing

  • Declare RabbitMQ exchanges, queues and bindings.
  • Add the in-memory fallback and SQLite batch writers.
  • Exercise retries and dead letter persistence.
Day 5

03 / 05

Monitoring

  • Build counters and gauges without a metrics library.
  • Expose GET /metrics and the operations dashboard.
Day 6

04 / 05

Respond to the brief

  • Implement the released operational requirement drops.
  • Retest the pipeline under the new constraints.
Day 7

05 / 05

Test, explain, review

  • Complete unit, integration and 1,000 logs/sec load tests.
  • Document architecture, API and concurrency decisions.
  • Complete a mandatory peer review and address the findings.

Submission checklist

Required deliverables

The implementation alone is not a complete submission. Provide the following evidence so another engineer can run, test and evaluate the system.

  1. 01A public source repository with a readable commit history.
  2. 02A README that explains the architecture, setup, configuration, API, concurrency model and failure behavior.
  3. 03Unit tests for validation, rate limiting and routing.
  4. 04Integration tests for the pipeline, RabbitMQ fallback, SQLite batching, retries and dead letter handling.
  5. 05A load-test result showing the system handling 1,000 logs per second, including the test method and observed bottlenecks.
  6. 06Evidence that GET /metrics and GET /dashboard report the required values.
  7. 07A completed peer review with reviewer notes and a record of the changes made in response.

Evaluation

Grading criteria

Ingestion & validation20%
Routing & enrichment15%
Storage & queuing20%
Monitoring10%
Alerting & maintenance10%
Testing10%
Code quality10%
Documentation5%

Mandatory peer review

Assessment questions

The reviewer should ask these questions and inspect the code, tests and runtime evidence supporting each answer. Record the findings and the changes made after review.

  1. 01What fields are required in a log entry, and which status codes can POST /logs return?
  2. 02How does your rate limiter work, where is it applied, and what happens when the limit is exceeded?
  3. 03Why does the ingestion path use an in-memory channel instead of writing directly to SQLite?
  4. 04Which enrichment fields do you add and where does each value come from?
  5. 05How are routing rules structured, and how does the router choose a SQLite database?
  6. 06Why use RabbitMQ? What changes when it is unavailable?
  7. 07How does batch writing work, and what is the retry and backoff strategy?
  8. 08What reaches the dead letter file and how can those records be recovered?
  9. 09Which metrics do you track, and what does GET /metrics return?
  10. 10Which alert conditions exist, and how do you prevent alert spam?

Participation and peer review

Publish the implementation evidence

Use a public repository. Post the architecture, important trade-offs, test results, performance evidence and final demo. Ask another developer to complete the required peer review. Tag @reduzer_tech so Reduzer can find the submission.

Start with REQ-001Create a repository
01

Declare your approach

Document the language, architecture, configuration and main risks before implementation.

02

Post evidence

Publish commits, test output, throughput results, metrics and dashboard evidence.

03

Invite review

Have another developer inspect the failure paths, record their findings and document your fixes.

Next project

More public engineering briefs are coming.

View the project series
Reduzer Technologies Training Institute

Reduzer Technologies Training Institute

Programme

  • Public projects
  • Fit and readiness
  • Graduate capability
  • How it works
  • Programme
  • Online pilot
  • Our commitments
  • Why Kisii
  • Cost

Admissions

  • Parents and sponsors
  • Sponsor a student
  • Admissions process
  • Apply for the in-person programme
  • Apply for the online pilot
  • FAQ

Contact admissions

Parents and sponsors can confirm fees, intake dates, seat availability, expectations, and support arrangements before committing.

Call +254 769 267 965Message admissions on WhatsAppEmail hello@reduzer.ac.ke

© 2026 Reduzer Technologies Limited

In person and online · Starts 5 October 2026

  • Privacy policy
  • Terms of service
  • Cookie policy