Skip to main content

Pizzeria observability on Grafana Canvas panel

· Updated on July 31, 2023
Mikhail Volkov

Can you smell it? The aroma of the baked pizza? Do you feel it? The increasing heartbeat rate when you look at the countdown timer where only 30 seconds left? How about joy mixed with pride when watching the number of completed orders increase and your revenue of the day bloom?

All that is possible now with Grafana 10 and the canvas panel, which becomes generally available in the latest Grafana 10 release. It saw the light of dawn in June 2023, and no doubt it could be called the best Grafana release yet.

The canvas panel is far from being complete but mature enough for a production environment. The breathtaking presentation featuring the house's energy with metrics and animated wind turbines gave many of us the itch to drop everything and try to build something with it.

As proved many times, Grafana is a champion in the observability of K8s clusters, monitoring logs, and traces.

However, we at Volkov Labs find it delightful to explore other Grafana possibilities. Time after time, we uncovered it being effective in areas yet to be considered. This time our love for pizza and the news about the Canvas panel being released as part of the core begged us to challenge ourselves with the pizzeria observability dashboard.

Canvas panel for Grafana | Advanced animated SVG element.

The results are in and look pleasing. Keep reading to learn what we were able to come up with.

Mockup

We started by designing the layout of the panel in Figma. The canvas panel requires the background to be a raster image, and custom elements are based on vector SVG graphics. Figma can do both at the same time!

We selected the most important metrics to track in the pizzeria observability journey:

  • Number of online and walk-in orders.
  • How many orders were completed today.
  • Revenue based on the completed orders.
  • Waiting time for walk-in customers.
  • Status of the ovens and progress of pizza baking.

The pizza oven includes:

  • Timer to display time left.
  • Smoke, lights, fire and knob lights to indicate that the oven is working.
  • Pizza opacity to imitate the baking process. The fully cooked pizza has 100%.
We used Figma to create an SVG mockup with observability metrics.
We used Figma to create an SVG mockup with observability metrics.

Background

The data metrics were removed from the Mockup and will be replaced with data elements on the canvas panel. Pizza ovens will be replaced with advanced custom elements.

Background image with pizzeria layout and placeholders.
Background image with pizzeria layout and placeholders.

The exported background file can be placed in the public/img/bg/ folder mapped in the Docker container or referenced from the URL in the panel's options:

Background image can be placed in the container or referenced by URL.
Background image can be placed in the container or referenced by URL.

Pizza oven

As we mentioned the wind turbine, drone and server elements in the canvas panel look interesting, but these kinds of elements can't be easily incorporated in the working version of Grafana. New advanced elements should be scripted in the Grafana source code, compiled and built into the new Docker container to take advantage of.

Creating new advanced elements starts with a transparent SVG file. This file will be used in the React display component. We recommend including id attributes to identify and animate layers.

Created oven's layers consist of text, vector, and ellipse elements with added filters and effects for a natural look and feel.

Pizza oven was exported as transparent SVG with id attribute to identify layers.
Pizza oven was exported as transparent SVG with id attribute to identify layers.

Advanced canvas element

The advanced canvas element consists of:

  • Definition with id, name, and description.
  • Options with default parameters for background, and placement.
  • UI options for element configuration.
  • Function to return data from data sources.
  • React component to display the element.

Element definitions

All custom elements should be identified with id, name and description. Name and description will be displayed for user selection in the panel options. The default size should be set based on the exported SVG width and height.

export const pizzaOvenItem: CanvasElementItem = {
id: "pizzaOven",
name: "Pizza Oven",
description: "Animated pizza oven",
display: PizzaOvenDisplay,
defaultSize: {
width: 200,
height: 300,
},
};

UI configuration options

We selected state and time options as input dimensions which can be set as fixed or data source field values:

  • state controls lights, fire and knob lights to indicate that the oven is working.
  • time displays how much time is left and controls the opacity of the pizza layers.
registerOptionsUI: (builder: any) => {
const category = ["Pizza Oven"];
builder
.addCustomEditor({
category,
id: "state",
path: "config.state",
name: "State",
editor: ResourceDimensionEditor,
})
.addCustomEditor({
category,
id: "time",
path: "config.time",
name: "Time",
editor: ResourceDimensionEditor,
});
};

Values from data sources

Based on the configured options values will be static or returned from the data source. To create a data structure to display elements we used getResource method to retrieve the last value from the data source.

  prepareData: (ctx: DimensionContext, cfg: PizzaOvenConfig) => {
const stateValues = cfg?.state && ctx.getResource(cfg.state).field?.values || [];
const timeValues = cfg?.time && ctx.getResource(cfg.time).field?.values || [];

const data: PizzaOvenData = {
state: stateValues.length && stateValues[stateValues.length-1],
time: timeValues.length ? timeValues[timeValues.length-1] : 0
};

return data;
},

React display component

The display component for the pizza oven returns SVG graphics with smoke animation and is controlled by the configured UI options and data source values.

An advanced element with styles, types and a React component
blog/2023-07-23-pizzeria-canvas/pizzaOven.tsx
loading...

The proposed canvas element was created in the public/app/features/canvas/elements/ folder and included in the registry (public/app/features/canvas/registry.ts) as an advanced element item:

export const defaultElementItems = [
metricValueItem, // default for now
textItem,
rectangleItem,
iconItem,
serverItem,
];

export const advancedElementItems = [
buttonItem,
windTurbineItem,
droneTopItem,
droneFrontItem,
droneSideItem,
pizzaOvenItem,
];

export const canvasElementRegistry =
new Registry() <
CanvasElementItem >
(() => [...defaultElementItems, ...advancedElementItems]);

Developing and building a Docker image

To get started with Grafana development on Mac or Linux:

  1. Clone repository git clone https://github.com/grafana/grafana.git
  2. Install dependencies yarn install --immutable
  3. Start Frontend yarn start
  4. Start Backend make run

Developing and building Docker images is explained in the Grafana developer guide.

If you followed all the steps you should see a Pizza Oven advanced element in the list:

Pizza Oven element can be added to the Canvas panel.
Pizza Oven element can be added to the Canvas panel.

PostgreSQL with Timescale data source

For the demonstration, we used the PostgreSQL with Timescale database, which is the ultimate storage partner for Grafana. You can find an explanation in the tutorial:

Ultimate storage partner for Grafana.

The table orders to keep track of online and walk-in orders and the cooking progress:

CREATE TABLE orders (
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
created timestamp with time zone NOT NULL,
name text,
phone text,
description text,
online boolean,
price integer,
oven integer,
started timestamp with time zone NOT NULL
);

CREATE SEQUENCE seq_orders START 1;

insert into orders values(nextval('seq_orders'), now(), 'Mike', '123-456-789', 'Cheese Pizza', true, 19.99, 1, now());
insert into orders values(nextval('seq_orders'), now(), 'Ella', '132-461-782', 'Pepperoni Pizza', false, 24.99, 2, now());

The canvas panel is awesome

The canvas panel can be used for a variety of use cases, pizzeria included.

Configured canvas panel with custom pizza oven elements based on the data source data.
Configured canvas panel with custom pizza oven elements based on the data source data.