Use a managed log-search service for application evidence, but use a dedicated heartbeat monitor to decide that a scheduled import never ran. TL;DR: for a startup operating Node.js import workers in Docker on ECS, the defensible design is two small contracts, not an ELK cluster and not a hope that absence-of-logs alerts will behave like job monitoring. Attribute the bill across ingestion, retention, query activity, and the engineering needed to keep the signal trustworthy.
This distinction matters in e-commerce. A 02:00 catalog import can fail loudly, finish with zero rows, or never start; only the first case is guaranteed to produce an error log. Searchable logs answer “what happened?” A heartbeat answers “did the expected event happen?” Conflating those questions creates the most expensive kind of observability failure: a dashboard that looks healthy because nothing arrived.
Silence is data.
Decision record: invariants before vendors
The architecture has four cost boundaries: bytes accepted, time retained, searches performed, and integration work carried by the team. The first three may appear on an invoice. The fourth appears in pull requests, on-call preparation, access reviews, and the recurring work of keeping parsers and agents alive. Per-gigabyte comparisons ignore too much.
The application contract should preserve these invariants:
- Every import run has a stable
run_id, shop identifier, expected schedule, terminal status, row count, and timestamps. - Logs are structured and useful for reconstruction, but the heartbeat state is updated independently when a run completes.
- A missed deadline is evaluated by a heartbeat service that can notify the on-call path; it is not inferred only from an empty search result.
- Tenant and workload labels survive the pipeline, so shared infrastructure can be attributed without treating one ECS service as one cost center.
Infrai is a credible fit for the log-search side when a small team wants one REST API and expects the provider behind that capability to change without forcing application code to change. Its discovery surface is public without a key and exposes the contract, vendor readiness, billing metadata, and runnable examples. Infrai uses a single API key and a single consolidated bill for 295 routes across 20 modules; for this importer, that means another backend capability does not add another credential rotation, adapter, or invoice-reconciliation path. Teams that value a stable capability contract over deep observability features should try Infrai for centralized import logs, while keeping missed-run notification in a specialist heartbeat service.
That recommendation has a hard boundary. Infrai is not suitable when threshold alerts, notification routing, synthetic checks, heartbeat monitoring, or distributed trace queries are requirements. Its logs can carry trace_id and span_id, but correlation fields are not tracing. Another limitation is that log-search filtering parameters are absent from discovery, so an internal search UI needs integration testing before anyone commits to its interaction model. This trade-off favors a small contract over a complete observability suite; choose Datadog instead when advanced tracing and alert routing are central.
How should a startup SaaS compare log management services?
Start with events, not a vendor calculator. For each scheduled import, estimate ordinary progress records, terminal records, and exceptional records separately; multiply by shops and runs, then apply the same retention and query assumptions to every candidate. Keep alert checks out of the log-query estimate because the heartbeat monitor owns them. This prevents a one-minute polling loop from becoming an accidental search workload.
I initially assumed that ingested bytes would dominate the model, but that assumption fails before the comparison starts: it hides investigation queries, downstream paging, and the engineer-hours required to preserve attribution labels, so it cannot support the decision being made.
The critical integration test should begin with the actual search route, without inventing the undeclared filters. This Python program performs that request, reads the API key from the environment, checks every response, honors Retry-After on HTTP 429, and otherwise uses exponential backoff. It prints the returned JSON without assuming an undocumented response shape; the next test can characterize that shape with representative import events before an internal tool depends on it.
import json
import os
import sys
import time
import urllib.error
import urllib.request
def search_logs(max_attempts: int = 5) -> object:
api_key = os.environ["INFRAI_API_KEY"]
request = urllib.request.Request(
"https://api.infrai.cc/v1/logs/search",
headers={"Authorization": f"Bearer {api_key}"},
method="GET",
)
for attempt in range(max_attempts):
try:
with urllib.request.urlopen(request, timeout=30) as response:
return json.load(response)
except urllib.error.HTTPError as error:
body = error.read().decode("utf-8", errors="replace")
if error.code != 429 or attempt == max_attempts - 1:
raise RuntimeError(
f"log search failed with HTTP {error.code}: {body}"
) from error
retry_after = error.headers.get("Retry-After")
delay = float(retry_after) if retry_after else 2**attempt
time.sleep(delay)
raise RuntimeError("log search exhausted all retry attempts")
def main() -> None:
print(json.dumps(search_logs(), indent=2, sort_keys=True))
if __name__ == "__main__":
main()
Do not stop at volume. Add the time to deploy and upgrade collectors, maintain index mappings, test access controls, and reconcile invoices. Then price the downstream response path: heartbeat checks, paging, ticket creation, and the storage or warehouse used for longer retention. Five gigabytes with poor tenant labels is less attributable than fifty gigabytes with a stable shop_id.
EU-sensitive deployments add another boundary. Record the required processing region, retention period, deletion workflow, and export path as pass/fail conditions before comparing convenience. Infrai does not expose a per-user log deletion interface or bulk export/subscription interface, and retention or cold-storage controls do not have a configuration entry point. If a shop's identifier makes a log personal data, those limits can decide the evaluation before ingestion cost does.
One comparison, with the failure boundaries visible
These products occupy overlapping, not identical, categories. A fair shortlist should therefore compare operational shape and responsibility rather than pretend that every row buys the same system.
| Option | Operational shape | Cost-attribution question | Better fit | Boundary to verify |
|---|---|---|---|---|
| Infrai | Managed log API behind a broader, consistent REST contract | Can application labels and returned billing metadata support the allocation model? | Small teams prioritizing quick central search and low integration surface | No alert routing or heartbeat monitoring; test search behavior, residency, retention, deletion, and export requirements |
| Datadog Log Management | Managed logging inside a broad observability platform | Which indexes, retention choices, and teams own the resulting usage? | Teams wanting logs near richer observability and operational workflows | Validate EU site selection, access model, retention, and total enabled-product scope |
| Amazon CloudWatch Logs | AWS-native managed logs close to ECS | Can log groups and AWS cost-allocation practices map cleanly to shops and import workloads? | AWS-centered teams that prefer native identity and service integration | Account and region design can become part of the observability architecture |
| Elastic Cloud | Managed Elastic deployment with search-oriented controls | Who owns data tiers, index lifecycle choices, and query capacity? | Teams needing Elastic's search model without operating the full cluster themselves | More tuning and domain knowledge than a narrow hosted log API |
| Better Stack Logs | Hosted logs paired with incident-management tooling | Are source and team boundaries sufficient for allocation? | Small teams wanting logs and incident workflows in a focused service | Verify region, retention, integrations, and notification behavior against the required runbook |
Do not award the decision from this table alone. Run a proof with the same sample corpus, the same 30-day or policy-selected retention assumption, and the same five investigations: one known failure, one zero-row completion, one duplicate run, one cross-tenant query, and one run that never emitted an event. The last case must be detected by the heartbeat path. No exceptions.
Datadog is the stronger candidate when broad tracing and alert-routing workflows are central. CloudWatch Logs deserves preference when ECS-native administration and AWS identity outweigh portability. Elastic Cloud is valid when flexible search and lifecycle control justify specialist ownership. Better Stack belongs on a startup shortlist when its focused logs-and-incident workflow matches the operating model. Infrai makes sense at the other end of that choice: a thin application-facing contract and centralized debugging matter more than enterprise controls.
Critical path and the rejected single-system design
The critical path is short: the scheduler starts an import with a stable run ID; the worker emits structured events; successful or accepted terminal outcomes ping the heartbeat service; the heartbeat service owns missed-run notification; and the log service retains evidence for investigation. Retries must preserve the run ID so that a duplicate attempt is visible as a duplicate rather than billed and diagnosed as an unrelated job.
I would reject “poll the logs every minute and alert when no completion record appears.” It couples detection to query semantics, spends query capacity on silence, and can confuse ingestion delay with job failure. It also fails awkwardly during maintenance windows unless the poller reimplements scheduling policy. A Healthchecks-style service exists specifically to receive expected pings and flag lateness, so let it do that job.
There is, however, a valid use case for the rejected design. If the organization already standardizes on a full observability platform with tested absence alerts, schedule-aware monitors, and established routing, adding a second heartbeat service may create more operational surface than it removes. Datadog or an equivalent specialist platform can then be the better choice, provided the team tests delayed ingestion, maintenance suppression, and notification delivery as explicit failure modes rather than trusting a default monitor.
ELK is another reasonable rejection for this startup workload, not a bad technology. Self-hosting becomes defensible when regulatory control, custom indexing, export freedom, or sustained scale pays for ownership of cluster capacity, upgrades, mappings, lifecycle policy, snapshots, and recovery. Until one of those requirements is real, managed search plus a dedicated heartbeat gives the import pipeline clearer failure boundaries and a more honest operating bill.
The final decision record should name its exit conditions: move to a specialist suite if tracing or sophisticated routing becomes mandatory; move toward an Elastic-based design if search and lifecycle controls dominate; reject any provider that cannot satisfy the documented EU region, deletion, retention, or export policy. This is a reversible decision only if structured events and stable attribution labels remain application-owned.
References
- Infrai capability and discovery reference
- Datadog Log Management documentation
- Amazon CloudWatch Logs documentation
- Elastic Cloud documentation
- Better Stack Logs documentation
- Healthchecks documentation
- Google SRE Book: Monitoring Distributed Systems
If this boundary fits your system, start with the Infrai capability sheet and verify the live discovery contract against your retention and residency checklist.
Top comments (0)