Technical Blog · Network telemetry

One model, every vendor: multivendor interface state in Grafana

Author

Jérémy Leclech

Published July 7, 2026

LinkedIn

Summary

Nokia and Arista report the same interface state in different shapes. Here's how one normalized model puts both vendors in a single Grafana dashboard.

Ask an Arista cEOS and a Nokia SR Linux the same two things: how many octets an interface received, and whether it is administratively up. You get two different answers. Not different numbers. Different shapes.

Arista returns them as OpenConfig:

  • counters at /interfaces/interface/state/counters/in-octets,
  • admin status at /interfaces/interface/state/admin-status, as UP / DOWN.

Nokia SR Linux native srl_nokia model:

  • counters at /srl_nokia-interfaces:interface/statistics/in-octets,
  • admin status at /srl_nokia-interfaces:interface/admin-state, as enable / disable.

Same facts. Different paths, different leaf names, different value vocabulary.

You guessed it, it's where network monitoring breaks.

The cost of multivendor data shapes

The counter values aren't the even hardest part. The trickiest part is everything downstream of them.

If your data carries the vendor's shape all the way to the dashboard, then every Grafana panel, every Prometheus rule, every alert threshold has to know which vendor it is looking at.

  • admin-status == "UP" for one fleet,
  • admin-state == "enable" for another.

One PromQL query becomes two. A "shut interfaces" panel becomes a per-vendor OR. And the day you add a third platform, you go back and change all of it again.

You end up maintaining the same logic again and again, once per vendor. The network is no more complex than before. Only the data shape changed.

And it shows up at the worst time. It's 2am, you filter for the interfaces that are shut, and the panel is wrong: half the fleet reports disable, and the rule only matches DOWN.

Nobody wrote a bug. The query was simply never told that two vendors name the same state differently. These problems are hard to spot. They show up on the one device nobody handled separately.

Where to absorb the difference

You can normalize in three places, and only one of them scales.

  • In the dashboard. Grafana transforms and value mappings do the job. The work only ever helps that one dashboard: the next panel, the next person's dashboard, the alert rule that skips Grafana entirely, none of them benefit.
  • In Prometheus. Relabeling and recording rules make it more reusable. But now you handle the vendor differences in PromQL, far from the device that caused them, and every consumer still has to trust the rules are complete.
  • At collection time. The difference never leaves the collector. One place already has to be vendor-aware: the part that talks gNMI to the box. That is the place that resolves the vendor's shape.

Everything downstream receives data with no vendor-specific shape left in it. You write the translation once, next to the device knowledge that explains it. Then you stop redoing it in every tool that reads the data later.

It's the same idea as checking input once, at the boundary, instead of repeating the check everywhere. Handle the difference where it enters, and the rest of the system can assume it is already gone.

The concept: normalize once, at collection time

The idea is to keep the vendor's shape from leaving the collector. You define one model with vendor-neutral field names, and you attach one mapping per vendor that translates that vendor's paths and values into your field names.

The vendor difference is handled at the edge. Everything past that point sees a single, stable shape: Prometheus, Grafana, your alerts, an AI agent reading the data.

For interface state, that model is eight fields:

interface-name, admin-status, oper-status, mtu, in-octets, out-octets, in-errors, out-errors.

Those names never change, whoever made the box. The pipeline looks like this:

                          ┌── Arista cEOS  (OpenConfig)
Devices ──(gNMI)──────────┤                                 one model,
                          └── Nokia SR Linux (srl_nokia)    per-vendor mapping
                                      │
                                      ▼
                          Prelude Collector ──(/metrics/collector)──► Prometheus ──(query)──► Grafana

Two vendors go in. One shape comes out. Here's what that looks like end to end, in the web UI.

Two vendors, one collector

Start with the devices. Two boxes from two vendors, an Arista cEOS and a Nokia SR Linux, added to the collector and connected over gNMI. Nothing vendor-specific happens here yet. They are just two gNMI targets.

Both devices added to the collector, active over gNMI

The collector already knows how to talk to each one. What it doesn't know yet is that the two devices are saying the same thing in different words. That is what the model handles.

One model, per-vendor mappings

In the collector you create an interface-state model: eight vendor-neutral fields, plus a gNMI mapping for each vendor (Arista's OpenConfig paths, Nokia's native srl_nokia paths). One definition, one translation per vendor. The full model, with both mappings, is written up in the tutorial linked at the end.

The collector's model list with the interface-state model highlighted: eight fields, one mapping per vendor

The interesting work is in the mappings, and it's more than renaming paths. A mapping normalizes three things at once:

  • Paths. Arista's OpenConfig path and Nokia's srl_nokia path both feed the same field.
  • Value vocabularies. Arista's UP/DOWN and Nokia's enable/disable both have to map to the same admin-status values, or your downstream logic depends on the vendor again.
  • Units. A counter has to mean the same thing too. In our model, in-octets and out-octets are always in octets. If a vendor reported its counter in bits, or in megabits, the mapping converts it to octets on the way in. So the numbers are directly comparable across the whole fleet, with no per-vendor scaling factor to remember later.

So the field doesn't just have the same name across vendors. It has the same meaning.

The proof: compare vendors side by side

This is the step worth pausing on. Before you build a single dashboard, the collector can test both mappings against the live devices and show you the result field by field, one vendor next to the other.

Compare Vendors: both platforms resolving to the same field names and values

Two devices, two completely different native models, and the output columns line up exactly. admin-status reads the same on both. in-octets reads the same on both.

This is the consistency we were after, verified against real devices, not assumed from a spec. Everything after this step is simple, precisely because this step was not.

From here it is routine: start a subscription on each device, and the collector streams normalized fields continuously.

From the collector to Grafana

The collector can send its output to several backends. For this post we use Prometheus: it exposes every collected field on a /metrics/collector endpoint.

You enable that output in the UI and set the Output Hints, so each field is exposed the right way: counters for the octet fields, an info series for the status labels.

Output Hints: telling the collector how to expose each field to Prometheus (counters for octets, an info series for status)

From there it is standard Prometheus and Grafana: point Prometheus at the endpoint, add it as a Grafana data source, and import a ready-made dashboard.

That's only a few UI steps, and the full click-by-click guide is already written, linked at the bottom. The point here isn't the setup. It's what you see once it is done.

One dashboard, every vendor

A single Grafana dashboard showing both vendors in the same panels

There's the result. Inbound and outbound traffic, interface status, error rates: every device subscribed to interface-state shows up in the same panels. The Arista and the Nokia appear side by side, separated only by a device label. No per-vendor query. No OR clauses. No special cases.

And it stays that way. Add an SR OS box, a Cisco IOS XR box, anything: you write one more mapping into the same model, start a subscription, and it appears in these panels automatically. You never touch the dashboard for a new vendor. It only ever sees one shape.

And the dashboard is only the most visible consumer. The same normalized fields feed your Prometheus alert rules, where one oper-status expression covers the whole fleet. They also feed anything else that reads the collector's output.

If you point an AI agent at your network, it gets the same clean shape: it works with oper-status and in-errors, not with whichever vendor is answering. Clean ground truth, with no vendor-specific format to learn.

That is the whole idea: do the vendor-specific work once, at the edge, where it stays contained and testable. Then the rest of your stack never has to do it.

Try it on your own network

Everything above runs in the collector's web UI, and the full step-by-step is in two tutorials:

Prelude Collector is free for up to 20 devices. A single docker compose up -d and you're collecting. If you run a multivendor network and want to see your own devices in one shape, reach out for a demo.

Ready to see Prelude in action?

Set up the free version of Prelude products in your own environment and see the results for yourself.

Get Started