Two questions, two audiences
Every framework ships with observability: request counts, latencies, error rates, a trace per call. It answers the questions an engineer has at 2 a.m.: is it up, is it slow, where did it break. It says nothing about the questions a managing director has on a Tuesday: did the quotes signed this week get their confirmation, how many files escalated, did the payout clear.
Most teams try to answer the second set with the first layer, by squinting at dashboards of HTTP status codes and guessing. It does not work, because a 200 on a request is not a sale, and a 500 is not necessarily a lost customer. The two questions need two layers.
The second layer
We always ship a thin layer of domain events named in the language of the business: quote.signed, case.escalated, payout.cleared, session.closed. Each carries the identifiers the business uses, the customer, the file, the amount, and nothing else. They are emitted where the thing happens, in the code that does it, not reconstructed later from logs.
That layer is small: a few dozen event names for most businesses, chosen with the people who will read them. The cost is a line of code per event. The return is that the Tuesday questions become queries, and the queries become a dashboard the finance team can read without an engineer in the room.
Keep them apart
The temptation is to merge the two: attach the business fields to the HTTP trace, or push the technical detail into the business event. Resist it. Domain events stay readable because they do not carry HTTP detail; HTTP traces stay focused because they do not carry business semantics. Mixed, each becomes useless to its audience: the CFO scrolls past stack traces, the engineer wades through customer names at 2 a.m.
What links the two is the identifier. A file's id appears in the business event and in the trace that produced it, so when the engineer needs to know why case.escalated fired twice, the path from the business question to the technical cause is one lookup, not an afternoon.
What it changes
For a training platform handling ten thousand learners a year, the business layer is what lets the operations team see the exceptions and not the firehose: a learner who stalled, a certificate that did not go out, a session with no attendance recorded. Those are domain events; the platform's health is a different screen, watched by different people.
It also changes the conversation with the client. A platform that reports in the client's own vocabulary is a platform whose value can be read every month, by them, without asking. That is worth more than any uptime figure.