Ejemplo n.º 1
0
    def compare(self, event):
        key = hashable(lookup_es_key(event, self.rules['query_key']))
        values = []
        elastalert_logger.debug(" Previous Values of compare keys  " +
                                str(self.occurrences))
        for val in self.rules['compound_compare_key']:
            lookup_value = lookup_es_key(event, val)
            values.append(lookup_value)
        elastalert_logger.debug(" Current Values of compare keys   " +
                                str(values))

        start = changed = False
        for val in values:
            if not isinstance(val,
                              bool) and not val and self.rules['ignore_null']:
                return False
        # If we have seen this key before, compare it to the new value
        if key in self.occurrences:
            for idx, previous_values in enumerate(self.occurrences[key]):
                elastalert_logger.debug(" " + str(previous_values) + " " +
                                        str(values[idx]))
                start = (previous_values != values[idx]
                         and values[idx] in self.rules['blacklist'])
                changed = (previous_values != values[idx]
                           and previous_values in self.rules['blacklist'])
                if start or changed:
                    break
            if changed:
                entry = [self.occurrences[key], None, None]
                # If using timeframe, only return true if the time delta is < timeframe
                if key in self.occurrence_time:
                    changed = (event[self.rules['timestamp_field']] -
                               self.occurrence_time[key] <=
                               self.timeframe(key))
                    old_time = self.occurrence_time[key]
                    new_time = event[self.rules['timestamp_field']]
                    duration = new_time - old_time
                    entry[1], entry[2] = [old_time, duration.total_seconds()]
                self.change_map[key] = tuple(entry)

        if key not in self.occurrences or start or changed:
            # Update the current value and time
            elastalert_logger.debug(
                " Setting current value of compare keys values " + str(values))
            self.occurrences[key] = values
            self.occurrence_time[key] = event[self.rules['timestamp_field']]
        elastalert_logger.debug(
            "Final result of comparision between previous and current values "
            + str(changed))
        return changed
Ejemplo n.º 2
0
 def add_match(self, match):
     # TODO this is not technically correct
     # if the term changes multiple times before an alert is sent
     # this data will be overwritten with the most recent change
     change = self.change_map.get(
         hashable(lookup_es_key(match, self.rules['query_key'])))
     extra = {}
     if change:
         extra = {
             'value': change[0],
             'start_time': change[1],
             'duration': change[2]
         }
         elastalert_logger.debug("Description of the changed records  " +
                                 str(dict(match.items() + extra.items())))
     super(BlacklistDurationRule,
           self).add_match(dict(match.items() + extra.items()))
Ejemplo n.º 3
0
    def alert(self, matches):
        body = ''
        for match in matches:
            body += str(BasicMatchString(self.rule, match))
            # Separate text of aggregated alerts with dashes
            if len(matches) > 1:
                body += '\n----------------------------------------\n'

        if self.custom_message is None:
            self.message = self.create_title(matches)
        else:
            self.message = self.custom_message.format(**matches[0])
        self.recipients = self._parse_responders(self.recipients,
                                                 self.recipients_args, matches,
                                                 self.default_reciepients)
        self.teams = self._parse_responders(self.teams, self.teams_args,
                                            matches, self.default_teams)
        post = {}
        post['message'] = self.message
        if self.account:
            post['user'] = self.account
        if self.recipients:
            post['responders'] = [{
                'username': r,
                'type': 'user'
            } for r in self.recipients]
        if self.teams:
            post['teams'] = [{'name': r, 'type': 'team'} for r in self.teams]
        if self.description:
            post['description'] = self.description.format(**matches[0])
        else:
            post['description'] = body
        if self.entity:
            post['entity'] = self.entity.format(**matches[0])
        if self.source:
            post['source'] = self.source.format(**matches[0])

        post['tags'] = []
        for i, tag in enumerate(self.tags):
            post['tags'].append(tag.format(**matches[0]))

        priority = self.priority
        if priority:
            priority = priority.format(**matches[0])
        if priority and priority not in ('P1', 'P2', 'P3', 'P4', 'P5'):
            elastalert_logger.warning(
                "Priority level does not appear to be specified correctly. \
                        Please make sure to set it to a value between P1 and P5"
            )
        else:
            post['priority'] = priority

        if self.alias is not None:
            post['alias'] = self.alias.format(**matches[0])

        details = self.get_details(matches)
        if details:
            post['details'] = details

        elastalert_logger.debug(json.dumps(post))

        headers = {
            'Content-Type': 'application/json',
            'Authorization': 'GenieKey {}'.format(self.api_key),
        }
        # set https proxy, if it was provided
        proxies = {
            'https': self.opsgenie_proxy
        } if self.opsgenie_proxy else None

        try:
            r = requests.post(self.to_addr,
                              json=post,
                              headers=headers,
                              proxies=proxies)

            elastalert_logger.debug('request response: {0}'.format(r))
            if r.status_code != 202:
                elastalert_logger.info("Error response from {0} \n "
                                       "API Response: {1}".format(
                                           self.to_addr, r))
                r.raise_for_status()
            elastalert_logger.info("Alert sent to OpsGenie")
        except Exception as err:
            raise EAException("Error sending alert: {0}".format(err))
Ejemplo n.º 4
0
    def alert(self, matches):
        try:
            elastalert_logger.debug("matches:%s", json.dumps(matches))
            client = self.get_client()
            # Instantiate a request object. You can further set the request parameters according to the API called and actual conditions
            # You can directly check the SDK source code to determine which attributes of `SendSmsRequest` can be set
            # An attribute may be of a basic type or import another data structure
            # We recommend you use the IDE for development where you can easily redirect to and view the documentation of each API and data structure
            req = models.SendSmsRequest()
            # Settings of a basic parameter:
            # The SDK uses the pointer style to specify parameters, so even for basic parameters, you need to use pointers to assign values to them.
            # The SDK provides encapsulation functions for importing the pointers of basic parameters
            # Help link:
            # SMS console: https://console.cloud.tencent.com/smsv2
            # sms helper: https://intl.cloud.tencent.com/document/product/382/3773?from_cn_redirect=1
            # SMS application ID, which is the `SdkAppId` generated after an application is added in the [SMS console], such as 1400006666
            # 短信应用ID: 短信SdkAppid在 [短信控制台] 添加应用后生成的实际SdkAppid,示例如 1400006666
            req.SmsSdkAppId = self.tencent_sms_sdk_appid

            # SMS signature content, which should be encoded in UTF-8. You must enter an approved signature, which can be viewed in the [SMS console]
            # 短信签名内容: 使用 UTF-8 编码,必须填写已审核通过的签名,签名信息可登录 [短信控制台] 查看
            req.SignName = self.tencent_sms_sign_name

            # SMS code number extension, which is not activated by default. If you need to activate it, please contact [SMS Helper]
            # 短信码号扩展号: 默认未开通,如需开通请联系 [sms helper]
            req.ExtendCode = ""

            # User session content, which can carry context information such as user-side ID and will be returned as-is by the server
            # 用户的 session 内容: 可以携带用户侧 ID 等上下文信息,server 会原样返回
            # req.SessionContext = "xxx"

            # `senderid` for Global SMS, which is not activated by default. If you need to activate it, please contact [SMS Helper] for assistance. This parameter should be left empty for Mainland China SMS
            # 国际/港澳台短信 senderid: 国内短信填空,默认未开通,如需开通请联系 [sms helper]
            # req.SenderId = ""

            # Target mobile number in the E.164 standard (+[country/region code][mobile number])
            # Example: +8613711112222, which has a + sign followed by 86 (country/region code) and then by 13711112222 (mobile number). Up to 200 mobile numbers are supported
            # 下发手机号码,采用 e.164 标准,+[国家或地区码][手机号]
            # 示例如:+8613711112222,其中前面有一个+号 ,86为国家码,13711112222为手机号,最多不要超过200个手机号
            req.PhoneNumberSet = self.tencent_sms_to_number

            # Template ID. You must enter the ID of an approved template, which can be viewed in the [SMS console]
            # 模板 ID: 必须填写已审核通过的模板 ID。模板ID可登录 [短信控制台] 查看
            req.TemplateId = self.tencent_sms_template_id

            # Template parameters. If there are no template parameters, leave it empty
            req.TemplateParamSet = self.create_template_parm(matches)

            elastalert_logger.debug("SendSms request :%s",
                                    json.dumps(req.__dict__))

            # Initialize the request by calling the `DescribeInstances` method on the client object. Note: the request method name corresponds to the request object
            # The returned `resp` is an instance of the `DescribeInstancesResponse` class which corresponds to the request object
            resp = client.SendSms(req)
            # A string return packet in JSON format is outputted
            elastalert_logger.debug("SendSms response :%s",
                                    resp.to_json_string())
            for item in resp.SendStatusSet:
                if item.Code != "Ok":
                    raise TencentCloudSDKException(item.Code, item.Message,
                                                   resp.RequestId)
        except TencentCloudSDKException as e:
            raise EAException("Error posting to TencentSMS: %s" % e)
        elastalert_logger.info("Alert sent to TencentSMS")