Beispiel #1
0
def run(username, password, room, fritzbox):
    logging.debug("Started at %s", datetime.now().isoformat())
    bot = JabberBot(username, password)

    telnet = Telnet(fritzbox, '1012')

    while True:
        # ugly, but seems to be the only way to stay on
        bot.join_room(room)
        logging.debug("Loop started at %s", datetime.now().isoformat())
        data = telnet.read_until('SIP0;', 300)
        number = '\n'.join(only_number.findall(data))
        if number:
            logging.debug("Sending a message at %s",
                          datetime.now().isoformat())
            bot.send(room, "Call from " + number, message_type='groupchat')
        else:
            what = bot.conn.Process(1)
            if what != '0' and what != None:
                logging.debug("What is this %s", what)
            elif what == None:
                logging.debug("Reconnecting")
                bot.conn.reconnectAndReauth()
Beispiel #2
0
from jabberbot import JabberBot
import random
import sys
import os
import time

# what is my account
username = '******'
# what is the password for that account
password = ''
# what is the account which should receive the messages
remotebot = '*****@*****.**'
# time between two updates in seconds
sleeptime = 60
# we are working via ping - so what should i ping?
# default sould be slotmachine (printerserver)
pinghost = "10.0.1.10"
# command to send to the remote bot if everything is fine
cmdfine = "setoffen"
# command to send to the remote bot if encountering a problem
cmdfail = "setzu"

########### END CONFIG

tmp = os.system("ping -c 1 " + pinghost)
bot = JabberBot(username, password)
if tmp == 0:
    bot.send(remotebot, cmdfine)
else:
    bot.send(remotebot, cmdfail)
Beispiel #3
0
def main():
    logger.info("Daemon 'Attractor' started...")

    if useMySQL:
        import MySQLdb

    # Создаем сокет для приема метрик
    tcps = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # Переводим сокет в неблокирующий режим и задаем опции для более быстрого освобождения ресурсов
    tcps.setblocking(0)
    tcps.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    tcps.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,
                    struct.pack('ii', 1, 0))

    clients = []  # список клиентов (входящих соединений)
    events_raw = ''  # сырые данные, принятые при очередном цикле
    metrics_storage = {
    }  # хранилище метрик, сюда складываются обработанные метрики со счетчиками

    # Пробуем открыть сокет
    try:
        tcps.bind((interface_ip, port))
    # Обрабатываем возможную ошибку сокета (сокет уже занят), делаем запись в лог и ноги :):
    except socket.error as err:
        logger.error("Socket Error: {}. Exiting...".format(err.args[1]))
        tcps.close()
        sys.exit(2)
    else:
        # При отсутствии ошибок начинаем прослушивать порт
        tcps.listen(2)

    # Пробуем подключиться к Jabber
    jbot_ok = False  # флаг, живо ли соединение с Jabber
    if useJabber:
        # jid - JID, jps - password, jcr - chat room, jnn - nickname
        jbot = JabberBot(jid, jps, jcr, jnn)
        if jbot.connect():
            if jbot.auth():
                jbot.joinroom()
                jbot_ok = True
                logger.info("Connection to Jabber '{}' established!".format(
                    jid.split("@")[1]))
            else:
                logger.error("ERROR (Jabber): Can't log ID '{}'!".format(
                    jid.split("@")[0]))
        else:
            logger.error("ERROR (Jabber): Can't connect to '{}'!".format(
                jid.split("@")[1]))

    try_mysql = True  # флаг, нужно ли пробовать открыть новое соединение с MySQL
    recog_events = 0  # счетчик распознанных событий (события которые были преобразованы в формат Attractor)
    triggered_events = 0  # счетчик сработавших условий
    timer = int(time.time()
                )  # время начала основного цикла программы (циклы по 5 секунд)
    timer_last_data = int(
        time.time())  # время получения последних данных при опросе сокета
    pause_ratio = 1  # множитель для паузы опроса сокета

    while True:
        events = []  # список всех распознанных событий

        # Каждые 5 секунд проверяем список клиентов и полученные события
        if int(time.time()) - timer >= 5:
            timer = int(time.time())

            # Убираем из списка неактивных клиентов
            for client in clients:
                try:
                    client.getpeername()
                except:
                    clients.remove(client)

            if useJabber:
                # Если подключение к Jabber не живо, то пробуем переподключиться
                if not jbot.is_alive:
                    jbot_ok = False
                    logger.info(
                        "WARNING: Not connected to Jabber! Trying to reconnect..."
                    )
                    if jbot.connect():
                        if jbot.auth():
                            jbot.joinroom()
                            jbot_ok = True
                            logger.info(
                                "Reconnection to Jabber '{}' established!".
                                format(jid.split("@")[1]))
                        else:
                            logger.error(
                                "ERROR (Jabber): Can't log ID '{}'!".format(
                                    jid.split("@")[0]))
                    else:
                        logger.error(
                            "ERROR (Jabber): Can't connect to '{}'!".format(
                                jid.split("@")[1]))
                if jbot_ok:
                    jbot.proc()

        jCount = 0  # счетчик сообщений, которые должны быть отправлены в Jabber
        external_requests_count = 0  # счетчик сообщений, которые должны быть отправлены путем запроса на внешний URL
        telegram_events_count = 0  # счетчик событий, которые должны быть отправлены в Telegram
        external_scripts_count = 0  # счетчик событий, которые должны быть отправлены во внешние скрипты

        # Пробуем принять подключение
        try:
            connect, addr = tcps.accept()
        except:
            pass
        else:
            # Переводим сокет в неблокирующий режим и говорим, чтобы при отключении освобождался
            # быстрее (no linger) и добавляем в список
            connect.setblocking(0)
            connect.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER,
                               struct.pack('ii', 1, 0))
            clients.append(connect)

        # Пробуем получить данные с сокета, перебирая всех клиентов
        for client in clients:
            try:
                data = client.recv(512)
            # Если данных нет возникнет ошибка, это нормально, ничего не трогаем
            except:
                pass
            else:
                # Если клиент отключился, то recv вернет пустую строку. Закроем такой сокет.
                if data == '':
                    client.close()
                # Складываем вместе данные, оставшиеся с прошлой обработки (могут быть пустыми), вместе с полученными
                events_raw = events_raw + data
                timer_last_data = int(time.time())
                # Если данные поступают, начинаем опрашивать сокет чаще путем уменьшения интервала ожидания
                pause_ratio = 0.01

        # Если истек интервал ожидания данных и сами данные не пустые, начинаем их обрабатывать
        if (int(time.time()) - timer_last_data >=
                nodata_int) & (len(events_raw) > 0):
            # Возвращаем прежнее значение коэффициента паузы для ожидания данных
            pause_ratio = 1
            # Необработанные данные преобразываются в список.
            # Если элемент списка удается преобразовать в словарь, значит получено валидное событие.
            tmp_events = events_raw.split("\n")
            for ev_item in tmp_events:
                # Пробуем преобразовать данные в словарь
                event = graphite2attractor(ev_item)
                if event:
                    events.append(event)
                    recog_events += 1
                else:
                    if ev_item != '':
                        logger.error("WARNING! Unknown data format: %s",
                                     ev_item)
            del tmp_events
            events_raw = ''
            # Проверяем, получены ли новые события
            if recog_events > 0:
                logger.info(
                    "New events are recieved. Recognized {} entries.".format(
                        recog_events))
                recog_events = 0
            # Пробуем подключиться к MySQL. Используем таймаут в 1 секунду
            if useMySQL and try_mysql:
                try:
                    mysql_conn = MySQLdb.connect(host=mysql_addr,
                                                 user=mysql_user,
                                                 passwd=mysql_pass,
                                                 db=mysql_base,
                                                 charset=mysql_cset,
                                                 connect_timeout=1)
                    mysql_conn.autocommit(True)
                except:
                    logger.error('ERROR (MySQL): Cannot connect to server. :(')
                else:
                    logger.info(
                        "Connection to MySQL Server '{}' (Write) established".
                        format(mysql_addr))
                    # Создаем 'курсор'. (Особая MySQLdb-шная магия)
                    mysql_cr = mysql_conn.cursor()
                finally:
                    try_mysql = False
            # Определяем словари, содержащие счетчики событий для MySQL и Oracle Apex
            send_query = {'query': '', 'count': 0, 'total': 0}
            apex_query = {'query': '', 'count': 0, 'total': 0}

            # Обработка событий
            for event in events:
                if event['metric'] in event_horizon:
                    # Полное имя полученной метрики
                    r_metricname = get_processed_str(MetricNameTemplate, event)
                    # Пробуем получить предыдущее значение метрики
                    # Важно: Использование try..except работает существенно быстрее,
                    # чем предварительный поиск ключа. Именно поэтому здесь так.
                    try:
                        last_val = metrics_storage[r_metricname]['lastval']
                    except:
                        last_val = '0'
                    test_metric = check_metric_terms(
                        metrics_storage, event, r_metricname,
                        event_horizon[event['metric']]['terms'], last_val)
                    tmp_trig, tmp_skip, tmp_reset, tmp_code = check_metric_counters(
                        metrics_storage, r_metricname, test_metric,
                        event_horizon[event['metric']]['trigger'],
                        event_horizon[event['metric']]['skip'],
                        event_horizon[event['metric']]['reset'],
                        event_horizon[event['metric']]['code'])

                    # Обновляем хранилище метрик, записывая туда временные значения счетчик срабатывания
                    # условий и счетчика пропусков
                    metrics_storage[r_metricname] = {
                        'lastval': event['value'],
                        'trigger': tmp_trig,
                        'skip': tmp_skip,
                        'reset': tmp_reset
                    }
                    if (tmp_code > 0) & (tmp_code in event_codes):
                        triggered_events += 1
                        if useJabber and jbot_ok and (event['metric']
                                                      in JabberMetricsList):
                            try:
                                jbot.send_msg(
                                    get_processed_str(event_codes[tmp_code],
                                                      event))
                            except:
                                logger.error(
                                    "ERROR (Jabber): Cannot send data to Jabber!"
                                )
                            jCount += 1
                        if useTelegram and (event['metric']
                                            in telegram_metrics):
                            send_msg_to_telegram(
                                get_processed_str(event_codes[tmp_code],
                                                  event))
                            telegram_events_count += 1
                        if use_external_urls and (
                                event['metric'] in external_requests_metrics):
                            make_external_requests(
                                get_processed_str(event_codes[tmp_code],
                                                  event), event['host'])
                            external_requests_count += 1
                        if use_external_scripts and (
                                event['metric'] in external_scripts_metrics):
                            call_external_scripts(event)
                            external_scripts_count += 1
                        if useMySQL:
                            if send_query['count'] == 0:
                                send_query['query'] = """INSERT INTO {0}.{1} (
                                    {1}.device, {1}.host, {1}.metric, {1}.key, {1}.value, {1}.event_code,
                                    {1}.event_text, {1}.datetime) 
                                    VALUES """.format(mysql_base, mysql_tabl)
                            send_query[
                                'query'] += "('{0}','{1}','{2}','{3}','{4}',{5},'{6}','{7}'),".format(
                                    event['device'], event['host'],
                                    event['metric'], event['key'],
                                    event['value'], tmp_code,
                                    get_processed_str(event_codes[tmp_code],
                                                      event), int(time.time()))
                            send_query['count'] += 1
                            if send_query['count'] >= mysql_chain_len:
                                if post_data_to_mysql(
                                        mysql_cr, send_query['query'][:-1]):
                                    send_query['total'] += send_query['count']
                                send_query['count'] = 0
                                send_query['query'] = ''
                        if useOracleApex:
                            if apex_query['count'] == 0:
                                apex_query[
                                    'query'] = apex_url + apex_cmd.encode(
                                        "hex")
                            apex_query['query'] += (
                                "SELECT {},{},'{}','{}','{}','{}','{}' FROM dual UNION ALL "
                                .format(int(time.time()), tmp_code,
                                        event['key'], event['value'],
                                        event['metric'], event['host'],
                                        event['device'])).encode("hex")
                            apex_query['count'] += 1
                            if apex_query['count'] >= apex_chain_len:
                                if post_data_to_oracle_apex(
                                        apex_query['query'][:-22]):
                                    apex_query['total'] += apex_query['count']
                                apex_query['count'] = 0
                                apex_query['query'] = ''
            # Проверяем, осталось ли что-то в буфере для MySQL. Если да - отправляем. После этого отключаемся от MySQL
            if useMySQL:
                if send_query['count'] > 0:
                    if post_data_to_mysql(mysql_cr, send_query['query'][:-1]):
                        send_query['total'] += send_query['count']
                try:
                    mysql_conn.close()
                except:
                    pass
                finally:
                    try_mysql = True
            # Проверяем, осталось ли что-то в буфере для Oracle Apex. Если да - отправляем
            if useOracleApex:
                if apex_query['count'] > 0:
                    if post_data_to_oracle_apex(apex_query['query'][:-22]):
                        apex_query['total'] += apex_query['count']

            # Проверяем, есть ли события, для которых достигнуто необходимое количество срабатываний
            if triggered_events > 0:
                logger.info("WARNING: New alerts triggered: {}.".format(
                    triggered_events))
                triggered_events = 0
            # Пишем в лог сколько записей мы отправили в Jabber, MySQL и Orale Apex
            logger.info(
                "Alerts sended to Jabber: {}, to MySQL: {}, to Oracle Apex: {}, to external URLs: {},"
                " to external scripts: {}, to Telegram: {}".format(
                    jCount, send_query['total'], apex_query['total'],
                    external_requests_count, external_scripts_count,
                    telegram_events_count))
            # Пишем в лог о завершении обработки
            logger.info("All events have been processed.")
            logger.info("-------")
        time.sleep(sleep_int * pause_ratio)