Course outline

Grafana / Intermediate: transformations, configuration, and alerts / Lesson 7

Transformations, joins, and order

Review panel transformations as an ordered data program, with explicit keys, output shape, missing rows, and limitations for server-side consumers.

About 4 min readContent reviewed
On this page

Lesson goals

  • Explain why transformation order changes meaning.
  • Check join-key uniqueness and time alignment.
  • Separate panel transformation from backend or alert semantics.

Each transformation consumes the previous shape

Grafana transformations can filter, rename, convert, calculate, reduce, or join returned data according to supported options. They form an ordered chain: removing a field can make a later join impossible, and reducing time series can discard timestamps needed for another operation. Review input and output frames at every step. A transformation can make a panel easier to read while changing the population or losing diagnostic detail. It is not a repair for wrong source authorization or an incorrect measurement boundary. Use the actual v12.1.0 transformation definitions rather than assuming every plugin returns interchangeable frames.

A join needs more than matching field names

Join by field and related operations depend on compatible key values, types, and row relationships. A route name can be nonunique across environments, and timestamps that differ by unit or precision may fail to align. Inner and outer choices preserve different unmatched rows. Inspect uniqueness and expected cardinality before joining metadata to delay observations. Duplicated metadata can multiply rows and distort a later mean. A source field called route is not automatically a trusted identity or access claim. Keep the scope and authority of each query result explicit.

Write the intended intermediate shapes

The editorial plan keeps route and time through filtering, checks one metadata row per scoped route, then joins and selects display fields. It is not Grafana transformation JSON or an executable panel. The point is to make the relationship reviewable before selecting UI controls. Organize fields, Reduce, and other named transformations have particular input requirements and options. A source returning multiple frames can need a different chain from one returning a single table. Keep missing-key and duplicate-key behavior in the contract rather than accepting whichever rows happen to remain after a successful-looking transformation.

yaml Editorial transformation-chain plan
transformation_plan: transit-route-delay
steps:
  - preserve-scoped-route-and-time
  - filter-intended-population
  - assert-unique-metadata-key
  - join-reviewed-relationship
  - select-display-fields
missing_key_policy: visible-and-reviewed

This is a review record, not Grafana configuration. It names preconditions and intended order without executing a join or selecting UI settings.

See how duplicate keys change a statistic

The offline relational model joins two delay rows with metadata containing a duplicate route. It produces three rows and a different row-weighted mean, even though no delay changed. This is not an implementation of a Grafana join transformation; its purpose is to expose a cardinality risk. A real chain must be tested with its supported join mode and frame structure. Do not hide a duplicate by arbitrary first-row selection without reviewing ownership and identity. If the desired statistic is one value per original departure, preserve that population through every transformation.

python Offline join-cardinality fixture
delays = [("r1", 5.0), ("r2", 10.0)]
metadata = [("r1", "team-a"), ("r1", "team-b"), ("r2", "team-c")]
joined = [(route, delay, team) for route, delay in delays for key, team in metadata if route == key]
print("original_rows", len(delays))
print("joined_rows", len(joined))
print("original_mean", sum(delay for route, delay in delays) / len(delays))
print("joined_mean", f"{sum(delay for route, delay, team in joined) / len(joined):.2f}")
Expected output
original_rows 2
joined_rows 3
original_mean 7.5
joined_mean 6.67

The fixed-list join demonstrates duplicated weighting only. No Grafana transformation, data frame API, backend, or query is executed.

Panel appearance is not an alert pipeline guarantee

A panel transformation chain and a server-side expression or alert query are separate execution contracts. Do not assume that a visually transformed value is automatically available to alert evaluation. Check the selected data-source plugin and supported server-side operations. Record both the original query and transformed display when investigating disagreement. This lesson runs only the synthetic join model and supplies an editorial plan. It validates no Grafana transformation engine, query, alert, browser execution, or plugin capability. Preserve those limitations and the exact field-shape assumptions in any handoff.

Common errors and fixes

A join silently doubles some departures

Why it happens
The metadata key is not unique.
How to fix it
Review cardinality and repair the identity relationship.
Prevent it next time
Test duplicate and unmatched keys.

A later transform cannot find Time

Why it happens
An earlier reduction or field selection removed it.
How to fix it
Inspect intermediate frames and reorder deliberately.
Prevent it next time
Document each stepโ€™s input and output.

An alert disagrees with a transformed panel

Why it happens
Separate execution paths were assumed identical.
How to fix it
Review the actual server-side query and expression.
Prevent it next time
Validate display and alert contracts independently.

Check your understanding

1. Why is checking only the final row count insufficient after a join?

Show worked solution

Equal counts can still conceal missing identities, duplicated weights, or incorrect metadata assignments. Compare keys, values, unmatched rows, and the intended population. A successful transformation UI state does not establish semantic correctness; use small known cases that expose the relationship and later statistic.

2. Can a panel transformation be used as the only definition of a critical alertโ€™s measurement?

Show worked solution

Not safely by assumption. The alert needs its own supported query or server-side expression with documented population, timing, units, and missing-data behavior. Verify that the chosen plugin and edition support that path. Keep any difference from the panel chain explicit and test both contracts.

Key takeaways

  • Transformations form an ordered program over frames.
  • Join cardinality can alter values without changing observations.
  • Display and alert execution paths require separate evidence.

Official references