3.29 Extension

There is no version number on any of the three interfaces. No datagram carries one, no query message carries one, and there is no exchange in which either party could state or discover what the other speaks.

That is a deliberate consequence of the shapes chosen, and it is worth being explicit about, because it means every rule below is the only mechanism available.

Ingestion is one-way over a datagram socket: there is no reply in which a collector could announce a version and no state in which a producer could remember one. The query channel could carry a version — it is a stream, and it has a request message — and does not, because a version field is only useful if a party may then behave differently, and a client cannot usefully vary: it either asks a question the collector understands or does not.

What replaces negotiation is a set of rules under which both sides may change without either being told.

3.29.1 Unknown fields are ignored #

A collector MUST ignore fields it does not recognise in a log record (§3.7), in a metric record (§3.11), and in a query request (§3.15).

This is what allows a field to be added. A producer built against a later revision may send a field this collector has never heard of, and the record is still stored; a producer built against an earlier one omits a field that has since been added, and the record is still stored because everything added is optional.

A field added to any of these three maps MUST therefore be optional, and a collector MUST NOT require one to be present.

3.29.2 Unknown values are refused, not ignored #

The rule does not extend to values.

An unrecognised type in a metric record discards the record (§3.12); a first token that is not a mode fails the query (§3.18); an unrecognised keyword is a parse error. A collector MUST NOT guess at an unrecognised value, and MUST NOT skip a field it recognised but could not interpret.

The asymmetry is the point. An unknown field is something the sender knows about and this collector does not, and ignoring it loses only what was never understood. An unknown value in a known field is the sender saying something specific about this record, and proceeding without understanding it stores something other than what was sent.

3.29.3 Response statuses #

A client MUST treat a response whose status it does not recognise as an error terminating the query, and MUST discard the "ok" messages it has received for that query unless "end" or "watch" had already arrived (§3.16).

A status is the control flow of the response stream, so there is no ignoring one: a client that skipped an unknown status would be waiting for a terminal message that had already been sent, or treating an incomplete result as complete. Failing is the only safe reading.

A collector MUST NOT introduce a new status for a condition that the four existing ones can express.

3.29.4 What may change without notice #

  • New optional fields in a log record, a metric record or a query request.
  • New fields in result records. A client MUST tolerate a key it does not recognise, and MUST NOT reject a record for carrying one.
  • New query keywords, clauses and functions. A client sending one the collector does not know receives a parse error, which is the correct answer.
  • Wording of any error string (§3.16).
  • New event types, log origins and metric names. These are data, not interface; nothing enumerates the valid set of any of them.

3.29.5 What may not change #

  • The meaning of an existing field, in either direction. A field is added or it is left alone.
  • The type of an existing field.
  • The four response statuses, or the rule that exactly one terminal message ends a query.
  • The framing of §3.15, which has no version field and therefore no way to change compatibly.
  • A required field becoming optional, or an optional one becoming required.

3.29.6 Limits are not the interface #

The declared bounds — the datagram ceilings (§3.6, §3.9), the query message ceiling (§3.15), the concurrency and timeout bounds (§3.14, §3.16), the existence window and lookback limit (§3.26) — are configuration, and an administrator may change any of them.

A collector MUST behave identically at any value in its supported range. A producer or client MUST NOT infer a bound from having exceeded one, or from not having exceeded one, and MUST NOT depend on the mainline defaults quoted in this chapter.

The one place this bites is the log and metric datagram ceilings, which a producer cannot discover and which silently discard what exceeds them (§3.6). Lowering either is a change to the contract with every producer on the system, and there is no mechanism by which any of them will find out.

Edit this page