Skip to content

Commit 5636e67

Browse files
authored
Merge pull request #1750 from AnthraX1/master
Add AWS SQS Alert
2 parents dff5437 + ca61341 commit 5636e67

7 files changed

Lines changed: 359 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
- None
55

66
## New features
7-
- None
7+
- Add AWS SQS alerter for sending alerts to Amazon Simple Queue Service queues - [#1750](https://github.com/jertel/elastalert2/pull/1750) - @AnthraX1
88

99
## Other changes
1010
- [Docs] Clarified Slack webhook URL documentation as it related to legacy vs app webhooks - [#1745](https://github.com/jertel/elastalert2/pull/1745) - @jertel

docs/source/alerts.rst

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,47 @@ Example When to use aws_profile usage::
546546
sns_topic_arn: 'arn:aws:sns:us-east-1:123456789:somesnstopic'
547547
sns_aws_profile: 'default'
548548

549+
AWS SQS (Amazon Simple Queue Service)
550+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
551+
552+
The AWS SQS alerter will send an alert message to an AWS SQS queue as a JSON object containing the rule name, matches, and alert text.
553+
The AWS SQS alerter uses boto3 and can use credentials in the rule yaml, in a standard AWS credential and config files, or
554+
via environment variables. See http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html for details.
555+
556+
Messages that exceed the SQS 1 MB size limit will be automatically truncated.
557+
558+
If ``sqs_aws_region`` is not set in the rule, the region will be automatically inferred from the SQS queue URL (for example, ``https://sqs.eu-west-1.amazonaws.com/...`` will use ``eu-west-1``).
559+
560+
AWS SQS requires one option:
561+
562+
``sqs_queue_url``: The URL of the SQS queue. For example, ``https://sqs.us-east-1.amazonaws.com/123456789012/my-queue``
563+
564+
Optional:
565+
566+
``sqs_aws_access_key_id``: An access key to connect to SQS with.
567+
568+
``sqs_aws_secret_access_key``: The secret key associated with the access key.
569+
570+
``sqs_aws_region``: The AWS region in which the SQS resource is located. Default is us-east-1
571+
572+
``sqs_aws_profile``: The AWS profile to use. If none specified, the default will be used.
573+
574+
Example when not using aws_profile::
575+
576+
alert:
577+
- sqs
578+
sqs_queue_url: 'https://sqs.us-east-1.amazonaws.com/123456789012/my-queue'
579+
sqs_aws_access_key_id: 'XXXXXXXXXXXXXXXXXX'
580+
sqs_aws_secret_access_key: 'YYYYYYYYYYYYYYYYYYYY'
581+
sqs_aws_region: 'us-east-1'
582+
583+
Example when using aws_profile::
584+
585+
alert:
586+
- sqs
587+
sqs_queue_url: 'https://sqs.us-east-1.amazonaws.com/123456789012/my-queue'
588+
sqs_aws_profile: 'default'
589+
549590
Chatwork
550591
~~~~~~~~
551592

docs/source/elastalert.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Currently, we have support built in for these alert types:
3131
- Alertmanager
3232
- AWS SES (Amazon Simple Email Service)
3333
- AWS SNS (Amazon Simple Notification Service)
34+
- AWS SQS (Amazon Simple Queue Service)
3435
- Chatwork
3536
- Command
3637
- Datadog

elastalert/alerters/sqs.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import boto3
2+
import json
3+
from urllib.parse import urlparse
4+
5+
from elastalert.alerts import Alerter
6+
from elastalert.util import elastalert_logger, EAException
7+
8+
9+
def _get_region_from_sqs_url(queue_url, default_region="us-east-1"):
10+
"""Infer the AWS region from an SQS queue URL like
11+
https://sqs.us-east-1.amazonaws.com/123456789012/my-queue.
12+
Falls back to default_region if it cannot be determined.
13+
"""
14+
host = urlparse(queue_url).hostname or ""
15+
parts = host.split(".")
16+
if len(parts) >= 3 and parts[0] == "sqs":
17+
return parts[1]
18+
return default_region
19+
20+
21+
class SqsAlerter(Alerter):
22+
"""Send alert using AWS SQS service"""
23+
24+
required_options = frozenset(["sqs_queue_url"])
25+
26+
def __init__(self, *args):
27+
super(SqsAlerter, self).__init__(*args)
28+
self.sqs_queue_url = self.rule.get("sqs_queue_url", None)
29+
self.sqs_aws_access_key_id = self.rule.get("sqs_aws_access_key_id")
30+
self.sqs_aws_secret_access_key = self.rule.get("sqs_aws_secret_access_key")
31+
explicit_region = self.rule.get("sqs_aws_region")
32+
if explicit_region:
33+
self.sqs_aws_region = explicit_region
34+
else:
35+
# If no region is configured explicitly, derive it from the queue URL.
36+
self.sqs_aws_region = _get_region_from_sqs_url(self.sqs_queue_url or "")
37+
self.profile = self.rule.get("sqs_aws_profile", None)
38+
39+
def alert(self, matches):
40+
# Create the alert as a JSON object
41+
alert_data = {
42+
"rule_name": self.rule["name"],
43+
"matches": matches,
44+
}
45+
alert_text = self.create_alert_body(matches)
46+
# SQS message body limit is 1 MB; crop text at ~800KB to be safe
47+
if len(alert_text) > 800000:
48+
alert_text = alert_text[:800000]
49+
alert_text += "\n*message was cropped according to SQS limits!*"
50+
alert_data["text"] = alert_text
51+
body = json.dumps(alert_data, default=str)
52+
53+
# If the body is still too long, remove the text field
54+
if len(body) > 1048576:
55+
alert_data["text"] = "Text message omitted due to SQS size limit."
56+
body = json.dumps(alert_data, default=str)
57+
try:
58+
# Always create the session in the configured region. SQS does not
59+
# infer the region from the queue URL; the client region must match.
60+
if self.profile is None:
61+
session = boto3.Session(
62+
aws_access_key_id=self.sqs_aws_access_key_id,
63+
aws_secret_access_key=self.sqs_aws_secret_access_key,
64+
region_name=self.sqs_aws_region,
65+
)
66+
else:
67+
session = boto3.Session(
68+
profile_name=self.profile,
69+
region_name=self.sqs_aws_region,
70+
)
71+
72+
sqs_client = session.client("sqs")
73+
74+
response = sqs_client.send_message(
75+
QueueUrl=self.sqs_queue_url,
76+
MessageBody=body,
77+
)
78+
except Exception as e:
79+
raise EAException("Error sending Amazon SQS: %s" % e)
80+
elastalert_logger.info("Sent Amazon SQS message to %s, MessageId: %s" % (self.sqs_queue_url, response.get("MessageId")))
81+
82+
def get_info(self):
83+
return {"type": "sqs"}

elastalert/loaders.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
from elastalert.alerters.slack import SlackAlerter
5353
from elastalert.alerters.smseagle import SMSEagleAlerter
5454
from elastalert.alerters.sns import SnsAlerter
55+
from elastalert.alerters.sqs import SqsAlerter
5556
from elastalert.alerters.teams import MsTeamsAlerter
5657
from elastalert.alerters.powerautomate import MsPowerAutomateAlerter
5758
from elastalert.alerters.yzj import YzjAlerter
@@ -115,6 +116,7 @@ class RulesLoader(object):
115116
'debug': elastalert.alerters.debug.DebugAlerter,
116117
'command': elastalert.alerters.command.CommandAlerter,
117118
'sns': SnsAlerter,
119+
'sqs': SqsAlerter,
118120
'ms_teams': MsTeamsAlerter,
119121
'ms_power_automate': MsPowerAutomateAlerter,
120122
'slack': SlackAlerter,

elastalert/schema.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,13 @@ properties:
445445
sns_aws_region: {type: string}
446446
sns_aws_profile: {type: string}
447447

448+
### AWS SQS
449+
sqs_queue_url: {type: string}
450+
sqs_aws_access_key_id: {type: string}
451+
sqs_aws_secret_access_key: {type: string}
452+
sqs_aws_region: {type: string}
453+
sqs_aws_profile: {type: string}
454+
448455
### Chatwork
449456
chatwork_apikey: {type: string}
450457
chatwork_room_id: {type: string}

0 commit comments

Comments
 (0)