Short answer: compare hosted log services by whether they preserve the evidence needed to replay an e-commerce incident while making user-scoped data easy to find, expire, delete, and export. Start with a deliberately small event schema, then run the same deletion and export drill against every candidate. Feature grids don't reveal whether an on-call engineer can reconstruct a failed checkout without collecting an email address, shipping address, or raw request body.
The useful mental model is evidence, not exhaust. Before: ship every application string and hope search rescues the investigation. After: define the questions an incident review must answer, emit only the fields that answer them, and give each field an owner and a retention class.
This changes the comparison. Good.
What evidence should survive an e-commerce incident?
Take a customer who clicks “Pay” and sees the cart again. The investigation needs a compact chain: a pseudonymous subject reference, cart and order references, a request or trace reference, the deployment version, the state transition, the dependency name, a bounded error category, and timestamps. It usually does not need the customer's name, full IP address, payment payload, address, session cookie, or the free-form exception object that happened to contain all of those values.
That distinction is the signal-quality decision. A broad message field feels flexible during development, but it mixes operational evidence with accidental personal data and makes later deletion depend on parsing prose. A typed event costs a little discipline up front. In return, the team can ask exact questions: Did order ord_demo_7F3 reach payment_requested? Which release emitted the transition? Did another service see the same trace? Was the failure a validation rejection or a dependency timeout? Those are incident questions, not log-volume questions.
Keep browser experience signals separate from identity-bearing application events. Core Web Vitals defines LCP, CLS, and INP and evaluates user experience at the 75th percentile. Those aggregates can help establish that a checkout page became slow or unstable, but they cannot explain an individual order transition. The two streams belong on the same incident timeline — deployment, aggregate experience change, then pseudonymous application events — without forcing customer details into the performance stream.
No raw payloads.
Here is the diagram in words: browser creates a request reference; the edge forwards it; each service emits a typed transition; an ingestion filter removes forbidden keys; hosted storage applies the selected retention class; a subject index maps the pseudonymous subject reference to event locations; deletion and export workers use that index; the incident view joins events by request, trace, cart, and order references. The index is important because “search every byte and hope” is not a deletion design.
How should EU app logging compare user deletion, retention, and export APIs?
Use a proof-based scorecard. Datadog, Better Stack, and Axiom can sit on the candidate list, but their names do not answer the architectural question. Configure an isolated evaluation dataset in each service and run the same operations. Record observed results and contract terms; don't infer them from a marketing page. Regional processing, deletion behavior, retention controls, and export semantics can depend on the selected service, plan, configuration, and current agreement, so those details must be verified during procurement and again before production rollout. I'm not sure which candidate fits your legal and operational constraints without that evidence, and a static comparison cannot settle it.
| Test | Evidence to capture | Failure that matters |
|---|---|---|
| EU data path | Contract, region configuration, and a test event's observed destination | A required processing step has no documented regional or contractual answer |
| User deletion | Before/after queries for one synthetic subject reference, completion record, and stated scope | Search results disappear but an included copy or tier is outside the documented operation |
| Retention | Policy configuration plus events placed on both sides of the expiry boundary | Expiry cannot be demonstrated for the storage classes the team will use |
| Export API | A repeatable export of the synthetic incident, including pagination and timestamps | The export cannot preserve ordering keys or be reconciled with the source query |
| Access evidence | Role matrix and an observed read/export/delete audit trail | A broad role can read or extract logs without the evidence the review requires |
| Incident reconstruction | A timed, scripted replay from alert to order timeline | The investigator needs a forbidden field or undocumented manual join |
The catch is that a hosted-service API can make deletion convenient without making the logging design GDPR-friendly. If the application emits an email address under five spellings, hides another copy inside message, and places the payment payload in an exception, a clean deletion endpoint cannot repair the schema. Conversely, a minimal schema is not enough when the processor, contract, region, access model, backups, and retention behavior do not meet the organization's requirements. Legal review still owns the legal conclusion; the engineering drill supplies concrete evidence for that review.
Set pass conditions before opening any dashboard. For example: the synthetic customer export contains all and only the approved event types; every item carries a stable schema version; the deletion operation has an observable completion record; queries using the subject reference return the agreed result after completion; and an on-call engineer can reconstruct the failed checkout using order, request, trace, release, state, and error-category fields. These are example acceptance criteria, not universal compliance thresholds. Your mileage may vary because the necessary evidence and retention period depend on the business process and legal basis.
Make the logging boundary executable
A written field policy gets stale. Put the boundary in code at the point where an application event becomes a log event, then test it like any other interface. The following TypeScript example uses an allowlist, bounded enums, a schema version, and synthetic identifiers. It rejects unknown keys before they reach a transport. The emit function is intentionally generic, so the same event contract can be exercised against each hosted destination without embedding a vendor client in the domain code.
type CheckoutState =
| "cart_validated"
| "payment_requested"
| "payment_rejected"
| "order_confirmed";
type ErrorCategory =
| "none"
| "validation"
| "dependency_timeout"
| "dependency_rejected";
type CheckoutEvent = {
schemaVersion: 1;
occurredAt: string;
subjectRef: string;
cartRef: string;
orderRef?: string;
requestRef: string;
traceRef: string;
release: string;
state: CheckoutState;
errorCategory: ErrorCategory;
};
const allowedKeys = new Set<keyof CheckoutEvent>([
"schemaVersion",
"occurredAt",
"subjectRef",
"cartRef",
"orderRef",
"requestRef",
"traceRef",
"release",
"state",
"errorCategory",
]);
function assertAllowedKeys(input: Record<string, unknown>): void {
const unexpected = Object.keys(input).filter(
(key) => !allowedKeys.has(key as keyof CheckoutEvent),
);
if (unexpected.length > 0) {
throw new Error(`Rejected log keys: ${unexpected.sort().join(", ")}`);
}
}
function toCheckoutEvent(input: Record<string, unknown>): CheckoutEvent {
assertAllowedKeys(input);
return input as CheckoutEvent;
}
type Emit = (event: CheckoutEvent) => Promise<void>;
async function recordCheckoutTransition(
input: Record<string, unknown>,
emit: Emit,
): Promise<void> {
const event = toCheckoutEvent(input);
await emit(event);
}
The example is a boundary, not a full privacy system. subjectRef must be created and governed outside this function; swapping an email address for a reversible or guessable value does not automatically make it safe. The code also needs runtime validation for types and allowed values in a production implementation. What it demonstrates is narrower and useful: an unexpected email, authorization, or requestBody key causes a test failure instead of becoming tomorrow's deletion surprise.
Now exercise the complete path with one synthetic incident. Emit cart_validated, payment_requested, and payment_rejected across two services using the same requestRef and traceRef. Confirm that the incident query reconstructs their order. Export by subjectRef, reconcile the exported event identifiers with the query, request deletion through the documented mechanism, and retain the operation record outside the data being deleted. Finally, advance events across configured expiry boundaries in a test environment and verify each retention class independently.
One drill. Every release.
When should you avoid a hosted logging service?
A hosted service is not suitable when policy forbids the required data path, when the organization cannot obtain acceptable contractual terms, when deletion must cover storage the service's documented mechanism does not address, or when the team cannot test export and expiry behavior end to end. Stick with a self-managed design when direct control of the storage lifecycle is the overriding constraint and the team can genuinely operate ingestion, analytical storage, access control, backups, deletion, export, upgrades, and incident response. ClickHouse is one documented option for analytical storage, but choosing a database does not supply the surrounding privacy and operations program.
Self-managed is not a magic compliance switch.
The reverse trade-off matters too. A small team may gain more reliable controls from a hosted system if it can verify the required region, contract, access evidence, deletion scope, retention behavior, and exports, while avoiding a database operations burden it cannot staff. Choose the operating model whose controls the team can repeatedly prove. Do not choose based on the prettiest search screen.
For the final decision, weight signal reconstruction and lifecycle proof above raw ingestion capacity. Reject any configuration that requires personal fields to make the checkout timeline useful. Among the remaining candidates, prefer the one that passes the scripted incident, deletion, retention, export, and access drills with the least undocumented manual work. That conclusion stays useful even as product packaging changes because the test belongs to your system.
Top comments (0)