Skip to main content

Check out Port for yourselfย 

Grafana

In this example you are going to create a webhook integration between Grafana and Port, which will ingest alert entities.

Port configurationโ€‹

Create the following blueprint definition:

Alert blueprint
{
"identifier": "grafanaAlert",
"description": "This blueprint represents a Grafana alert in your software catalog",
"title": "Grafana Alert",
"icon": "Grafana",
"schema": {
"properties": {
"status": {
"title": "Status",
"description": "Current status of the alert, firing or resolved",
"type": "string",
"enum": ["firing", "resolved"],
"enumColors": {
"firing": "red",
"resolved": "green"
}
},
"labels": {
"title": "Labels",
"type": "object",
"description": "Labels that are part of this alert, map of string keys to string values"
},
"description": {
"title": "Description",
"type": "string"
},
"createdAt": {
"title": "Created at",
"description": "Start time of the alert",
"type": "string",
"format": "date-time"
},
"resolvedAt": {
"title": "Resolved At",
"type": "string",
"description": "End time of the alert",
"format": "date-time"
},
"values": {
"title": "Values",
"type": "object",
"description": "Values that triggered the current status"
},
"generatorURL": {
"title": "Generator URL",
"type": "string",
"description": "URL of the alert rule in the Grafana UI",
"format": "url"
},
"fingerprint": {
"title": "Fingerprint",
"description": "The labels fingerprint, alarms with the same labels will have the same fingerprint",
"type": "string"
},
"silenceURL": {
"title": "Silence URL",
"description": "URL to silence the alert rule in the Grafana UI",
"type": "string",
"format": "url"
},
"summary": {
"title": "Summary",
"type": "string"
},
"runbookURL": {
"title": "Runbook URL",
"type": "string",
"description": "URL of the runbook in the Grafana UI",
"format": "url"
}
},
"required": []
},
"mirrorProperties": {},
"calculationProperties": {},
"relations": {}
}

Create the following webhook configuration using Port's UI

Alert webhook configuration
  1. Basic details tab - fill the following details:

    1. Title : Grafana Alert Mapper;
    2. Identifier : grafana_alert_mapper;
    3. Description : A webhook configuration to map Grafana alerts to Port;
    4. Icon : Grafana;
  2. Integration configuration tab - fill the following JQ mapping:

    [
    {
    "blueprint": "grafanaAlert",
    "filter": "true",
    "itemsToParse": ".body.alerts",
    "entity": {
    "identifier": ".item.labels.alertname + \"-\" + .item.fingerprint | gsub(\"[^a-zA-Z0-9@_.:/=-]\"; \"-\") | tostring",
    "title": ".item.labels.alertname",
    "properties": {
    "status": ".item.status",
    "labels": ".item.labels",
    "description": ".item.annotations.description",
    "summary": ".item.annotations.summary",
    "runbookURL": ".item.annotations.runbook_url",
    "createdAt": ".item.startsAt",
    "resolvedAt": ".item.endsAt",
    "values": ".item.values",
    "generatorURL": "if .item.generatorURL != \"\" then .item.generatorURL else null end",
    "fingerprint": ".item.fingerprint",
    "silenceURL": "if .item.silenceURL != \"\" then .item.silenceURL else null end"
    }
    }
    }
    ]
  3. Click Save at the bottom of the page.

Create a webhook in Grafanaโ€‹

  1. Go to Alerting in your Grafana account;
  2. Under Contact points click Add contact point;
  3. Input the following details:
    1. Name - use a meaningful name such as Port Webhook;
    2. Integration - select Webhook from the list;
    3. URL - enter the value of the url key you received after creating the webhook configuration;
  4. Click Save contact point to save the contact;
  5. Go to Notification policies and add the Port Webhook contact point to your Default policy and be notified of any alert in Grafana;
  6. You can optionally add the contact point to an existing notification policy or create a new policy depending on your use case;
  7. Click Save policy.

Done! any change that happens to your alerts in Grafana will trigger a webhook event to the webhook URL provided by Port. Port will parse the events according to the mapping and update the catalog entities accordingly.

Let's Test Itโ€‹

This section includes a sample response data from Grafana. In addition, it includes the entity created from the resync event based on the Ocean configuration provided in the previous section.

Payloadโ€‹

Here is an example of the payload structure from Grafana:

Webhook response data (Click to expand)
{
"status": "firing",
"labels": {
"alertname": "High memory usage",
"team": "blue",
"zone": "us-1"
},
"annotations": {
"description": "The system has high memory usage",
"runbook_url": "https://myrunbook.com/runbook/1234",
"summary": "This alert was triggered for zone us-1"
},
"startsAt": "2021-10-12T09:51:03.157076+02:00",
"endsAt": "0001-01-01T00:00:00Z",
"generatorURL": "https://play.grafana.org/alerting/1afz29v7z/edit",
"fingerprint": "c6eadffa33fcdf37",
"silenceURL": "https://play.grafana.org/alerting/silence/new?alertmanager=grafana&matchers=alertname%3DT2%2Cteam%3Dblue%2Czone%3Dus-1",
"dashboardURL": "",
"panelURL": "",
"values": {
"B": 44.23943737541908,
"C": 1
}
}

Mapping Resultโ€‹

The combination of the sample payload and the Ocean configuration generates the following Port entity:

Alert entity in Port (Click to expand)
{
"identifier": "High memory usage - c6eadffa33fcdf37",
"title": "High memory usage",
"blueprint": "grafanaAlert",
"team": [],
"icon": "Grafana",
"properties": {
"status": "firing",
"labels": {
"alertname": "High memory usage",
"team": "blue",
"zone": "us-1"
},
"description": "The system has high memory usage",
"summary": "This alert was triggered for zone us-1",
"runbookURL": "https://myrunbook.com/runbook/1234",
"createdAt": "2021-10-12T09:51:03.157076+02:00",
"resolvedAt": "0001-01-01T00:00:00+00:00",
"values": {
"B": 44.23943737541908,
"C": 1
},
"generatorURL": "https://play.grafana.org/alerting/1afz29v7z/edit",
"fingerprint": "c6eadffa33fcdf37",
"silenceURL": "https://play.grafana.org/alerting/silence/new?alertmanager=grafana&matchers=alertname%3DT2%2Cteam%3Dblue%2Czone%3Dus-1"
},
"relations": {},
"createdAt": "2024-2-6T09:30:57.924Z",
"createdBy": "hBx3VFZjqgLPEoQLp7POx5XaoB0cgsxW",
"updatedAt": "2024-2-6T11:49:20.881Z",
"updatedBy": "hBx3VFZjqgLPEoQLp7POx5XaoB0cgsxW"
}