示例#1
0
    def profile(self):
        profile_path = self.rules.get('profile')
        if profile_path is None:
            return {}
        now = time.time()

        try:
            if not (self._update_ts <= now <
                    self._update_ts + UPDATE_INTERVAL):
                # Check if updated
                ts = os.path.getmtime(profile_path)
                self._update_ts = now
            else:
                # Skip
                ts = self._profile_ts

            if ts > self._profile_ts or ts > now or now > self._profile_ts + FORCE_UPDATE_INTERVAL:
                elastalert_logger.info('Reloading profile %s', profile_path)
                with open(profile_path, 'r') as profile_file:
                    profile = json.load(profile_file)
                    self._profile = {
                        k: timedelta(seconds=profile[k])
                        for k in profile
                    }
                    self._profile_ts = now
        except (OSError, IOError, ValueError) as e:
            elastalert_logger.error('Cannot load profile %s: %s', profile_path,
                                    e)
        return self._profile
示例#2
0
    def garbage_collect(self, timestamp):
        if self.garbage_time == 0:
            self.garbage_time = timestamp
        diff = timestamp - self.garbage_time
        self.garbage_time = timestamp
        elastalert_logger.info(
            "From garbage collect - time diff since last exec: %f" %
            diff.total_seconds())
        if not diff.total_seconds() > 0:
            return

        self.exec_num += 1
        elastalert_logger.info("Timeperiod: %d/%d" %
                               (self.exec_num, self.runs_per_timeperiod))
        # end of timeperiod
        if self.exec_num >= self.runs_per_timeperiod:
            self.exec_num = 0
            self.timeperiods_index += 1
        # end of all timeperiods (self.no_of_timeperiods)
        if self.timeperiods_index >= self.no_of_timeperiods:
            elastalert_logger.info("All timeperiods passed")
            elastalert_logger.info("Sets for all timeperiods: %s" %
                                   str(self.values))
            self.timeperiods_index = 0
            result = self.values[0]
            for i in range(0, self.no_of_timeperiods):
                result = result & self.values[i]
                self.values[i].clear()

            if result != set():
                result_str = " ".join(result)
                elastalert_logger.info("Alert triggered, final result: %s" %
                                       result_str)
                extra = {self.field: result_str}
                self.add_match(extra)
示例#3
0
    def alert(self, matches):
        body = ''
        for match in matches:
            body += str(BasicMatchString(self.rule, match))
            if len(matches) > 1:
                body += '\n----------------------------------------\n'
        if len(body) > 2047:
            body = body[
                0:
                1950] + '\n *message was cropped according to chatwork embed description limits!*'
        headers = {'X-ChatWorkToken': self.chatwork_apikey}
        # set https proxy, if it was provided
        proxies = {
            'https': self.chatwork_proxy
        } if self.chatwork_proxy else None
        auth = HTTPProxyAuth(
            self.chatwork_proxy_login,
            self.chatwork_proxy_pass) if self.chatwork_proxy_login else None
        params = {'body': body}

        try:
            response = requests.post(self.url,
                                     params=params,
                                     headers=headers,
                                     proxies=proxies,
                                     auth=auth)
            response.raise_for_status()
        except RequestException as e:
            raise EAException(
                "Error posting to Chattwork: %s. Details: %s" %
                (e, "" if e.response is None else e.response.text))

        elastalert_logger.info("Alert sent to Chatwork room %s" %
                               self.chatwork_room_id)
示例#4
0
    def alert(self, matches):
        """ Each match will trigger a POST to the specified endpoint(s). """
        for match in matches:
            payload = match if self.post_all_values else {}
            payload.update(self.post_static_payload)
            for post_key, es_key in list(self.post_payload.items()):
                payload[post_key] = lookup_es_key(match, es_key)
            headers = {
                "Content-Type": "application/json",
                "Accept": "application/json;charset=utf-8"
            }
            if self.post_ca_certs:
                verify = self.post_ca_certs
            else:
                verify = not self.post_ignore_ssl_errors
            if self.post_ignore_ssl_errors:
                requests.packages.urllib3.disable_warnings()

            headers.update(self.post_http_headers)
            proxies = {'https': self.post_proxy} if self.post_proxy else None
            for url in self.post_url:
                try:
                    response = requests.post(url,
                                             data=json.dumps(
                                                 payload, cls=DateTimeEncoder),
                                             headers=headers,
                                             proxies=proxies,
                                             timeout=self.timeout,
                                             verify=verify)
                    response.raise_for_status()
                except RequestException as e:
                    raise EAException("Error posting HTTP Post alert: %s" % e)
            elastalert_logger.info("HTTP Post alert sent.")
示例#5
0
    def alert(self, matches):
        body = '⚠ *%s* ⚠ ```\n' % (self.create_title(matches))
        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 len(body) > 4095:
            body = body[0:4000] + "\n⚠ *message was cropped according to telegram limits!* ⚠"
        body += ' ```'

        headers = {'content-type': 'application/json'}
        # set https proxy, if it was provided
        proxies = {'https': self.telegram_proxy} if self.telegram_proxy else None
        auth = HTTPProxyAuth(self.telegram_proxy_login, self.telegram_proxy_password) if self.telegram_proxy_login else None
        payload = {
            'chat_id': self.telegram_room_id,
            'text': body,
            'parse_mode': 'markdown',
            'disable_web_page_preview': True
        }

        try:
            response = requests.post(self.url, data=json.dumps(payload, cls=DateTimeEncoder), headers=headers, proxies=proxies, auth=auth)
            warnings.resetwarnings()
            response.raise_for_status()
        except RequestException as e:
            raise EAException("Error posting to Telegram: %s. Details: %s" % (e, "" if e.response is None else e.response.text))

        elastalert_logger.info(
            "Alert sent to Telegram room %s" % self.telegram_room_id)
示例#6
0
def configure_logging(args, conf):
    # configure logging from config file if provided
    if 'logging' in conf:
        # load new logging config
        logging.config.dictConfig(conf['logging'])

    if args.verbose and args.debug:
        elastalert_logger.info(
            "Note: --debug and --verbose flags are set. --debug takes precedent."
        )

    # re-enable INFO log level on elastalert_logger in verbose/debug mode
    # (but don't touch it if it is already set to INFO or below by config)
    if args.verbose or args.debug:
        if elastalert_logger.level > logging.INFO or elastalert_logger.level == logging.NOTSET:
            elastalert_logger.setLevel(logging.INFO)

    if args.debug:
        elastalert_logger.info(
            """Note: In debug mode, alerts will be logged to console but NOT actually sent.
            To send them but remain verbose, use --verbose instead.""")

    if not args.es_debug and 'logging' not in conf:
        logging.getLogger('elasticsearch').setLevel(logging.WARNING)

    if args.es_debug_trace:
        tracer = logging.getLogger('elasticsearch.trace')
        tracer.setLevel(logging.INFO)
        tracer.addHandler(logging.FileHandler(args.es_debug_trace))
    def senddata(self, content):
        config_file = os.environ.get('ALERTA_CONF_FILE') or OPTIONS['config_file']
        config = configparser.RawConfigParser(defaults=OPTIONS)
        try:
            config.read(os.path.expanduser(config_file))
        except Exception:
            sys.exit("Problem reading configuration file %s - is this an ini file?" % config_file)

        want_profile = os.environ.get('ALERTA_DEFAULT_PROFILE') or config.defaults().get('profile')
        if want_profile and config.has_section('profile %s' % want_profile):
            for opt in OPTIONS:
                try:
                    OPTIONS[opt] = config.getboolean('profile %s' % want_profile, opt)
                except (ValueError, AttributeError):
                    OPTIONS[opt] = config.get('profile %s' % want_profile, opt)
        else:
            for opt in OPTIONS:
                try:
                    OPTIONS[opt] = config.getboolean('DEFAULT', opt)
                except (ValueError, AttributeError):
                    OPTIONS[opt] = config.get('DEFAULT', opt)
        try:
            LOG.debug("[alerta] sendto=%s ", OPTIONS.get("endpoint"))
            api = Client(endpoint=OPTIONS.get("endpoint"), key=OPTIONS.get("key"), ssl_verify=OPTIONS.get("sslverify"))
            api.send_alert(**content)
        except RequestException as e:
            raise EAException("send message has error: %s" % e)

        elastalert_logger.info("send msg success" )
示例#8
0
    def alert(self, matches):
        body = self.create_alert_body(matches)

        # post to victorops
        headers = {'content-type': 'application/json'}
        # set https proxy, if it was provided
        proxies = {
            'https': self.victorops_proxy
        } if self.victorops_proxy else None
        payload = {
            "message_type": self.victorops_message_type,
            "entity_display_name": self.victorops_entity_display_name,
            "monitoring_tool": "ElastAlert",
            "state_message": body
        }
        if self.victorops_entity_id:
            payload["entity_id"] = self.victorops_entity_id

        try:
            response = requests.post(self.url,
                                     data=json.dumps(payload,
                                                     cls=DateTimeEncoder),
                                     headers=headers,
                                     proxies=proxies)
            response.raise_for_status()
        except RequestException as e:
            raise EAException("Error posting to VictorOps: %s" % e)
        elastalert_logger.info("Trigger sent to VictorOps")
示例#9
0
    def __init__(self, *args):
        super(UniqueLongTermRule, self).__init__(*args)
        self.values = []
        self.garbage_time = 0
        self.exec_num = 0
        self.field = self.rules['compare_key']
        self.timeperiods_index = 0
        self.no_of_timeperiods = int(self.rules['no_of_timeperiods'])
        for i in range(0, self.no_of_timeperiods):
            self.values.append(set())

        timeperiod_sec = int(self.rules['timeframe'].total_seconds())
        run_every_sec = int(self.rules['run_every'].total_seconds())
        if run_every_sec > timeperiod_sec:
            raise EAException(
                "Run Every option cannot be greater than Timeperiod option")
        if timeperiod_sec % run_every_sec != 0:
            raise EAException(
                "Run Every must fit integer number of times in Timeperiod")
        self.runs_per_timeperiod = int(timeperiod_sec / run_every_sec)

        elastalert_logger.info(
            "Timeperiod sec: %d, Number of executions per timeperiod: %d, Number of timeperiods: %d"
            %
            (timeperiod_sec, self.runs_per_timeperiod, self.no_of_timeperiods))
示例#10
0
    def alert(self, matches):
        body = self.create_alert_body(matches)

        body = self.format_body(body)
        # post to Teams
        headers = {'content-type': 'application/json'}
        # set https proxy, if it was provided
        proxies = {
            'https': self.ms_teams_proxy
        } if self.ms_teams_proxy else None
        payload = {
            '@type': 'MessageCard',
            '@context': 'http://schema.org/extensions',
            'summary': self.ms_teams_alert_summary,
            'title': self.create_title(matches),
            'text': body
        }
        if self.ms_teams_theme_color != '':
            payload['themeColor'] = self.ms_teams_theme_color

        for url in self.ms_teams_webhook_url:
            try:
                response = requests.post(url,
                                         data=json.dumps(payload,
                                                         cls=DateTimeEncoder),
                                         headers=headers,
                                         proxies=proxies)
                response.raise_for_status()
            except RequestException as e:
                raise EAException("Error posting to ms teams: %s" % e)
        elastalert_logger.info("Alert sent to MS Teams")
示例#11
0
    def alert(self, matches):
        # Format the command and arguments
        command = [
            resolve_string(command_arg, matches[0])
            for command_arg in self.rule['command']
        ]
        self.last_command = command

        # Run command and pipe data
        try:
            subp = subprocess.Popen(command,
                                    stdin=subprocess.PIPE,
                                    shell=self.shell)

            if self.rule.get('pipe_match_json'):
                match_json = json.dumps(matches, cls=DateTimeEncoder) + '\n'
                stdout, stderr = subp.communicate(input=match_json.encode())
            elif self.rule.get('pipe_alert_text'):
                alert_text = self.create_alert_body(matches)
                stdout, stderr = subp.communicate(input=alert_text.encode())
            if self.rule.get("fail_on_non_zero_exit", False) and subp.wait():
                raise EAException(
                    "Non-zero exit code while running command %s" %
                    (' '.join(command)))
        except OSError as e:
            raise EAException("Error while running command %s: %s" %
                              (' '.join(command), e))
        elastalert_logger.info("Alert sent to Command")
示例#12
0
    def garbage_collect(self, timestamp):
        key_del = set()
        for key, value in self.start_time_per_qk.items():
            if total_seconds(timestamp - value) > self.time_seconds:
                # delete start entry if end event not found within specified timeframe
                if not self.invert:
                    elastalert_logger.info(
                        "Match not found for query_key: %s within specified timeframe"
                        % key)
                    key_del.add(key)

                # alert when end event not found after specified time has elapsed
                else:
                    elastalert_logger.info(
                        "Alert triggered! End event with query_key: %s not found"
                        % key)
                    extra = {
                        self.compare_key: 'end event not found',
                        'start_event': self.start_value,
                        'end_event': self.end_value,
                        self.query_key: key,
                    }
                    self.add_match(extra)
                    key_del.add(key)

        for key in key_del:
            del self.start_time_per_qk[key]
示例#13
0
    def senddata(self, content):
        
        # 微信企业号有字符长度限制,超长自动截断

        if len(content) > 2000:
            content = content[:1997] + "..."

        send_url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=' + self.access_token

        headers = {'content-type': 'application/json'}

        payload = {
            "touser": self.user_id,
            "toparty": self.party_id,
            "totag": self.tag_id,
            'msgtype': "text",
            "agentid": self.agent_id,
            "text":{
                "content": content.encode('UTF-8') #避免中文字符发送失败
               },
            "safe":"0"
        }

        # set https proxy, if it was provided
        # proxies = {'https': self.pagerduty_proxy} if self.pagerduty_proxy else None
        try:
            response = requests.post(send_url, data=json.dumps(payload, ensure_ascii=False), headers=headers)
            response.raise_for_status()
        except RequestException as e:
            raise EAException("推送消息异常: %s" % e)
        
        elastalert_logger.info("推送消息")

        print response.text
示例#14
0
    def alert(self, matches):
        client = TwilioClient(self.twilio_account_sid, self.twilio_auth_token)

        try:
            if self.twilio_use_copilot:
                if self.twilio_message_service_sid is None:
                    raise EAException(
                        "Twilio Copilot requires the 'twilio_message_service_sid' option"
                    )

                client.messages.create(
                    body=self.rule['name'],
                    to=self.twilio_to_number,
                    messaging_service_sid=self.twilio_message_service_sid)
            else:
                if self.twilio_from_number is None:
                    raise EAException(
                        "Twilio SMS requires the 'twilio_from_number' option")

                client.messages.create(body=self.rule['name'],
                                       to=self.twilio_to_number,
                                       from_=self.twilio_from_number)
        except TwilioRestException as e:
            raise EAException("Error posting to twilio: %s" % e)

        elastalert_logger.info("Trigger sent to Twilio")
    def alert(self, matches):

        # 参考elastalert的写法
        # https://github.com/Yelp/elastalert/blob/master/elastalert/alerts.py#L236-L243
        # body = self.create_alert_body(matches)
        # LOG.error(body)
        '''
        resource={HOST}
        event={subject}
        environment=Production
        severity=warning
        status=Open
        ack={EVENT.ACK.STATUS}
        service={Service_NAME}
        value={Num_hits}
        text={NAME + Message}
        tags={}
        attributes.name={Name}
        attributes.ip={HOST.IP1}
        type=elastAlert
        dateTime={@timestamp}
        attributes.models=["dingding"]
        attributes.app={project_name}

        '''

        body = self.create_alert_body(matches)
        if len(body) >= 1000:
            body = body[:1000]

        payload = {
            # "resource":matches[0]["fields"].get("ip",""),
            "resource": self.rule["name"],
            "event":self.create_custom_title(matches),
            "environment":"Production",
            "severity":"warning",
            "status": "open",
            "service":[self.rule["app"]],
            "value": matches[0]["num_hits"],
            # "text": self.rule["name"] + "\t" + matches[0]["message"],
            "text": body,
            "type": "elastAlert",
            "tags":"",
            "dateTime":matches[0]["@timestamp"]
        }
        attributes = {}
        attributes["name"] = self.rule["name"]
        fields = matches[0].get("fields",{})
        attributes["ip"] = fields.get("ip","")
        attributes["models"] = "dingding"
        attributes["app"] = self.rule["app"]
        payload["attributes"] = attributes


        #matches 是json格式
        #self.create_alert_body(matches)是String格式,详见 [create_alert_body 函数](https://github.com/Yelp/elastalert/blob/master/elastalert/alerts.py)
        LOG.debug(payload)
        elastalert_logger.info("send message to alerta")
        self.senddata(payload)
示例#16
0
    def alert(self, matches):
        body = self.create_alert_body(matches)
        body = self.format_body(body)
        headers = {'content-type': 'application/json'}
        proxies = {
            'https': self.rocket_chat_proxy
        } if self.rocket_chat_proxy else None
        payload = {
            'username':
            self.rocket_chat_username_override,
            'text':
            self.rocket_chat_text_string,
            'attachments': [{
                'color': self.rocket_chat_msg_color,
                'title': self.create_title(matches),
                'text': body,
                'fields': []
            }]
        }

        # if we have defined fields, populate noteable fields for the alert
        if self.rocket_chat_alert_fields != '':
            payload['attachments'][0]['fields'] = self.populate_fields(matches)

        if self.rocket_chat_emoji_override != '':
            payload['emoji'] = self.rocket_chat_emoji_override

        if self.rocket_chat_attach_kibana_discover_url:
            kibana_discover_url = lookup_es_key(matches[0],
                                                'kibana_discover_url')
            if kibana_discover_url:
                payload['attachments'].append({
                    'color': self.rocket_chat_kibana_discover_color,
                    'title': self.rocket_chat_kibana_discover_title,
                    'title_link': kibana_discover_url
                })

        for url in self.rocket_chat_webhook_url:
            for channel_override in self.rocket_chat_channel_override:
                try:
                    if self.rocket_chat_ca_certs:
                        verify = self.rocket_chat_ca_certs
                    else:
                        verify = not self.rocket_chat_ignore_ssl_errors
                    if self.rocket_chat_ignore_ssl_errors:
                        requests.packages.urllib3.disable_warnings()
                    payload['channel'] = channel_override
                    response = requests.post(url,
                                             data=json.dumps(
                                                 payload, cls=DateTimeEncoder),
                                             headers=headers,
                                             verify=verify,
                                             proxies=proxies,
                                             timeout=self.rocket_chat_timeout)
                    warnings.resetwarnings()
                    response.raise_for_status()
                except RequestException as e:
                    raise EAException("Error posting to Rocket.Chat: %s" % e)
            elastalert_logger.info("Alert sent to Rocket.Chat")
示例#17
0
    def alert(self, matches):
    	
        # 获取或者更新access_token
        self.get_token()

        self.send_template_data(matches)

        elastalert_logger.info("send message to %s" % (self.openid))
示例#18
0
 def add_value(self, qkey, value):
     try:
         self.arr[qkey].append(float(value))
     except ValueError:
         elastalert_logger.info("Ignoring value since it is not a number")
         return False
     while len(self.arr[qkey]) > self.count:
         self.arr[qkey].pop(0)
     return True
示例#19
0
    def alert(self, matches):
        # Build TheHive alert object, starting with some defaults, updating with any
        # user-specified config
        alert_config = {
            'artifacts': [],
            'customFields': {},
            'date': int(time.time()) * 1000,
            'description': self.create_alert_body(matches),
            'sourceRef': str(uuid.uuid4()),
            'tags': [],
            'title': self.create_title(matches),
        }
        alert_config.update(self.rule.get('hive_alert_config', {}))

        # Iterate through each match found, populating the alert tags and observables as required
        tags = set()
        artifacts = []
        for match in matches:
            artifacts = artifacts + self.load_observable_artifacts(match)
            tags.update(self.load_tags(alert_config['tags'], match))

        alert_config['artifacts'] = artifacts
        alert_config['tags'] = list(tags)

        # Populate the customFields
        alert_config['customFields'] = self.load_custom_fields(
            alert_config['customFields'], matches[0])

        # POST the alert to TheHive
        connection_details = self.rule['hive_connection']

        api_key = connection_details.get('hive_apikey', '')
        hive_host = connection_details.get('hive_host', 'http://localhost')
        hive_port = connection_details.get('hive_port', 9000)
        proxies = connection_details.get('hive_proxies', {
            'http': '',
            'https': ''
        })
        verify = connection_details.get('hive_verify', False)

        alert_body = json.dumps(alert_config, indent=4, sort_keys=True)
        req = f'{hive_host}:{hive_port}/api/alert'
        headers = {
            'Content-Type': 'application/json',
            'Authorization': f'Bearer {api_key}'
        }

        try:
            response = requests.post(req,
                                     headers=headers,
                                     data=alert_body,
                                     proxies=proxies,
                                     verify=verify)
            response.raise_for_status()
        except RequestException as e:
            raise EAException(f"Error posting to TheHive: {e}")
        elastalert_logger.info("Alert sent to TheHive")
示例#20
0
    def alert(self, matches):
        body = self.create_alert_body(matches)

        to_addr = self.email
        if 'ses_email_from_field' in self.rule:
            recipient = lookup_es_key(matches[0],
                                      self.rule['ses_email_from_field'])
            if isinstance(recipient, str):
                if '@' in recipient:
                    to_addr = [recipient]
                elif 'ses_email_add_domain' in self.rule:
                    to_addr = [recipient + self.rule['ses_email_add_domain']]
            elif isinstance(recipient, list):
                to_addr = recipient
                if 'ses_email_add_domain' in self.rule:
                    to_addr = [
                        name + self.rule['ses_email_add_domain']
                        for name in to_addr
                    ]

        try:
            if self.aws_profile != '':
                session = boto3.Session(profile_name=self.aws_profile)
            else:
                session = boto3.Session(
                    aws_access_key_id=self.aws_access_key_id,
                    aws_secret_access_key=self.aws_secret_access_key,
                    region_name=self.aws_region)

            client = session.client('ses')

            client.send_email(Source=self.from_addr,
                              Destination={
                                  'ToAddresses': to_addr,
                                  'CcAddresses': self.rule.get('ses_cc', []),
                                  'BccAddresses': self.rule.get('ses_bcc', [])
                              },
                              Message={
                                  'Subject': {
                                      'Charset': 'UTF-8',
                                      'Data': self.create_title(matches),
                                  },
                                  'Body': {
                                      'Text': {
                                          'Charset': 'UTF-8',
                                          'Data': body,
                                      }
                                  }
                              },
                              ReplyToAddresses=self.rule.get(
                                  'ses_email_reply_to', []))
        except Exception as e:
            raise EAException("Error sending Amazon SES: %s" % e)

        elastalert_logger.info("Sent Amazon SES to %s" % (to_addr, ))
示例#21
0
    def alert(self, matches):
        body = self.create_alert_body(matches)

        body = self.format_body(body)
        # post to Teams
        headers = {'content-type': 'application/json'}

        if self.ms_teams_ca_certs:
            verify = self.ms_teams_ca_certs
        else:
            verify = not self.ms_teams_ignore_ssl_errors
        if self.ms_teams_ignore_ssl_errors:
            requests.packages.urllib3.disable_warnings()

        # set https proxy, if it was provided
        proxies = {'https': self.ms_teams_proxy} if self.ms_teams_proxy else None
        payload = {
            '@type': 'MessageCard',
            '@context': 'http://schema.org/extensions',
            'summary': self.ms_teams_alert_summary,
            'title': self.create_title(matches),
            'sections': [{'text': body}],
        }

        if self.ms_teams_alert_facts != '':
            payload['sections'][0]['facts'] = self.populate_facts(matches)

        if self.ms_teams_theme_color != '':
            payload['themeColor'] = self.ms_teams_theme_color

        if self.ms_teams_attach_kibana_discover_url:
            kibana_discover_url = lookup_es_key(matches[0], 'kibana_discover_url')
            if kibana_discover_url:
                payload['potentialAction'] = [
                    {
                        '@type': 'OpenUri',
                        'name': self.ms_teams_kibana_discover_title,
                        'targets': [
                            {
                                'os': 'default',
                                'uri': kibana_discover_url,
                            }
                        ],
                    }
                ]

        for url in self.ms_teams_webhook_url:
            try:
                response = requests.post(url, data=json.dumps(payload, cls=DateTimeEncoder),
                                         headers=headers, proxies=proxies, verify=verify)
                response.raise_for_status()
            except RequestException as e:
                raise EAException("Error posting to MS Teams: %s" % e)
        elastalert_logger.info("Alert sent to MS Teams")
示例#22
0
    def alert(self, matches):
        client = Exotel(self.exotel_account_sid, self.exotel_auth_token)

        try:
            message_body = self.rule['name'] + self.sms_body
            response = client.sms(self.rule['exotel_from_number'], self.rule['exotel_to_number'], message_body)
            if response != 200:
                raise EAException("Error posting to Exotel, response code is %s" % response)
        except RequestException:
            raise EAException("Error posting to Exotel").with_traceback(sys.exc_info()[2])
        elastalert_logger.info("Trigger sent to Exotel")
示例#23
0
    def alert(self, matches):
        body = ''
        title = u'%s' % (self.create_title(matches))
        for match in matches:
            body += str(BasicMatchString(self.rule, match))
            if len(matches) > 1:
                body += '\n----------------------------------------\n'
        if len(body) > 2047:
            body = body[
                0:
                1950] + '\n *message was cropped according to discord embed description limits!*'

        proxies = {'https': self.discord_proxy} if self.discord_proxy else None
        auth = HTTPProxyAuth(
            self.discord_proxy_login,
            self.discord_proxy_password) if self.discord_proxy_login else None
        headers = {"Content-Type": "application/json"}

        data = {}
        data["content"] = "%s %s %s" % (self.discord_emoji_title, title,
                                        self.discord_emoji_title)
        data["embeds"] = []
        embed = {}
        embed["description"] = "%s" % (body)
        embed["color"] = (self.discord_embed_color)

        if self.discord_embed_footer:
            embed["footer"] = {}
            embed["footer"]["text"] = (self.discord_embed_footer
                                       ) if self.discord_embed_footer else None
            embed["footer"]["icon_url"] = (
                self.discord_embed_icon_url
            ) if self.discord_embed_icon_url else None
        else:
            None

        data["embeds"].append(embed)

        try:
            response = requests.post(self.discord_webhook_url,
                                     data=json.dumps(data),
                                     headers=headers,
                                     proxies=proxies,
                                     auth=auth)
            warnings.resetwarnings()
            response.raise_for_status()
        except RequestException as e:
            raise EAException(
                "Error posting to Discord: %s. Details: %s" %
                (e, "" if e.response is None else e.response.text))

        elastalert_logger.info("Alert sent to the webhook %s" %
                               self.discord_webhook_url)
示例#24
0
    def compare(self, event):
        changed = False
        qkey = lookup_es_key(event, self.rules['query_key'])
        value = lookup_es_key(event, self.rules['compare_key'])
        if qkey not in self.arr:
            self.arr[qkey] = []

        if self.add_value(qkey, value):
            changed = self.set_off_alarm(qkey)

        elastalert_logger.info("%s: %s" % (str(qkey), str(self.arr[qkey])))
        return changed
示例#25
0
    def alert(self, matches):
        # https://github.com/Yelp/elastalert/blob/master/elastalert/alerts.py#L236-L243
        body = self.create_alert_body(matches)

        # http://qydev.weixin.qq.com/wiki/index.php?title=AccessToken
        self.get_token()
        
        #print self.access_token
        #print self.expires_in

        self.senddata(body)
        elastalert_logger.info("发送消息给 %s" % (self.corp_id))
示例#26
0
    def senddata(self, content):

        #如果需要原始json,需要传入matches

        # http://qydev.weixin.qq.com/wiki/index.php?title=%E6%B6%88%E6%81%AF%E7%B1%BB%E5%9E%8B%E5%8F%8A%E6%95%B0%E6%8D%AE%E6%A0%BC%E5%BC%8F
        # 微信企业号有字符长度限制(2048),超长自动截断

        # 参考 http://blog.csdn.net/handsomekang/article/details/9397025
        #len utf8 3字节,gbk2 字节,ascii 1字节
        if len(content) > 2048:
            content = content[:2045] + "..."

        # 微信发送消息文档
        # http://qydev.weixin.qq.com/wiki/index.php?title=%E6%B6%88%E6%81%AF%E7%B1%BB%E5%9E%8B%E5%8F%8A%E6%95%B0%E6%8D%AE%E6%A0%BC%E5%BC%8F
        send_url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s' % (
            self.access_token)

        headers = {'content-type': 'application/json'}

        #最新微信企业号调整校验规则,tagid必须是string类型,如果是数字类型会报错,故而使用str()函数进行转换
        payload = {
            "touser": self.user_id and str(self.user_id) or '',  #用户账户,建议使用tag
            "toparty": self.party_id and str(self.party_id)
            or '',  #部门id,建议使用tag
            "totag": self.tag_id and str(self.tag_id) or
            '',  #tag可以很灵活的控制发送群体细粒度。比较理想的推送应该是,在heartbeat或者其他elastic工具自定义字段,添加标签id。这边根据自定义的标签id,进行推送
            'msgtype': "text",
            "agentid": self.agent_id,
            "text": {
                "content":
                content.encode('UTF-8').decode("latin1")  #避免中文字符发送失败
            },
            "safe": "0"
        }

        # set https proxy, if it was provided
        # 如果需要设置代理,可修改此参数并传入requests
        # proxies = {'https': self.pagerduty_proxy} if self.pagerduty_proxy else None
        try:
            #response = requests.post(send_url, data=json.dumps(payload, ensure_ascii=False), headers=headers)
            response = requests.post(send_url,
                                     data=json.dumps(payload,
                                                     cls=MyEncoder,
                                                     indent=4,
                                                     ensure_ascii=False),
                                     headers=headers)
            response.raise_for_status()
        except RequestException as e:
            raise EAException("send message has error: %s" % e)

        elastalert_logger.info("send msg and response: %s" % response.text)
示例#27
0
    def alert(self, matches):
        headers = {'content-type': 'application/json'}
        proxies = {
            'https': self.ms_teams_proxy
        } if self.ms_teams_proxy else None

        payload = {
            '@type':
            'MessageCard',
            '@context':
            'http://schema.org/extensions',
            'themeColor':
            self.ms_teams_theme_color,
            'summary':
            self.ms_teams_alert_summary,
            'sections': [{
                'activityTitle': self.create_title(matches),
                'facts': [],
                'markdown': True
            }],
            'potentialAction': []
        }

        if self.ms_teams_alert_title != '':
            payload['sections'][0]['activityTitle'] = self.populate_title(
                matches)

        if self.ms_teams_alert_fields != '':
            payload['sections'][0]['facts'] = self.populate_fields(matches)

        if self.ms_teams_alert_links != '' or self.ms_teams_index_pattern_url != '':
            payload['potentialAction'] = self.populate_links(matches)

        with open('/opt/elastalert/elastalert_modules/alerter_test_output.log',
                  'a') as outfile:
            json.dump(payload, outfile)

        for url in self.ms_teams_webhook_url:
            try:
                response = requests.post(url,
                                         data=json.dumps(payload,
                                                         cls=DateTimeEncoder),
                                         headers=headers,
                                         proxies=proxies)
                response.raise_for_status()
            except RequestException as e:
                raise EAException("Error posting to ms teams: %s" % e)
        elastalert_logger.info("Alert sent to MS Teams")
示例#28
0
 def alert(self, matches):
     headers = {
         'content-type': 'application/json',
         'Accept': 'application/json;charset=utf-8',
     }
     body = self.create_alert_body(matches)
     content = {'title': self.create_title(matches), 'text': body}
     webhook_url = 'https://'
     try:
         response = requests.post(webhook_url,
                                  data=json.dumps(content),
                                  headers=headers)
         response.raise_for_status()
     except RequestException as e:
         raise EAException("send message has error: %s" % e)
     elastalert_logger.info("send msg and response: %s")
    def alert(self, matches):

        if not self.party_id and not self.user_id and not self.tag_id:
            elastalert_logger.warn("All touser & toparty & totag invalid")

        # 参考elastalert的写法
        # https://github.com/Yelp/elastalert/blob/master/elastalert/alerts.py#L236-L243
        body = self.create_alert_body(matches)

        # 微信企业号获取Token文档
        # http://qydev.weixin.qq.com/wiki/index.php?title=AccessToken
        self.get_token()

        self.senddata(body)

        elastalert_logger.info("send message to %s" % (self.corp_id))
示例#30
0
    def alert(self, matches):
        # Override the resource if requested
        if self.use_qk_as_resource and 'query_key' in self.rule and lookup_es_key(matches[0], self.rule['query_key']):
            self.resource = lookup_es_key(matches[0], self.rule['query_key'])

        headers = {'content-type': 'application/json'}
        if self.api_key is not None:
            headers['Authorization'] = 'Key %s' % (self.rule['alerta_api_key'])
        alerta_payload = self.get_json_payload(matches[0])

        try:
            response = requests.post(self.url, data=alerta_payload, headers=headers, verify=self.verify_ssl)
            response.raise_for_status()
        except RequestException as e:
            raise EAException("Error posting to Alerta: %s" % e)
        elastalert_logger.info("Alert sent to Alerta")
    def alert(self, matches):

        if not self.party_id and not self.user_id and not self.tag_id:
            elastalert_logger.warn("All touser & toparty & totag invalid")

        # 参考elastalert的写法
        # https://github.com/Yelp/elastalert/blob/master/elastalert/alerts.py#L236-L243
        body = self.create_alert_body(matches)

        #matches 是json格式
        #self.create_alert_body(matches)是String格式,详见 [create_alert_body 函数](https://github.com/Yelp/elastalert/blob/master/elastalert/alerts.py)

        # 微信企业号获取Token文档
        # http://qydev.weixin.qq.com/wiki/index.php?title=AccessToken
        self.get_token()

        self.senddata(body)

        elastalert_logger.info("send message to %s" % (self.corp_id))
    def senddata(self, content):

        #如果需要原始json,需要传入matches

        # http://qydev.weixin.qq.com/wiki/index.php?title=%E6%B6%88%E6%81%AF%E7%B1%BB%E5%9E%8B%E5%8F%8A%E6%95%B0%E6%8D%AE%E6%A0%BC%E5%BC%8F
        # 微信企业号有字符长度限制(2048),超长自动截断

        # 参考 http://blog.csdn.net/handsomekang/article/details/9397025
        #len utf8 3字节,gbk2 字节,ascii 1字节
        if len(content) > 2048:
            content = content[:2045] + "..."

        # 微信发送消息文档
        # http://qydev.weixin.qq.com/wiki/index.php?title=%E6%B6%88%E6%81%AF%E7%B1%BB%E5%9E%8B%E5%8F%8A%E6%95%B0%E6%8D%AE%E6%A0%BC%E5%BC%8F
        send_url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=%s' %( self.access_token)

        headers = {'content-type': 'application/json'}

        #最新微信企业号调整校验规则,tagid必须是string类型,如果是数字类型会报错,故而使用str()函数进行转换
        payload = {
            "touser": self.user_id and str(self.user_id) or '', #用户账户,建议使用tag
            "toparty": self.party_id and str(self.party_id) or '', #部门id,建议使用tag
            "totag": self.tag_id and str(self.tag_id) or '', #tag可以很灵活的控制发送群体细粒度。比较理想的推送应该是,在heartbeat或者其他elastic工具自定义字段,添加标签id。这边根据自定义的标签id,进行推送
            'msgtype': "text",
            "agentid": self.agent_id,
            "text":{
                "content": content.encode('UTF-8') #避免中文字符发送失败
               },
            "safe":"0"
        }

        # set https proxy, if it was provided
        # 如果需要设置代理,可修改此参数并传入requests
        # proxies = {'https': self.pagerduty_proxy} if self.pagerduty_proxy else None
        try:
            response = requests.post(send_url, data=json.dumps(payload, ensure_ascii=False), headers=headers)
            response.raise_for_status()
        except RequestException as e:
            raise EAException("send message has error: %s" % e)

        elastalert_logger.info("send msg and response: %s" % response.text)