prometheus.md 38.8 KB
Newer Older
1 2
# Prometheus integration

3
> [Introduced][ce-8935] in GitLab 9.0.
4

Joshua Lambert's avatar
Joshua Lambert committed
5
GitLab offers powerful integration with [Prometheus] for monitoring key metrics of your apps, directly within GitLab.
6
Metrics for each environment are retrieved from Prometheus, and then displayed
7 8
within the GitLab interface.

9
![Environment Dashboard](img/prometheus_dashboard.png)
10

11
There are two ways to set up Prometheus integration, depending on where your apps are running:
12 13 14

- For deployments on Kubernetes, GitLab can automatically [deploy and manage Prometheus](#managed-prometheus-on-kubernetes).
- For other deployment targets, simply [specify the Prometheus server](#manual-configuration-of-prometheus).
15

16
Once enabled, GitLab will automatically detect metrics from known services in the [metric library](#monitoring-cicd-environments). You are also able to [add your own metrics](#adding-additional-metrics-premium) as well.
Joshua Lambert's avatar
Joshua Lambert committed
17 18 19 20

## Enabling Prometheus Integration

### Managed Prometheus on Kubernetes
21

22
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/28916) in GitLab 10.5.
23

Joshua Lambert's avatar
Joshua Lambert committed
24
GitLab can seamlessly deploy and manage Prometheus on a [connected Kubernetes cluster](../clusters/index.md), making monitoring of your apps easy.
25

Joshua Lambert's avatar
Joshua Lambert committed
26
#### Requirements
27

28 29
- A [connected Kubernetes cluster](../clusters/index.md)
- Helm Tiller [installed by GitLab](../clusters/index.md#installing-applications)
30

Joshua Lambert's avatar
Joshua Lambert committed
31
#### Getting started
32

33
Once you have a connected Kubernetes cluster with Helm installed, deploying a managed Prometheus is as easy as a single click.
34

35
1. Go to the **Operations > Kubernetes** page to view your connected clusters
36 37
1. Select the cluster you would like to deploy Prometheus to
1. Click the **Install** button to deploy Prometheus to the cluster
38

39
![Managed Prometheus Deploy](img/prometheus_deploy.png)
40

41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
#### Getting metrics to display on the Metrics Dashboard

After completing the steps above, you will also need deployments in order to view the
**Operations > Metrics** page. Setting up [Auto DevOps](../../../topics/autodevops/index.md)
will help you to quickly create a deployment:

1. Navigate to your project's **Operations > Kubernetes** page, and ensure that,
   in addition to "Prometheus" and "Helm Tiller", you also have "Runner" and "Ingress"
   installed. Once "Ingress" is installed, copy its endpoint.
1. Navigate to your project's **Settings > CI/CD** page. In the Auto DevOps section,
   select a deployment strategy and save your changes.
1. On the same page, in the Variables section, add a variable named `KUBE_INGRESS_BASE_DOMAIN`
   with the value of the Ingress endpoint you have copied in the previous step. Leave the type
   as "Variable".
1. Navigate to your project's **CI/CD > Pipelines** page, and run a pipeline on any branch.
1. When the pipeline has run successfully, graphs will be available on the **Operations > Metrics** page.

58 59 60 61 62 63 64 65 66 67 68
![Monitoring Dashboard](img/prometheus_monitoring_dashboard_v12_8.png)

#### Using the Metrics Dashboard

##### Select an environment

The **Environment** dropdown box above the dashboard displays the list of all [environments](#monitoring-cicd-environments).
It enables you to search as you type through all environments and select the one you're looking for.

![Monitoring Dashboard Environments](img/prometheus_dashboard_environments_v12_8.png)

Joshua Lambert's avatar
Joshua Lambert committed
69
#### About managed Prometheus deployments
70

71
Prometheus is deployed into the `gitlab-managed-apps` namespace, using the [official Helm chart](https://github.com/helm/charts/tree/master/stable/prometheus). Prometheus is only accessible within the cluster, with GitLab communicating through the [Kubernetes API](https://kubernetes.io/docs/concepts/overview/kubernetes-api/).
72

73
The Prometheus server will [automatically detect and monitor](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config) nodes, pods, and endpoints. To configure a resource to be monitored by Prometheus, simply set the following [Kubernetes annotations](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/):
74

75 76 77
- `prometheus.io/scrape` to `true` to enable monitoring of the resource.
- `prometheus.io/port` to define the port of the metrics endpoint.
- `prometheus.io/path` to define the path of the metrics endpoint. Defaults to `/metrics`.
78

Joshua Lambert's avatar
Joshua Lambert committed
79
CPU and Memory consumption is monitored, but requires [naming conventions](prometheus_library/kubernetes.html#specifying-the-environment) in order to determine the environment. If you are using [Auto DevOps](../../../topics/autodevops/), this is handled automatically.
80

Joshua Lambert's avatar
Joshua Lambert committed
81
The [NGINX Ingress](../clusters/index.md#installing-applications) that is deployed by GitLab to clusters, is automatically annotated for monitoring providing key response metrics: latency, throughput, and error rates.
82

Joshua Lambert's avatar
Joshua Lambert committed
83
### Manual configuration of Prometheus
84

Joshua Lambert's avatar
Joshua Lambert committed
85
#### Requirements
86

87
Integration with Prometheus requires the following:
88

89
1. GitLab 9.0 or higher
Marcia Ramos's avatar
Marcia Ramos committed
90
1. Prometheus must be configured to collect one of the [supported metrics](prometheus_library/index.md)
91 92
1. Each metric must be have a label to indicate the environment
1. GitLab must have network connectivity to the Prometheus server
93

Joshua Lambert's avatar
Joshua Lambert committed
94
#### Getting started
95

96
Installing and configuring Prometheus to monitor applications is fairly straight forward.
97

98
1. [Install Prometheus](https://prometheus.io/docs/prometheus/latest/installation/)
Marcia Ramos's avatar
Marcia Ramos committed
99
1. Set up one of the [supported monitoring targets](prometheus_library/index.md)
100
1. Configure the Prometheus server to [collect their metrics](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config)
101

Joshua Lambert's avatar
Joshua Lambert committed
102
#### Configuration in GitLab
103

104
The actual configuration of Prometheus integration within GitLab is very simple.
105
All you will need is the domain name or IP address of the Prometheus server you'd like
106
to integrate with.
107

108 109 110 111
1. Navigate to the [Integrations page](project_services.md#accessing-the-project-services).
1. Click the **Prometheus** service.
1. Provide the domain name or IP address of your server, for example `http://prometheus.example.com/` or `http://192.0.2.1/`.
1. Click **Save changes**.
112

113
![Configure Prometheus Service](img/prometheus_service_configuration.png)
114

115 116 117 118 119 120 121 122 123 124 125
#### Thanos configuration in GitLab

You can configure [Thanos](https://thanos.io/) as a drop-in replacement for Prometheus
with GitLab. You will need the domain name or IP address of the Thanos server you'd like
to integrate with.

1. Navigate to the [Integrations page](project_services.md#accessing-the-project-services).
1. Click the **Prometheus** service.
1. Provide the domain name or IP address of your server, for example `http://thanos.example.com/` or `http://192.0.2.1/`.
1. Click **Save changes**.

126 127
## Monitoring CI/CD Environments

128
Once configured, GitLab will attempt to retrieve performance metrics for any
129
environment which has had a successful deployment.
130

131
GitLab will automatically scan the Prometheus server for metrics from known servers like Kubernetes and NGINX, and attempt to identify individual environment. The supported metrics and scan process is detailed in our [Prometheus Metrics Library documentation](prometheus_library/index.md).
132

Joshua Lambert's avatar
Joshua Lambert committed
133
You can view the performance dashboard for an environment by [clicking on the monitoring button](../../../ci/environments.md#monitoring-environments).
134

135
### Adding additional metrics **(PREMIUM)**
136

137
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/3799) in [GitLab Premium](https://about.gitlab.com/pricing/) 10.6.
138

139
Custom metrics can be monitored by adding them on the monitoring dashboard page. Once saved, they will be displayed on the environment performance dashboard provided that either:
140

141
- A [connected Kubernetes cluster](../clusters/add_remove_clusters.md) with the environment scope of `*` is used and [Prometheus installed on the cluster](#enabling-prometheus-integration)
142
- Prometheus is [manually configured](#manual-configuration-of-prometheus).
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157

![Add New Metric](img/prometheus_add_metric.png)

A few fields are required:

- **Name**: Chart title
- **Type**: Type of metric. Metrics of the same type will be shown together.
- **Query**: Valid [PromQL query](https://prometheus.io/docs/prometheus/latest/querying/basics/).
- **Y-axis label**: Y axis title to display on the dashboard.
- **Unit label**: Query units, for example `req / sec`. Shown next to the value.

Multiple metrics can be displayed on the same chart if the fields **Name**, **Type**, and **Y-axis label** match between metrics. For example, a metric with **Name** `Requests Rate`, **Type** `Business`, and **Y-axis label** `rec / sec` would display on the same chart as a second metric with the same values. A **Legend label** is suggested if this feature used.

#### Query Variables

158
GitLab supports a limited set of [CI variables](../../../ci/variables/README.md) in the Prometheus query. This is particularly useful for identifying a specific environment, for example with `ci_environment_slug`. The supported variables are:
159

160 161 162 163 164 165 166 167 168
- `ci_environment_slug`
- `kube_namespace`
- `ci_project_name`
- `ci_project_namespace`
- `ci_project_path`
- `ci_environment_name`

NOTE: **Note:**
Variables for Prometheus queries must be lowercase.
169

170 171
There are 2 methods to specify a variable in a query or dashboard:

172
1. Variables can be specified using the [Liquid template format](https://help.shopify.com/en/themes/liquid/basics), for example `{{ci_environment_slug}}` ([added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20793) in GitLab 12.6).
173
1. You can also enclose it in quotation marks with curly braces with a leading percent, for example `"%{ci_environment_slug}"`. This method is deprecated  though and support will be [removed in the next major release](https://gitlab.com/gitlab-org/gitlab/issues/37990).
174

175
### Defining custom dashboards per project
176

177
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/59974) in GitLab 12.1.
178

179 180
By default, all projects include a GitLab-defined Prometheus dashboard, which
includes a few key metrics, but you can also define your own custom dashboards.
181

182 183 184
You may create a new file from scratch or duplicate a GitLab-defined Prometheus
dashboard.

185 186 187
NOTE: **Note:**
The custom metrics as defined below do not support alerts, unlike
[additional metrics](#adding-additional-metrics-premium).
188

189
#### Adding a new dashboard to your project
190

191 192 193 194
You can configure a custom dashboard by adding a new YAML file into your project's
`.gitlab/dashboards/` directory. In order for the dashboards to be displayed on
the project's **Operations > Metrics** page, the files must have a `.yml`
extension and should be present in the project's **default** branch.
195

196
For example:
197

198 199
1. Create `.gitlab/dashboards/prom_alerts.yml` under your repository's root
   directory with the following contents:
200

201 202 203 204 205 206 207 208 209 210 211
   ```yaml
   dashboard: 'Dashboard Title'
   panel_groups:
     - group: 'Group Title'
       panels:
         - type: area-chart
           title: "Chart Title"
           y_label: "Y-Axis"
           metrics:
             - id: metric_of_ages
               query_range: 'http_requests_total'
212
               label: "Instance: {{instance}}, method: {{method}}"
213 214 215 216 217 218 219
               unit: "count"
   ```

   The above sample dashboard would display a single area chart. Each file should
   define the layout of the dashboard and the Prometheus queries used to populate
   data.

220
1. Save the file, commit, and push to your repository. The file must be present in your **default** branch.
221 222 223 224 225 226 227
1. Navigate to your project's **Operations > Metrics** and choose the custom
   dashboard from the dropdown.

NOTE: **Note:**
Configuration files nested under subdirectories of `.gitlab/dashboards` are not
supported and will not be available in the UI.

228
#### Duplicating a GitLab-defined dashboard
229

230 231
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/37238) in GitLab 12.7.
> - From [GitLab 12.8 onwards](https://gitlab.com/gitlab-org/gitlab/issues/39505), custom metrics are also duplicated when you duplicate a dashboard.
232

233 234 235 236
You can save a complete copy of a GitLab defined dashboard along with all custom metrics added to it.
Resulting `.yml` file can be customized and adapted to your project.
You can decide to save the dashboard `.yml` file in the project's **default** branch or in a
new branch.
237

238
1. Click **Duplicate dashboard** in the dashboard dropdown.
239

Amy Qualls's avatar
Amy Qualls committed
240
   NOTE: **Note:**
241
   You can duplicate only GitLab-defined dashboards.
242

243
1. Enter the file name and other information, such as the new commit's message, and click **Duplicate**.
244

245 246
If you select your **default** branch, the new dashboard becomes immediately available.
If you select another branch, this branch should be merged to your **default** branch first.
247 248 249 250 251 252 253 254

#### Dashboard YAML properties

Dashboards have several components:

- Panel groups, which comprise of panels.
- Panels, which support one or more metrics.

255 256 257 258 259
The following tables outline the details of expected properties.

**Dashboard properties:**

| Property | Type | Required | Description |
260
| ------ | ------ | ------ | ------ |
261 262 263 264
| `dashboard` | string | yes | Heading for the dashboard. Only one dashboard should be defined per file. |
| `panel_groups` | array | yes | The panel groups which should be on the dashboard. |

**Panel group (`panel_groups`) properties:**
265

266
| Property | Type | Required | Description |
267 268
| ------ | ------ | ------ | ------ |
| `group` | string | required | Heading for the panel group. |
269
| `priority` | number | optional, defaults to order in file | Order to appear on the dashboard. Higher number means higher priority, which will be higher on the page. Numbers do not need to be consecutive. |
270 271
| `panels` | array | required | The panels which should be in the panel group. |

272 273 274
**Panel (`panels`) properties:**

| Property | Type | Required | Description |
275
| ------ | ------ | ------ | ------- |
276
| `type` | enum | no, defaults to `area-chart` | Specifies the chart type to use, can be: `area-chart`, `line-chart` or `anomaly-chart`. |
277 278 279
| `title` | string | yes | Heading for the panel. |
| `y_label` | string | no, but highly encouraged | Y-Axis label for the panel. |
| `weight` | number | no, defaults to order in file | Order to appear within the grouping. Lower number means higher priority, which will be higher on the page. Numbers do not need to be consecutive. |
280
| `metrics` | array | yes | The metrics which should be displayed in the panel. Any number of metrics can be displayed when `type` is `area-chart` or `line-chart`, whereas only 3 can be displayed when `type` is `anomaly-chart`. |
281 282 283 284

**Metrics (`metrics`) properties:**

| Property | Type | Required | Description |
285
| ------ | ------ | ------ | ------ |
286
| `id` | string | no | Used for associating dashboard metrics with database records. Must be unique across dashboard configuration files. Required for [alerting](#setting-up-alerts-for-prometheus-metrics-ultimate) (support not yet enabled, see [relevant issue](https://gitlab.com/gitlab-org/gitlab-foss/issues/60319)). |
287
| `unit` | string | yes | Defines the unit of the query's return data. |
288
| `label` | string | no, but highly encouraged | Defines the legend-label for the query. Should be unique within the panel's metrics. Can contain time series labels as interpolated variables. |
289 290
| `query` | string | yes if `query_range` is not defined | Defines the Prometheus query to be used to populate the chart/panel. If defined, the `query` endpoint of the [Prometheus API](https://prometheus.io/docs/prometheus/latest/querying/api/) will be utilized. |
| `query_range` | string | yes if `query` is not defined | Defines the Prometheus query to be used to populate the chart/panel. If defined, the `query_range` endpoint of the [Prometheus API](https://prometheus.io/docs/prometheus/latest/querying/api/) will be utilized. |
291

292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
##### Dynamic labels

Dynamic labels are useful when multiple time series are returned from a Prometheus query.

When a static label is used and a query returns multiple time series, then all the legend items will be labeled the same, which makes identifying each time series difficult:

```yaml
metrics:
  - id: metric_of_ages
    query_range: 'http_requests_total'
    label: "Time Series"
    unit: "count"
```

This may render a legend like this:

![repeated legend label chart](img/prometheus_dashboard_repeated_label.png)

For labels to be more explicit, using variables that reflect time series labels is a good practice. The variables will be replaced by the values of the time series labels when the legend is rendered:

```yaml
metrics:
  - id: metric_of_ages
    query_range: 'http_requests_total'
    label: "Instance: {{instance}}, method: {{method}}"
    unit: "count"
```

The resulting rendered legend will look like this:

![legend with label variables](img/prometheus_dashboard_label_variables.png)

There is also a shorthand value for dynamic dashboard labels that make use of only one time series label:

```yaml
metrics:
  - id: metric_of_ages
    query_range: 'http_requests_total'
    label: "Method"
    unit: "count"
```

334
This works by lowercasing the value of `label` and, if there are more words separated by spaces, replacing those spaces with an underscore (`_`). The transformed value is then checked against the labels of the time series returned by the Prometheus query. If a time series label is found that is equal to the transformed value, then the label value will be used and rendered in the legend like this:
335 336 337

![legend with label shorthand variable](img/prometheus_dashboard_label_variable_shorthand.png)

338 339 340 341
#### Panel types for dashboards

The below panel types are supported in monitoring dashboards.

342
##### Area or Line Chart
343

344
To add an area chart panel type to a dashboard, look at the following sample dashboard file:
345 346 347 348 349 350

```yaml
dashboard: 'Dashboard Title'
panel_groups:
  - group: 'Group Title'
    panels:
351 352
      - type: area-chart # or line-chart
        title: 'Area Chart Title'
353 354
        y_label: "Y-Axis"
        metrics:
355
          - id: area_http_requests_total
356
            query_range: 'http_requests_total'
357
            label: "Instance: {{instance}}, Method: {{method}}"
358 359 360 361 362 363 364 365
            unit: "count"
```

Note the following properties:

| Property | Type | Required | Description |
| ------ | ------ | ------ | ------ |
| type | string | no | Type of panel to be rendered. Optional for area panel types |
366
| query_range | string | required | For area panel types, you must use a [range query](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries) |
367

368 369 370
![area panel chart](img/prometheus_dashboard_area_panel_type_v12_8.png)

Starting in [version 12.8](https://gitlab.com/gitlab-org/gitlab/issues/202696), the y-axis values will automatically scale according to the data. Previously, it always started from 0.
371

372 373
##### Anomaly chart

374
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16530) in GitLab 12.5.
375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413

To add an anomaly chart panel type to a dashboard, add add a panel with *exactly* 3 metrics.

The first metric represents the current state, and the second and third metrics represent the upper and lower limit respectively:

```yaml
dashboard: 'Dashboard Title'
panel_groups:
  - group: 'Group Title'
    panels:
      - type: anomaly-chart
        title: "Chart Title"
        y_label: "Y-Axis"
        metrics:
          - id: anomaly_requests_normal
            query_range: 'http_requests_total'
            label: "# of Requests"
            unit: "count"
        metrics:
          - id: anomaly_requests_upper_limit
            query_range: 10000
            label: "Max # of requests"
            unit: "count"
        metrics:
          - id: anomaly_requests_lower_limit
            query_range: 2000
            label: "Min # of requests"
            unit: "count"
```

Note the following properties:

| Property | Type | Required | Description |
| ------ | ------ | ------ | ------ |
| type | string | required | Must be `anomaly-chart` for anomaly panel types |
| query_range | yes | required | For anomaly panel types, you must use a [range query](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries) in every metric. |

![anomaly panel type](img/prometheus_dashboard_anomaly_panel_type.png)

414
##### Column chart
415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440

To add a column panel type to a dashboard, look at the following sample dashboard file:

```yaml
dashboard: 'Dashboard Title'
panel_groups:
  - group: 'Group title'
    panels:
      - title: "Column"
        type: "column"
        metrics:
        - id: 1024_memory
          query: 'avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}) by (job)) without (job) / count(avg(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-([^c].*|c([^a]|a([^n]|n([^a]|a([^r]|r[^y])))).*|)-(.*)",namespace="%{kube_namespace}"}) without (job)) /1024/1024'
          unit: MB
          label: "Memory Usage"
```

Note the following properties:

| Property | Type | Required | Description |
| ------ | ------ | ------ | ------ |
| type | string | yes | Type of panel to be rendered. For column panel types, set to `column` |
| query_range | yes | yes | For column panel types, you must use a [range query](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries) |

![anomaly panel type](img/prometheus_dashboard_column_panel_type.png)

441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478
##### Stacked column

> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/30583) in GitLab 12.8.

To add a stacked column panel type to a dashboard, look at the following sample dashboard file:

```yaml
dashboard: 'Dashboard title'
priority: 1
panel_groups:
- group: 'Group Title'
  priority: 5
  panels:
  - type: 'stacked-column'
    title: "Stacked column"
    y_label: "y label"
    x_label: 'x label'
    metrics:
      - id: memory_1
        query_range: 'memory_query'
        label: "memory query 1"
        unit: "count"
        series_name: 'group 1'
      - id: memory_2
        query_range: 'memory_query_2'
        label: "memory query 2"
        unit: "count"
        series_name: 'group 2'

```

![stacked column panel type](img/prometheus_dashboard_stacked_column_panel_type_v12_8.png)

| Property | Type | Required | Description |
| ------ | ------ | ------ | ------ |
| `type` | string | yes | Type of panel to be rendered. For stacked column panel types, set to `stacked-column` |
| `query_range` | yes | yes | For stacked column panel types, you must use a [range query](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries) |

479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505
##### Single Stat

To add a single stat panel type to a dashboard, look at the following sample dashboard file:

```yaml
dashboard: 'Dashboard Title'
panel_groups:
  - group: 'Group Title'
    panels:
      - title: "Single Stat"
        type: "single-stat"
        metrics:
        - id: 10
          query: 'max(go_memstats_alloc_bytes{job="prometheus"})'
          unit: MB
          label: "Total"
```

Note the following properties:

| Property | Type | Required | Description |
| ------ | ------ | ------ | ------ |
| type | string | yes | Type of panel to be rendered. For single stat panel types, set to `single-stat` |
| query | string | yes | For single stat panel types, you must use an [instant query](https://prometheus.io/docs/prometheus/latest/querying/api/#instant-queries) |

![single stat panel type](img/prometheus_dashboard_single_stat_panel_type.png)

506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528
###### Percentile based results

> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/201946) in GitLab 12.8.

Query results sometimes need to be represented as a percentage value out of 100. You can use the `max_value` property at the root of the panel definition:

```yaml
dashboard: 'Dashboard Title'
panel_groups:
  - group: 'Group Title'
    panels:
      - title: "Single Stat"
        type: "single-stat"
        max_value: 100
        metrics:
        - id: 10
          query: 'max(go_memstats_alloc_bytes{job="prometheus"})'
          unit: '%'
          label: "Total"
```

For example, if you have a query value of `53.6`, adding `%` as the unit results in a single stat value of `53.6%`, but if the maximum expected value of the query is `120`, the value would be `44.6%`. Adding the `max_value` causes the correct percentage value to display.

529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557
##### Heatmaps

> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/30581) in GitLab 12.5.

To add a heatmap panel type to a dashboard, look at the following sample dashboard file:

```yaml
dashboard: 'Dashboard Title'
panel_groups:
  - group: 'Group Title'
    panels:
      - title: "Heatmap"
        type: "heatmap"
        metrics:
        - id: 10
          query: 'sum(rate(nginx_upstream_responses_total{upstream=~"%{kube_namespace}-%{ci_environment_slug}-.*"}[60m])) by (status_code)'
          unit: req/sec
          label: "Status code"
```

Note the following properties:

| Property | Type | Required | Description |
| ------ | ------ | ------ | ------ |
| type | string | yes | Type of panel to be rendered. For heatmap panel types, set to `heatmap` |
| query_range | yes | yes | For area panel types, you must use a [range query](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries) |

![heatmap panel type](img/heatmap_panel_type.png)

558 559 560 561 562 563 564
### View and edit the source file of a custom dashboard

> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/34779) in GitLab 12.5.

When viewing a custom dashboard of a project, you can view the original
`.yml` file by clicking on **Edit dashboard** button.

565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
### Chart Context Menu

From each of the panels in the dashboard, you can access the context menu by clicking the **{ellipsis_v}** **More actions** dropdown box above the upper right corner of the panel to take actions related to the chart's data.

![Context Menu](img/panel_context_menu_v12_8.png)

The options are:

- [View logs](#view-pod-logs-ultimate)
- [Download CSV](#downloading-data-as-csv)
- [Generate link to chart](#embedding-gitlab-managed-kubernetes-metrics)
- [Alerts](#setting-up-alerts-for-prometheus-metrics-ultimate)

### View Pod Logs **(ULTIMATE)**

> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/122013) in GitLab 12.8.

582 583 584
If you have [Pod Logs](../clusters/kubernetes_pod_logs.md) enabled,
you can navigate from the charts in the dashboard to view Pod Logs by
clicking on the context menu in the upper-right corner.
585 586 587

If you use the **Timeline zoom** function at the bottom of the chart, logs will narrow down to the time range you selected.

588 589
### Downloading data as CSV

590
Data from Prometheus charts on the metrics dashboard can be downloaded as CSV.
591

592
### Setting up alerts for Prometheus metrics **(ULTIMATE)**
593 594 595

#### Managed Prometheus instances

596
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/6590) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.2 for [custom metrics](#adding-additional-metrics-premium), and 11.3 for [library metrics](prometheus_library/metrics.md).
597 598 599

For managed Prometheus instances using auto configuration, alerts for metrics [can be configured](#adding-additional-metrics-premium) directly in the performance dashboard.

600 601 602 603 604 605
To set an alert:

1. Click on the ellipsis icon in the top right corner of the metric you want to create the alert for.
1. Choose **Alerts**
1. Set threshold and operator.
1. Click **Add** to save and activate the alert.
606 607 608 609 610 611 612

![Adding an alert](img/prometheus_alert.png)

To remove the alert, click back on the alert icon for the desired metric, and click **Delete**.

#### External Prometheus instances

613
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/9258) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.8.
614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631

For manually configured Prometheus servers, a notify endpoint is provided to use with Prometheus webhooks. If you have manual configuration enabled, an **Alerts** section is added to **Settings > Integrations > Prometheus**. This contains the *URL* and *Authorization Key*. The **Reset Key** button will invalidate the key and generate a new one.

![Prometheus service configuration of Alerts](img/prometheus_service_alerts.png)

To send GitLab alert notifications, copy the *URL* and *Authorization Key* into the [`webhook_configs`](https://prometheus.io/docs/alerting/configuration/#webhook_config) section of your Prometheus Alertmanager configuration:

```yaml
receivers:
  name: gitlab
  webhook_configs:
  - http_config:
      bearer_token: 9e1cbfcd546896a9ea8be557caf13a76
    send_resolved: true
    url: http://192.168.178.31:3001/root/manual_prometheus/prometheus/alerts/notify.json
  ...
```

632 633
In order for GitLab to associate your alerts with an [environment](../../../ci/environments.md), you need to configure a `gitlab_environment_name` label on the alerts you set up in Prometheus. The value of this should match the name of your Environment in GitLab.

634
### Taking action on incidents **(ULTIMATE)**
635

636 637
>- [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/4925) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 11.11.
>- [From GitLab Ultimate 12.5](https://gitlab.com/gitlab-org/gitlab/issues/13401), when GitLab receives a recovery alert, it will automatically close the associated issue.
638

639
Alerts can be used to trigger actions, like open an issue automatically (enabled by default since `12.1`). To configure the actions:
640 641 642 643 644 645 646

1. Navigate to your project's **Settings > Operations > Incidents**.
1. Enable the option to create issues.
1. Choose the [issue template](../description_templates.md) to create the issue from.
1. Optionally, select whether to send an email notification to the developers of the project.
1. Click **Save changes**.

647 648 649 650 651 652 653 654 655
Once enabled, an issue will be opened automatically when an alert is triggered which contains values extracted from [alert's payload](https://prometheus.io/docs/alerting/configuration/#webhook_config
):

- Issue author: `GitLab Alert Bot`
- Issue title: Extract from `annotations/title`, `annotations/summary` or `labels/alertname`
- Alert `Summary`: A list of properties
  - `starts_at`: Alert start time via `startsAt`
  - `full_query`: Alert query extracted from `generatorURL`
  - Optional list of attached annotations extracted from `annotations/*`
656
- Alert [GFM](../../markdown.md): GitLab Flavored Markdown from `annotations/gitlab_incident_markdown`
657

658
When GitLab receives a **Recovery Alert**, it will automatically close the associated issue. This action will be recorded as a system message on the issue indicated that it was closed automatically by the GitLab Alert bot.
659

660
To further customize the issue, you can add labels, mentions, or any other supported [quick action](../quick_actions.md) in the selected issue template, which will apply to all incidents. To limit quick actions or other information to only specific types of alerts, use the `annotations/gitlab_incident_markdown` field.
661

662
Since [version 12.2](https://gitlab.com/gitlab-org/gitlab-foss/issues/63373), GitLab will tag each incident issue with the `incident` label automatically. If the label does not yet exist, it will be created automatically as well.
663

664 665
If the metric exceeds the threshold of the alert for over 5 minutes, an email will be sent to all [Maintainers and Owners](../../permissions.md#project-members-permissions) of the project.

666
## Determining the performance impact of a merge
Fatih Acet's avatar
Fatih Acet committed
667

668
> - [Introduced][ce-10408] in GitLab 9.2.
669
> - GitLab 9.3 added the [numeric comparison](https://gitlab.com/gitlab-org/gitlab-foss/issues/27439) of the 30 minute averages.
Fatih Acet's avatar
Fatih Acet committed
670

Joshua Lambert's avatar
Joshua Lambert committed
671
Developers can view the performance impact of their changes within the merge
672 673 674 675 676 677 678 679 680 681 682
request workflow.

NOTE: **Note:**
Requires [Kubernetes](prometheus_library/kubernetes.md) metrics.

When a source branch has been deployed to an environment, a sparkline and
numeric comparison of the average memory consumption will appear. On the
sparkline, a dot indicates when the current changes were deployed, with up to 30 minutes of
performance data displayed before and after. The comparison shows the difference
between the 30 minute average before and after the deployment. This information
is updated after each commit has been deployed.
Fatih Acet's avatar
Fatih Acet committed
683

684
Once merged and the target branch has been redeployed, the metrics will switch
685
to show the new environments this revision has been deployed to.
686

687 688
Performance data will be available for the duration it is persisted on the
Prometheus server.
689 690

![Merge Request with Performance Impact](img/merge_request_performance.png)
Fatih Acet's avatar
Fatih Acet committed
691

692
## Embedding metric charts within GitLab Flavored Markdown
693

694 695
### Embedding GitLab-managed Kubernetes metrics

696 697
> [Introduced][ce-29691] in GitLab 12.2.

Sarah Yasonik's avatar
Sarah Yasonik committed
698
It is possible to display metrics charts within [GitLab Flavored Markdown](../../markdown.md#gitlab-flavored-markdown-gfm). The maximum number of embeds allowed in a GitLab Flavored Markdown field is 100.
699

700 701 702
This can be useful if you are sharing an application incident or performance
metrics to others and want to have relevant information directly available.

703 704 705
NOTE: **Note:**
Requires [Kubernetes](prometheus_library/kubernetes.md) metrics.

706 707 708 709 710 711 712
To display metric charts, include a link of the form `https://<root_url>/<project>/-/environments/<environment_id>/metrics`:

![Embedded Metrics Markdown](img/embedded_metrics_markdown_v12_8.png)

GitLab unfurls the link as an embedded metrics panel:

![Embedded Metrics Rendered](img/embedded_metrics_rendered_v12_8.png)
713

714
A single chart may also be embedded. You can generate a link to the chart via the dropdown located on the right side of the chart:
715 716 717

![Generate Link To Chart](img/generate_link_to_chart.png)

718 719 720 721 722 723 724 725 726 727 728 729
The following requirements must be met for the metric to unfurl:

- The `<environment_id>` must correspond to a real environment.
- Prometheus must be monitoring the environment.
- The GitLab instance must be configured to receive data from the environment.
- The user must be allowed access to the monitoring dashboard for the environment ([Reporter or higher](../../permissions.md)).
- The dashboard must have data within the last 8 hours.

 If all of the above are true, then the metric will unfurl as seen below:

![Embedded Metrics](img/embed_metrics.png)

730 731
### Embedding metrics in issue templates

732
It is also possible to embed either the default dashboard metrics or individual metrics in issue templates. For charts to render side-by-side, links to the entire metrics dashboard or individual metrics should be separated by either a comma or a space.
733 734 735

![Embedded Metrics in issue templates](img/embed_metrics_issue_template.png)

736 737 738
### Embedding Grafana charts

Grafana metrics can be embedded in [GitLab Flavored Markdown](../../markdown.md).
Tristan Read's avatar
Tristan Read committed
739

740 741
#### Embedding charts via Grafana Rendered Images

742
It is possible to embed live [Grafana](https://docs.gitlab.com/omnibus/settings/grafana.html) charts in issues, as a [direct linked rendered image](https://grafana.com/docs/grafana/latest/reference/share_panel/#direct-link-rendered-image).
Tristan Read's avatar
Tristan Read committed
743 744 745 746 747 748

The sharing dialog within Grafana provides the link, as highlighted below.

![Grafana Direct Linked Rendered Image](img/grafana_live_embed.png)

NOTE: **Note:**
749
For this embed to display correctly, the Grafana instance must be available to the target user, either as a public dashboard, or on the same network.
Tristan Read's avatar
Tristan Read committed
750

751
Copy the link and add an image tag as [inline HTML](../../markdown.md#inline-html) in your Markdown. You may tweak the query parameters as required. For instance, removing the `&from=` and `&to=` parameters will give you a live chart. Here is example markup for a live chart from GitLab's public dashboard:
Tristan Read's avatar
Tristan Read committed
752 753

```html
754
<img src="https://dashboards.gitlab.com/d/RZmbBr7mk/gitlab-triage?orgId=1&refresh=30s&var-env=gprd&var-environment=gprd&var-prometheus=prometheus-01-inf-gprd&var-prometheus_app=prometheus-app-01-inf-gprd&var-backend=All&var-type=All&var-stage=main&from=1580444107655&to=1580465707655"/>
Tristan Read's avatar
Tristan Read committed
755 756 757 758
```

This will render like so:

759
![Grafana dashboard embedded preview](img/grafana_embedded.png)
Tristan Read's avatar
Tristan Read committed
760

761 762 763 764
#### Embedding charts via integration with Grafana HTTP API

> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/31376) in GitLab 12.5.

765
Each project can support integration with one Grafana instance. This configuration allows a user to copy a link to a panel in Grafana, then paste it into a GitLab Markdown field. The chart will be rendered in the GitLab chart format.
766 767 768 769 770 771 772 773 774 775

Prerequisites for embedding from a Grafana instance:

1. The datasource must be a Prometheus instance.
1. The datasource must be proxyable, so the HTTP Access setting should be set to `Server`.

![HTTP Proxy Access](img/http_proxy_access_v12_5.png)

##### Setting up the Grafana integration

776
1. [Generate an Admin-level API Token in Grafana.](https://grafana.com/docs/grafana/latest/http_api/auth/#create-api-token)
777 778 779 780 781 782 783 784 785 786 787 788 789
1. In your GitLab project, navigate to **Settings > Operations > Grafana Authentication**.
1. To enable the integration, check the "Active" checkbox.
1. For "Grafana URL", enter the base URL of the Grafana instance.
1. For "API Token", enter the Admin API Token you just generated.
1. Click **Save Changes**.

##### Generating a link to a chart

1. In Grafana, navigate to the dashboard you wish to embed a panel from.
   ![Grafana Metric Panel](img/grafana_panel_v12_5.png)
1. In the upper-left corner of the page, select a specific value for each variable required for the queries in the chart.
   ![Select Query Variables](img/select_query_variables_v12_5.png)
1. In Grafana, click on a panel's title, then click **Share** to open the panel's sharing dialog to the **Link** tab.
790
1. If your Prometheus queries use Grafana's custom template variables, ensure that "Template variables" option is toggled to **On**. Of Grafana global template variables, only `$__interval`, `$__from`, and `$__to` are currently supported. Toggle **On** the "Current time range" option to specify the time range of the chart. Otherwise, the default range will be the last 8 hours.
791 792
   ![Grafana Sharing Dialog](img/grafana_sharing_dialog_v12_5.png)
1. Click **Copy** to copy the URL to the clipboard.
793
1. In GitLab, paste the URL into a Markdown field and save. The chart will take a few moments to render.
794 795
   ![GitLab Rendered Grafana Panel](img/rendered_grafana_embed_v12_5.png)

796 797
## Troubleshooting

Joshua Lambert's avatar
Joshua Lambert committed
798
If the "No data found" screen continues to appear, it could be due to:
799

800
- No successful deployments have occurred to this environment.
801 802
- Prometheus does not have performance data for this environment, or the metrics
  are not labeled correctly. To test this, connect to the Prometheus server and
803
  [run a query](prometheus_library/kubernetes.html#metrics-supported), replacing `$CI_ENVIRONMENT_SLUG`
804
  with the name of your environment.
805
- You may need to re-add the GitLab predefined common metrics. This can be done by running the [import common metrics rake task](../../../administration/raketasks/maintenance.md#import-common-metrics).
806

807
[autodeploy]: ../../../topics/autodevops/index.md#auto-deploy
808
[kubernetes]: https://kubernetes.io
809
[kube]: ./kubernetes.md
810
[prometheus-k8s-sd]: https://prometheus.io/docs/operating/configuration/#<kubernetes_sd_config>
811 812
[prometheus]: https://prometheus.io
[gitlab-prometheus-k8s-monitor]: ../../../administration/monitoring/prometheus/index.md#configuring-prometheus-to-monitor-kubernetes
813 814 815
[prometheus-docker-image]: https://hub.docker.com/r/prom/prometheus/
[prometheus-yml]:samples/prometheus.yml
[gitlab.com-ip-range]: https://gitlab.com/gitlab-com/infrastructure/issues/434
816
[ci-environment-slug]: ../../../ci/variables/#predefined-environment-variables
817 818 819
[ce-8935]: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/8935
[ce-10408]: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10408
[ce-29691]: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/29691
820
[promgldocs]: ../../../administration/monitoring/prometheus/index.md