Skip to content

Commit

Permalink
Fix email alert examples, closes #2187 (#2188)
Browse files Browse the repository at this point in the history
  • Loading branch information
sanderson committed Feb 18, 2021
1 parent 69daa19 commit 89d354a
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 262 deletions.
223 changes: 1 addition & 222 deletions content/influxdb/cloud/monitor-alert/send-email.md
Expand Up @@ -11,225 +11,4 @@ related:
- /influxdb/cloud/monitor-alert/checks/
---

Send an alert email using a third party service, such as [SendGrid](https://sendgrid.com/), [Amazon Simple Email Service (SES)](https://aws.amazon.com/ses/), [Mailjet](https://www.mailjet.com/), or [Mailgun](https://www.mailgun.com/). To send an alert email, complete the following steps:

1. [Create a check](/influxdb/cloud/monitor-alert/checks/create/#create-a-check-in-the-influxdb-ui) to identify the data to monitor and the status to alert on.
2. Set up your preferred email service (sign up, retrieve API credentials, and send test email):
- **SendGrid**: See [Getting Started With the SendGrid API](https://sendgrid.com/docs/API_Reference/api_getting_started.html)
- **AWS Simple Email Service (SES)**: See [Using the Amazon SES API](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/send-email.html). Your AWS SES request, including the `url` (endpoint), authentication, and the structure of the request may vary. For more information, see [Amazon SES API requests](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/using-ses-api-requests.html) and [Authenticating requests to the Amazon SES API](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/using-ses-api-authentication.html).
- **Mailjet**: See [Getting Started with Mailjet](https://dev.mailjet.com/email/guides/getting-started/)
- **Mailgun**: See [Mailgun Signup](https://signup.mailgun.com/new/signup)
3. [Create an alert email task](#create-an-alert-email-task) to call your email service and send an alert email.

{{% note %}}
In the procedure below, we use the **Task** page in the InfluxDB UI (user interface) to create a task. Explore other ways to [create a task](/influxdb/cloud/process-data/manage-tasks/create-task/).
{{% /note %}}

### Create an alert email task

1. In the InfluxDB UI, select **Tasks** in the navigation menu on the left.

{{< nav-icon "tasks" >}}

2. Click **{{< icon "plus" >}} Create Task**, and then select **New Task**.
3. In the **Name** field, enter a descriptive name, for example, **Send alert email**, and then enter how often to run the task in the **Every** field, for example, `10m`. For more detail, such as using cron syntax or including an offset, see [Task configuration options](/influxdb/cloud/process-data/task-options/).

4. In the right panel, enter the following detail in your **task script** (see [examples below](#examples)):
- Import the [Flux HTTP package](/influxdb/cloud/reference/flux/stdlib/http/).
- (Optional) Store your API key as a secret for reuse. First, [add your API key as a secret](/influxdb/cloud/security/secrets/manage-secrets/add/), and then import the [Flux InfluxDB Secrets package](/influxdb/cloud/reference/flux/stdlib/secrets/).
- Query the `statuses` measurement in the `_monitoring` bucket to retrieve all statuses generated by your check.
- Set the time range to monitor; use the same interval that the task is scheduled to run. For example, `range (start: -task.every)`.
- Set the `_level` to alert on, for example, `crit`, `warn`, `info`, or `ok`.
- Use the `map()` function to evaluate the criteria to send an alert using `http.post()`.
- Specify your email service `url` (endpoint), include applicable request `headers`, and verify your request `data` format follows the format specified for your email service.

#### Examples

{{< tabs-wrapper >}}
{{% tabs %}}
[SendGrid](#)
[AWS SES](#)
[Mailjet](#)
[Mailgun](#)
{{% /tabs %}}

<!-------------------------------- BEGIN SendGrid -------------------------------->
{{% tab-content %}}

The example below uses the SendGrid API to send an alert email when more than 3 critical statuses occur since the previous task run.

```js
import "http"

// Import the Secrets package if you store your API key as a secret.
// For detail on how to do this, see Step 4 above.
import "influxdata/influxdb/secrets"

// Retrieve the secret if applicable. Otherwise, skip this line
// and add the API key as the Bearer token in the Authorization header.
SENDGRID_APIKEY = secrets.get(key: "SENDGRID_APIKEY")

numberOfCrits = from(bucket: "_monitoring")
|> range(start: -task.every)
|> filter(fn: (r) => r.measurement == "statuses" and r.level == "crit")
|> count()

numberOfCrits
|> map(fn: (r) => (if r._value > 3 then {
r with _value: http.post(
url: "https://api.sendgrid.com/v3/mail/send",
headers: {"Content-Type": "application/json", Authorization: "Bearer ${SENDGRID_APIKEY}"},
data: bytes(v: "{
\"personalizations\": [{
\"to\": [{
\"email\": \”jane.doe@example.com\"}],
\"subject\": \”InfluxData critical alert\"
}],
\"from\": {\"email\": \"john.doe@example.com\"},
\"content\": [{
\"type\": \"text/plain\",
\"value\": \”Example alert text\"
}]
}\""))} else {r with _value: 0}))
```

{{% /tab-content %}}

<!-------------------------------- BEGIN AWS SES -------------------------------->
{{% tab-content %}}

The example below uses the AWS SES API v2 to send an alert email when more than 3 critical statuses occur since the last task run.

{{% note %}}
Your AWS SES request, including the `url` (endpoint), authentication, and the structure of the request may vary. For more information, see [Amazon SES API requests](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/using-ses-api-requests.html) and [Authenticating requests to the Amazon SES API](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/using-ses-api-authentication.html). We recommend signing your AWS API requests using the [Signature Version 4 signing process](https://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html).
{{% /note %}}

```js
import "http"

// Import the Secrets package if you store your API credentials as secrets.
// For detail on how to do this, see Step 4 above.
import "influxdata/influxdb/secrets"

// Retrieve the secrets if applicable. Otherwise, skip this line
// and add the API key as the Bearer token in the Authorization header.
AWS_AUTH_ALGORITHM = secrets.get(key: "AWS_AUTH_ALGORITHM")
AWS_CREDENTIAL = secrets.get(key: "AWS_CREDENTIAL")
AWS_SIGNED_HEADERS = secrets.get(key: "AWS_SIGNED_HEADERS")
AWS_CALCULATED_SIGNATURE = secrets.get(key: "AWS_CALCULATED_SIGNATURE")

numberOfCrits = from(bucket: "_monitoring")
|> range(start: -task.every)
|> filter(fn: (r) => (r.measurement == "statuses" and r._level == "crit")
|> count()

numberOfCrits
|> map(fn: (r) => (if r._value > 3 then {
r with _value: http.post(
url: "https://email.your-aws-region.amazonaws.com/sendemail/v2/email/outbound-emails",
headers: {"Content-Type": "application/json", Authorization: "Bearer ${AWS_AUTH_ALGORITHM}${AWS_CREDENTIAL}${AWS_SIGNED_HEADERS}${AWS_CALCULATED_SIGNATURE}"},
data: bytes(v: "{
\"personalizations\": [{
\"to\": [{
\"email\": \”jane.doe@example.com\"}],
\"subject\": \”InfluxData critical alert\"
}],
\"from\": {\"email\": \"john.doe@example.com\"},
\"content\": [{
\"type\": \"text/plain\",
\"value\": \”Example alert text\"
}]
}\""))} else {r with _value: 0}))
```
For details on the request syntax, see [SendEmail API v2 reference](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html).
{{% /tab-content %}}
<!-------------------------------- BEGIN Mailjet ------------------------------->
{{% tab-content %}}
The example below uses the Mailjet Send API to send an alert email when more than 3 critical statuses occur since the last task run.
{{% note %}}
To view your Mailjet API credentials, sign in to Mailjet and open the [API Key Management page](https://app.mailjet.com/account/api_keys).
{{% /note %}}
```js
import "http"

// Import the Secrets package if you store your API keys as secrets.
// For detail on how to do this, see Step 4 above.
import "influxdata/influxdb/secrets"

// Retrieve the secrets if applicable. Otherwise, skip this line
// and add the API keys as Basic credentials in the Authorization header.
MAILJET_APIKEY = secrets.get(key: "MAILJET_APIKEY")
MAILJET_SECRET_APIKEY = secrets.get(key: "MAILJET_SECRET_APIKEY")

numberOfCrits = from(bucket: "_monitoring")
|> range(start: -task.every)
|> filter(fn: (r) => (r.measurement == "statuses" and "r.level" == "crit")
|> count()

numberOfCrits
|> map(fn: (r) => (if r._value > 3 then {
r with _value: http.post(
url: "https://api.mailjet.com/v3.1/send",
headers: {"Content-type": "application/json", Authorization: "Basic ${MAILJET_APIKEY}:${MAILJET_SECRET_APIKEY}"},
data: bytes(v: "{
\"Messages\": [{
\"From\": {\"Email\": \”jane.doe@example.com\"},
\"To\": [{\"Email\": \"john.doe@example.com\"]},
\"Subject\": \”InfluxData critical alert\",
\"TextPart\": \”Example alert text\"
\"HTMLPart\": `"<h3>Hello, to review critical alerts, review your <a href=\"https://www.example-dashboard.com/\">Critical Alert Dashboard</a></h3>}]}'
}\""))} else {r with _value: 0}))
```
{{% /tab-content %}}
<!-------------------------------- BEGIN Mailgun ---------------------------->
{{% tab-content %}}
The example below uses the Mailgun API to send an alert email when more than 3 critical statuses occur since the last task run.
{{% note %}}
To view your Mailgun API keys, sign in to Mailjet and open [Account Security - API security](https://app.mailgun.com/app/account/security/api_keys). Mailgun requires that a domain be specified via Mailgun. A domain is automatically created for you when you first set up your account. You must include this domain in your `url` endpoint (for example, `https://api.mailgun.net/v3/YOUR_DOMAIN` or `https://api.eu.mailgun.net/v3/YOUR_DOMAIN`. If you're using a free version of Mailgun, you can set up a maximum of five authorized recipients (to receive email alerts) for your domain. To view your Mailgun domains, sign in to Mailgun and view the [Domains page](https://app.mailgun.com/app/sending/domains).
{{% /note %}}

```js
import "http"
// Import the Secrets package if you store your API key as a secret.
// For detail on how to do this, see Step 4 above.
import "influxdata/influxdb/secrets"
// Retrieve the secret if applicable. Otherwise, skip this line
// and add the API key as the Bearer token in the Authorization header.
MAILGUN_APIKEY = secrets.get(key: "MAILGUN_APIKEY")
numberOfCrits = from(bucket: "_monitoring")
|> range(start: -task.every)
|> filter(fn: (r) => (r["_measurement"] == "statuses"))
|> filter(fn: (r) => (r["_level"] == "crit"))
|> count()
numberOfCrits
|> map(fn: (r) =>
(if r._value > 1 then {r with _value: http.post(
url: "https://api.mailgun.net/v3/YOUR_DOMAIN/messages",
headers: {"Content-type": "application/json", Authorization: "Basic api:${MAILGUN_APIKEY}"},
data: bytes(v: "{
\"from\": \"Username <mailgun@YOUR_DOMAIN_NAME>\",
\"to\"=\"YOU@YOUR_DOMAIN_NAME\",
\"to\"=\"email@example.com\",
\"subject\"=\"Critical InfluxData alert\",
\"text\"=\"You have critical alerts to review\"
}\""))} else {r with _value: 0}))
```

{{% /tab-content %}}

{{< /tabs-wrapper >}}
{{< duplicate-oss >}}
120 changes: 80 additions & 40 deletions content/influxdb/v2.0/monitor-alert/send-email.md
Expand Up @@ -43,6 +43,12 @@ Send an alert email using a third party service, such as [SendGrid](https://send
- Use the `map()` function to evaluate the criteria to send an alert using `http.post()`.
- Specify your email service `url` (endpoint), include applicable request `headers`, and verify your request `data` format follows the format specified for your email service.

{{% note %}}
#### Escape double quotes in your request body
To successfully byte-encode request bodies (`data`) in the `http.post()` function,
escape all double-quote characters with a backslash (`\"`).
{{% /note %}}

#### Examples

{{< tabs-wrapper >}}
Expand Down Expand Up @@ -78,19 +84,31 @@ numberOfCrits
|> map(fn: (r) => (if r._value > 3 then {
r with _value: http.post(
url: "https://api.sendgrid.com/v3/mail/send",
headers: {"Content-Type": "application/json", Authorization: "Bearer ${SENDGRID_APIKEY}"},
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer ${SENDGRID_APIKEY}"
},
data: bytes(v: "{
\"personalizations\": [{
\"to\": [{
\"email\": \”jane.doe@example.com\"}],
\"subject\": \”InfluxData critical alert\"
}],
\"from\": {\"email\": \"john.doe@example.com\"},
\"content\": [{
\"personalizations\": [
{
\"to\": [
{
\"email\": \"jane.doe@example.com\"
}
]
}
],
\"from\": {
\"email\": \"john.doe@example.com\"
},
\"subject\": \"InfluxDB critical alert\",
\"content\": [
{
\"type\": \"text/plain\",
\"value\": \”Example alert text\"
}]
}\""))} else {r with _value: 0}))
\"value\": \"There have been ${string(v: r._value)} critical statuses.\"
}
]
}"))} else {r with _value: 0}))
```

{{% /tab-content %}}
Expand Down Expand Up @@ -120,26 +138,38 @@ AWS_CALCULATED_SIGNATURE = secrets.get(key: "AWS_CALCULATED_SIGNATURE")

numberOfCrits = from(bucket: "_monitoring")
|> range(start: -task.every)
|> filter(fn: (r) => (r.measurement == "statuses" and r._level == "crit")
|> filter(fn: (r) => r.measurement == "statuses" and r._level == "crit")
|> count()

numberOfCrits
|> map(fn: (r) => (if r._value > 3 then {
r with _value: http.post(
url: "https://email.your-aws-region.amazonaws.com/sendemail/v2/email/outbound-emails",
headers: {"Content-Type": "application/json", Authorization: "Bearer ${AWS_AUTH_ALGORITHM}${AWS_CREDENTIAL}${AWS_SIGNED_HEADERS}${AWS_CALCULATED_SIGNATURE}"},
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer ${AWS_AUTH_ALGORITHM}${AWS_CREDENTIAL}${AWS_SIGNED_HEADERS}${AWS_CALCULATED_SIGNATURE}"
},
data: bytes(v: "{
\"personalizations\": [{
\"to\": [{
\"email\": \”jane.doe@example.com\"}],
\"subject\": \”InfluxData critical alert\"
}],
\"from\": {\"email\": \"john.doe@example.com\"},
\"content\": [{
\"type\": \"text/plain\",
\"value\": \”Example alert text\"
}]
}\""))} else {r with _value: 0}))
\"Content\": {
\"Simple\": {
\"Body\": {
\"Text\": {
\"Charset\": \"UTF-8\",
\"Data\": \"There have been ${string(v: r._value)} critical statuses.\"
}
},
\"Subject\": {
\"Charset\": \"UTF-8\",
\"Data\": \"InfluxDB critical alert\"
}
}
},
\"Destination\": {
\"ToAddresses\": [
\"john.doe@example.com\"
]
}
}"))} else {r with _value: 0}))
```

For details on the request syntax, see [SendEmail API v2 reference](https://docs.aws.amazon.com/ses/latest/APIReference-V2/API_SendEmail.html).
Expand Down Expand Up @@ -169,22 +199,30 @@ MAILJET_SECRET_APIKEY = secrets.get(key: "MAILJET_SECRET_APIKEY")

numberOfCrits = from(bucket: "_monitoring")
|> range(start: -task.every)
|> filter(fn: (r) => (r.measurement == "statuses" and "r.level" == "crit")
|> filter(fn: (r) => r.measurement == "statuses" and "r.level" == "crit")
|> count()

numberOfCrits
|> map(fn: (r) => (if r._value > 3 then {
r with _value: http.post(
url: "https://api.mailjet.com/v3.1/send",
headers: {"Content-type": "application/json", Authorization: "Basic ${MAILJET_APIKEY}:${MAILJET_SECRET_APIKEY}"},
headers: {
"Content-type": "application/json",
"Authorization": "Basic ${MAILJET_APIKEY}:${MAILJET_SECRET_APIKEY}"
},
data: bytes(v: "{
\"Messages\": [{
\"From\": {\"Email\": \”jane.doe@example.com\"},
\"To\": [{\"Email\": \"john.doe@example.com\"]},
\"Subject\": \”InfluxData critical alert\",
\"TextPart\": \”Example alert text\"
\"HTMLPart\": `"<h3>Hello, to review critical alerts, review your <a href=\"https://www.example-dashboard.com/\">Critical Alert Dashboard</a></h3>}]}'
}\""))} else {r with _value: 0}))
\"Messages\": [{
\"From\": {
\"Email\": \"jane.doe@example.com\"
},
\"To\": [{
\"Email\": \"john.doe@example.com\"
}],
\"Subject\": \"InfluxDB critical alert\",
\"TextPart\": \"There have been ${string(v: r._value)} critical statuses.\",
\"HTMLPart\": \"<h3>${string(v: r._value)} critical statuses</h3><p>There have been ${string(v: r._value)} critical statuses.\"
}]
}"))} else {r with _value: 0}))
```

{{% /tab-content %}}
Expand Down Expand Up @@ -220,14 +258,16 @@ numberOfCrits
|> map(fn: (r) =>
(if r._value > 1 then {r with _value: http.post(
url: "https://api.mailgun.net/v3/YOUR_DOMAIN/messages",
headers: {"Content-type": "application/json", Authorization: "Basic api:${MAILGUN_APIKEY}"},
headers: {
"Content-type": "application/json",
"Authorization": "Basic api:${MAILGUN_APIKEY}"
},
data: bytes(v: "{
\"from\": \"Username <mailgun@YOUR_DOMAIN_NAME>\",
\"to\"=\"YOU@YOUR_DOMAIN_NAME\",
\"to\"=\"email@example.com\",
\"subject\"=\"Critical InfluxData alert\",
\"text\"=\"You have critical alerts to review\"
}\""))} else {r with _value: 0}))
\"from\": \"Username <mailgun@YOUR_DOMAIN_NAME>\",
\"to\": \"email@example.com\",
\"subject\": \"InfluxDB critical alert\",
\"text\": \"There have been ${string(v: r._value)} critical statuses.\"
}"))} else {r with _value: 0}))
```

{{% /tab-content %}}
Expand Down

0 comments on commit 89d354a

Please sign in to comment.