Building Dashboards and Configuring Alerts in Grafana: A Practical Guide

Grafana Overview

Grafana is an open-source visualization and monitoring platform that enables users to create interactive dashboards and analyze real-time data. The platform supports multiple data sources including Prometheus, Graphite, InfluxDB, Elasticsearch, and MySQL, allowing data to be aggregated and displayed through customizable panels and charts.

Beyond its integration with Prometheus for metrics collection, Grafana provides standalone alerting capabilities. Users can define custom alerting rules based on query results and receive notifications through various channels including email, webhooks, and instant messaging platforms.

Dashboard Creation Fundamentals

Dashboard creation in Grafana involves three essential components:

  1. Data Source Configuration - Establishing connection to your database
  2. Panel Creation - Building individual visualizations
  3. Dashboard Assembly - Combining panels into a cohesive view

This guide demonstrates dashboard creation using MySQL as the data source.

Data Source Setup

Navigate to Configuration → Data Sources → Add New Data Source, then select MySQL and configure the connection parameters including host, database name, credentials, and SSL settings.

Panel and Dashboard Creation

Create a new dashboard through the Dashboards menu. Each dashboard contains multiple panels, and each panel executes a query against the configured data source.

For demonstration purposes, this guide uses a student records table with the following structure:

CREATE TABLE student (
    id INT AUTO_INCREMENT PRIMARY KEY,
    birthday_time DATETIME,
    name VARCHAR(50),
    class_id INT,
    score INT
);

INSERT INTO student (birthday_time, name, class_id, score) VALUES 
('2015-01-01', 'Alice', 1, 80),
('2015-02-02', 'Bob', 2, 75),
('2015-03-03', 'Charlie', 1, 90),
('2015-04-04', 'David', 3, 85),
('2015-05-05', 'Eve', 2, 78),
('2015-06-06', 'Frank', 1, 92),
('2015-07-07', 'Grace', 3, 87),
('2015-08-08', 'Henry', 2, 79),
('2015-09-09', 'Iris', 1, 88),
('2015-10-10', 'Jack', 3, 82),
('2015-11-11', 'Kate', 2, 91),
('2015-12-12', 'Leo', 1, 76);

Visualization Types

Table View

The simplest visualization displays raw query results in table format:

SELECT * FROM student;

Bar Chart

Group data by categorical values using aggregation functions:

SELECT
  UNIX_TIMESTAMP(birthday_time) AS time_sec,
  SUM(score) AS value,
  CONCAT(class_id, ' Class') AS metric
FROM student
GROUP BY class_id
ORDER BY birthday_time ASC

Time Series Line Chart

For trend analysis over time, use Grafana's built-in time macros:

  • $__timeGroup(column, interval) - Groups timestamp data into specified intervals
  • $__timeFilter(column) - Applies the dashboard's selected time range

Query using time-grouped aggregation:

SELECT
  $__timeGroup(birthday_time, '1M') AS time_sec,
  COUNT(id) AS count
FROM student
WHERE $__timeFilter(birthday_time)
GROUP BY time_sec

Multi-Series Line Chart

Add multiple series by including grouped columns in the SELECT statement:

SELECT
  $__timeGroup(birthday_time, '1M') AS time_sec,
  COUNT(id) AS total,
  SUM(class_id = 1) AS class_one
FROM student
WHERE $__timeFilter(birthday_time)
GROUP BY time_sec

Filtered Queries with Variables

Create dashboard variables to enable user-driven filtering. Add a variable through Dashboard Settings → Variables:

  • Variable name: classFilter
  • Query: SELECT class_id FROM student GROUP BY class_id
  • Multi-value: enabled

Apply the variable in queries:

SELECT
  $__timeGroup(birthday_time, '1M') AS time_sec,
  COUNT(id) AS count
FROM student
WHERE $__timeFilter(birthday_time)
  AND class_id = $classFilter
GROUP BY time_sec

For multiple selected values, use the IN operator:

SELECT
  $__timeGroup(birthday_time, '1M') AS time_sec,
  COUNT(id) AS count
FROM student
WHERE $__timeFilter(birthday_time)
  AND class_id IN ($classFilter)
GROUP BY time_sec

Dynamic Panel Creation

Use the Transform feature to automatically generate separate panels for each group. Configure the "Group by" transform to partition data based on the class dimension:

SELECT
  $__timeGroup(birthday_time, '1M') AS time_sec,
  CAST(class_id AS CHAR) AS class,
  COUNT(class_id) AS count
FROM student
WHERE $__timeFilter(birthday_time)
  AND class_id IN ($classFilter)
GROUP BY class_id, time_sec

Enable "Panel repeat" in the panel options to iterate through variable values, automatically creating separate panels for each class.

Alert Configuration

Grafana alerting requires three configuration components:

  1. Contact Point - Notification destination
  2. Alert Rule - Condition that triggers evaluation
  3. Notification Policy - Routing rules linking contacts to alerts

Contact Point Configuration

Configure notification channels based on your messaging platform:

DingTalk/Enterprise WeChat

Select the appropriate contact point type from the dropdown and provide the webhook URL.

Feishu ( Lark )

Feishu does not have native Grafana integration. Create an intermediary service that:

  1. Receives Grafana webhook payloads
  2. Transforms data into Feishu's message format
  3. forwards to Feishu webhook endpoint

Example intermediary service:

@RestController
@Slf4j
public class AlertForwarder {

    @Value("${feishu.webhook-url}")
    private String webHookUrl;

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/alert/webhook")
    public void receive(@RequestBody String payload) {
        Map<String, Object> message = buildMessage(payload);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        restTemplate.postForEntity(webHookUrl, 
            new HttpEntity<>(message, headers), Void.class);
    }

    private Map<String, Object> buildMessage(String body) {
        JSONObject json = JSON.parseObject(body);
        String status = json.getString("status");
        String title = json.getString("title");
        String description = 
            json.getJSONObject("commonAnnotations").getString("description");
        
        String content = String.format(
            "Status: %s\nTitle: %s\nDescription: %s\nTimestamp: %s",
            "firing".equals(status) ? "Alert Triggered" : "Alert Resolved",
            title, description, LocalDateTime.now()
        );
        
        Map<String, Object> message = new HashMap<>();
        message.put("msg_type", "text");
        Map<String, Object> textContent = new HashMap<>();
        textContent.put("text", content);
        message.put("content", textContent);
        return message;
    }
}

Configure the contact point with your intermediary service endpoint.

Alert Rule Creation

Create alert rules through Alerting → Alert Rules, or directly from panel editing interfaces:

  1. Select the target panel
  2. Enable "Alert" toggle in panel settings
  3. Define the query and evaluation condition
  4. Set evaluation frequency and pending period
  5. Configure alert metadata (title, description, tags)

Example rule for monitoring student scores:

SELECT
  COUNT(1) AS alert_count
FROM student
WHERE score < 90

Configure the alert condition:

  • Condition: alert_count > 0
  • Evaluate every: 1 minute
  • For: 5 minutes

Notification Policy Configuration

Associate contact points with alert rules through Notification Policies:

  1. Navigate to Alerting → Notification Policies
  2. Create or modify the default policy
  3. Select the contact point for matched alerts
  4. Configure matching rules using label selectors
  5. Set grouping and timing options

Silent Policy Configuration

Configure mute timings to suppress notifications during maintenance windows or off-hours.

Additional Time Macros

Grafana provides additional time-related macros:

  • $__timeFrom() - Dashboard start time
  • $__timeTo() - Dashboard end time
  • $__timeGroupAlias() - Grouped alias for legend labels
  • $__unixEpochGroup() - Unix timestamp grouping

References

  • Grafana MySQL Data Source Documentation
  • Grafana Alerting Configuration
  • Grafana HTTP API Documentation
  • Grafana Variable Documentation
  • Time Series Visualization Best Practices

Tags: Grafana Dashboard Alerting MySQL monitoring

Posted on Thu, 11 Jun 2026 18:20:58 +0000 by Terminator