Page_c76a3fcf https://linux-notes.org Unix/ Linux блог, на котором можно найти полезную информацию по настройке ОС и ПО. Mon, 11 Jun 2018 16:15:56 +0000 ru-RU hourly 1 https://wordpress.org/?v=6.7.2 Page_c76a3fcf https://linux-notes.org/upravlenie-polzovateljami-v-grafana-cherez-python/ https://linux-notes.org/upravlenie-polzovateljami-v-grafana-cherez-python/#respond Mon, 11 Jun 2018 16:15:56 +0000 http://linux-notes.org/?p=15620 Управление пользователями в Grafana через Python Когда-то писал скрипт для работы с пользователями в Grafana. Нашел немного времени чтобы поделится данным скриптом с миром. Не всегда есть время, но желание и материал всегда имеется! И так, приступим… Полезное чтиво: Установка grafana в Unix/Linux Настройка Grafana с Graphite/Zabbix/Prometheus/MySQL/InfluxDB/Elasticsearch/CloudWatch для сбора и отображения метрик в Unix/Linux Экспорт […]

The post Управление пользователями в Grafana через Python first appeared on linux-notes.org.]]>

Управление пользователями в Grafana через Python

Когда-то писал скрипт для работы с пользователями в Grafana. Нашел немного времени чтобы поделится данным скриптом с миром. Не всегда есть время, но желание и материал всегда имеется! И так, приступим…

Полезное чтиво:

Установка grafana в Unix/Linux

Настройка Grafana с Graphite/Zabbix/Prometheus/MySQL/InfluxDB/Elasticsearch/CloudWatch для сбора и отображения метрик в Unix/Linux

Экспорт дашбордов из grafana в Unix/Linux

Собственно, катаю скрипт:

$ cat work_with_users_in_grafana.py

Скрипт содержит:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import requests
import time
import argparse
import json


class Bgcolors:
    def __init__(self):
        self.get = {
            'HEADER': '\033[95m',
            'OKBLUE': '\033[94m',
            'OKGREEN': '\033[92m',
            'WARNING': '\033[93m',
            'FAIL': '\033[91m',
            'ENDC': '\033[0m',
            'BOLD': '\033[1m',
            'UNDERLINE': '\033[4m'
        }


def search_grafana_user(gurl, g_user, g_password, email):
    g_protocol = gurl.split(':')[0]
    g_url = gurl.split('//')[1]

    get_data_req = requests.get(
        g_protocol + '://' + g_user + ':' + g_password + '@' + g_url + '/api/users?perpage=10&page=1')
    pars_json = json.loads(get_data_req.text)
    for user in pars_json:
        if user['email'] == email:
            account_id = user['id']
        else:
            account_id = -1

    return account_id


def get_grafana_users(gurl, g_user, g_password):
    users_array = []

    g_protocol = gurl.split(':')[0]
    g_url = gurl.split('//')[1]

    get_data_req = requests.get(g_protocol + '://' + g_user + ':' + g_password + '@' + g_url + '/api/users')
    pars_json = json.loads(get_data_req.text)
    for user in pars_json:
        users_array.append(user['email'])
        # print (user)

    return users_array


def add_grafana_user(gurl, g_user, g_password, created_email, created_password):
    g_protocol = gurl.split(':')[0]
    g_url = gurl.split('//')[1]

    grafana_users = get_grafana_users(gurl, g_user, g_password)
    for user in grafana_users:
        if user == created_email:
            print(Bgcolors().get['FAIL'] + 'User already exist: ', user, '\nUse another name!' + Bgcolors().get['ENDC'])
            exit(0)
    data = {"name": created_email,
            "email": created_email,
            "login": created_email,
            "password": created_password,
            }

    get_data_req = requests.post(g_protocol + '://' + g_user + ':' + g_password + '@' + g_url + '/api/admin/users',
                                 data)
    pars_json = json.loads(get_data_req.text)
    print(pars_json)
    print('URL: ' + gurl, '\nemail: ' + created_email, '\npassword: ' + created_password)

    return add_grafana_user


def update_grafana_users(gurl, g_user, g_password, email):
    g_protocol = gurl.split(':')[0]
    g_url = gurl.split('//')[1]

    state_of_admin = str.lower('True')
    data_put = {"Accept": "application/json",
                "Content-Type": "application/json",
                "isGrafanaAdmin": state_of_admin,
                }

    account_id = search_grafana_user(gurl, g_user, g_password, email)
    if account_id != -1:
        get_data_req = requests.put(
            g_protocol + '://' + g_user + ':' + g_password + '@' + g_url + '/api/admin/users/%s/permissions' % account_id,
            data=data_put)
        pars_json = json.loads(get_data_req.text)
        print(pars_json)

        get_data_req = requests.get(
            g_protocol + '://' + g_user + ':' + g_password + '@' + g_url + '/api/users?perpage=10&page=1')
        pars_json = json.loads(get_data_req.text)
        for user in pars_json:
            if user['email'] == email:
                print(user)
    else:
        print('Unfortunately, I cant find [%s] email in grafana to update role!' % email)
        print('Please, use current EMAIL!')
        exit(0)

    return update_grafana_users


def update_grafana_user_password(gurl, g_user, g_password, email):
    g_protocol = gurl.split(':')[0]
    g_url = gurl.split('//')[1]

    data_put = {"password": "password"}
    account_id = search_grafana_user(gurl, g_user, g_password, email)
    if account_id != -1:
        get_data_req = requests.put(
            g_protocol + '://' + g_user + ':' + g_password + '@' + g_url + '/api/admin/users/%s/password' % account_id,
            data=data_put)
        pars_json = json.loads(get_data_req.text)
        print(pars_json)

    else:
        print('Unfortunately, I cant find [%s] email in grafana to update PW!' % email)
        print('Please, use current EMAIL!')
        exit(0)

    return update_grafana_users


def delete_grafana_users(gurl, g_user, g_password, email):
    g_protocol = gurl.split(':')[0]
    g_url = gurl.split('//')[1]

    account_id = search_grafana_user(gurl, g_user, g_password, email)
    get_data_req = requests.delete(
        g_protocol + '://' + g_user + ':' + g_password + '@' + g_url + '/api/admin/users/%s' % account_id)
    pars_json = json.loads(get_data_req.text)
    print(pars_json)

    get_data_req = requests.get(g_protocol + '://' + g_user + ':' + g_password + '@' + g_url + '/api/users')
    pars_json = json.loads(get_data_req.text)
    for user in pars_json:
        print(user)

    return update_grafana_users


def main():
    start__time = time.time()
    parser = argparse.ArgumentParser(prog='python3 script_name.py -h',
                                     usage='python3 script_name.py {ARGS}',
                                     add_help=True,
                                     prefix_chars='--/',
                                     epilog='''created by Vitalii Natarov''')
    parser.add_argument('--version', action='version', version='v1.0.5')
    parser.add_argument('--gtoken', '--token', dest='gtoken', help='Token of grafana server', default=None)
    parser.add_argument('--gurl', '--url', dest='gurl', help='URL from grafana', default=None)
    parser.add_argument('--glogin', dest='glogin', help='A login to grafana', default=None)
    parser.add_argument('--gpassword', dest='gpassword', help='A password of grafana user', default=None)
    parser.add_argument('--email', dest='email', help='A email to create a new user in grafana', default=None)
    parser.add_argument('--password', dest='password', help='A password of grafana user which need to create',
                        default=None)

    group = parser.add_mutually_exclusive_group(required=False)
    group.add_argument('--show', dest='show', help='Show grafana users', action='store_true')
    group.add_argument('--s', dest='show', help='Show grafana users', action='store_true')

    group2 = parser.add_mutually_exclusive_group(required=False)
    group2.add_argument('--add', dest='add', help='Add grafana user', action='store_true')
    group2.add_argument('--a', dest='add', help='Add grafana user', action='store_true')

    group3 = parser.add_mutually_exclusive_group(required=False)
    group3.add_argument('--update', dest='update', help='Update grafana user', action='store_true')
    group3.add_argument('--u', dest='update', help='Update grafana user', action='store_true')

    group4 = parser.add_mutually_exclusive_group(required=False)
    group4.add_argument('--cpassword', dest='changepassword', help='Change grafana user PW', action='store_true')
    group4.add_argument('--changepw', dest='changepassword', help='Change grafana user PW', action='store_true')

    group5 = parser.add_mutually_exclusive_group(required=False)
    group5.add_argument('--delete', dest='delete', help='Delete grafana user', action='store_true')
    group5.add_argument('--d', dest='delete', help='Delete grafana user', action='store_true')

    results = parser.parse_args()
    grafana_url = results.gurl
    grafana_login = results.glogin
    grafana_password = results.gpassword
    user_email = results.email
    user_password = results.password

    if results.add:
        if (grafana_url is not None) and (user_email is not None) and (user_password is not None):
            add_grafana_user(grafana_url, grafana_login, grafana_password, user_email, user_password)
        else:
            print('Please add [--gurl] or [--email] or [--password]')
            print('For help, use: script_name.py -h')
            exit(0)

    elif results.update:
        if user_email is not None:
            update_grafana_users(grafana_url, grafana_login, grafana_password, user_email)
        else:
            print('Please add [--gurl] or [--email]')
            print('For help, use: script_name.py -h')
            exit(0)

    elif results.changepassword:
        if user_email is not None:
            update_grafana_user_password(grafana_url, grafana_login, grafana_password, user_email)
        else:
            print('Please add [--gurl] or [--email]')
            print('For help, use: script_name.py -h')
            exit(0)
    elif results.delete:
        if user_email is not None:
            delete_grafana_users(grafana_url, grafana_login, grafana_password, user_email)
        else:
            print('Please add [--gurl] or [--email]')
            print('For help, use: script_name.py -h')
            exit(0)
    elif results.show:
        if (grafana_url is not None) and (grafana_login is not None) and (grafana_password is not None):
            # print(get_grafana_users(grafana_url, grafana_login, grafana_password))
            users = get_grafana_users(grafana_url, grafana_login, grafana_password)
            for user in users:
                print(user)
        else:
            print('Please add [--gurl] or [--email] or [--password]')
            print('For help, use: script_name.py -h')
            exit(0)
    else:
        print('For help, use: script_name.py -h')
        exit(0)

    end__time = round(time.time() - start__time, 2)
    print("--- %s seconds ---" % end__time)

    print(
        Bgcolors().get['OKGREEN'], "============================================================",
        Bgcolors().get['ENDC'])
    print(
        Bgcolors().get['OKGREEN'], "==========================FINISHED==========================",
        Bgcolors().get['ENDC'])
    print(
        Bgcolors().get['OKGREEN'], "============================================================",
        Bgcolors().get['ENDC'])


if __name__ == '__main__':
    main()

Для помощи можно воспользоватся следующей командой:

$ work_with_users_in_grafana.py -h

usage: python3 script_name.py {ARGS}

optional arguments:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  --gtoken GTOKEN, --token GTOKEN
                        Token of grafana server
  --gurl GURL, --url GURL
                        URL from grafana
  --glogin GLOGIN       A login to grafana
  --gpassword GPASSWORD
                        A password of grafana user
  --email EMAIL         A email to create a new user in grafana
  --password PASSWORD   A password of grafana user which need to create
  --show                Show grafana users
  --s                   Show grafana users
  --add                 Add grafana user
  --a                   Add grafana user
  --update              Update grafana user
  --u                   Update grafana user
  --cpassword           Change grafana user PW
  --changepw            Change grafana user PW
  --delete              Delete grafana user
  --d                   Delete grafana user

created by Vitalii Natarov

Собственно, скрипт умеет:

  • —show — Показывает всех пользователей графана.
  • —add — Добавляет пользователя.
  • —update — Обновляет роль (пока не работает)….
  • —cpassword — Служит функцией для смены пароля.
  • — delete — Удаляет пользователя.
$ python3 work_with_users_in_grafana.py --gurl="https://grafana.local" --glogin "grafana_login" --gpassword "grafana_password" --add --email="vnatarov@ololo.com" --password="my_passWD"

Кому будет не понятно как использовать или возникнут ошибки, — пишите в комментариях, помогу. Я по мере необходимости, переписываю куски кода во всех моих скриптах и всегда обновляю материал на сайте.

Вот и все, статья «Управление пользователями в Grafana через Python» завершена.

The post Управление пользователями в Grafana через Python first appeared on linux-notes.org.]]>
https://linux-notes.org/upravlenie-polzovateljami-v-grafana-cherez-python/feed/ 0
Page_c76a3fcf https://linux-notes.org/sozdanie-autodiscovery-pravil-v-zabbix/ https://linux-notes.org/sozdanie-autodiscovery-pravil-v-zabbix/#respond Fri, 08 Jun 2018 16:23:10 +0000 http://linux-notes.org/?p=15610 Создание autodiscovery правил в Zabbix У меня на работе, появилась очередная задача — добавлять дискавери правила для обнаружения машин. Руками делать — это хорошо, но с каждым разом напрягает. Тем более, сейчас все больше наберает оборты «Monitoring as Code» и по этом — пришло время — автоматизировать хоть что-то. Вообще, данный скрипт я писал для […]

The post Создание autodiscovery правил в Zabbix first appeared on linux-notes.org.]]>

Создание autodiscovery правил в Zabbix

У меня на работе, появилась очередная задача — добавлять дискавери правила для обнаружения машин. Руками делать — это хорошо, но с каждым разом напрягает. Тем более, сейчас все больше наберает оборты «Monitoring as Code» и по этом — пришло время — автоматизировать хоть что-то. Вообще, данный скрипт я писал для своих нужд, но 2 дня назад ко мне пришли и сказали что у нас фигня на ПРОДе и нужно все переделать. Я прикинул, что оно все однотипное, и к тому-же у меня завалялся скрипт. Этим скриптом, я ократил время ручной работы, часа на 2-3.

Для этой цели, я создал скрипт:

# cat add_discoveryrules_to_zabbix.py

Который имеет следующее содержание:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import requests
import argparse
import time

from datetime import datetime
from pyzabbix import ZabbixAPI


class Bgcolors:
    def __init__(self):
        self.get = {
            'HEADER': '\033[95m',
            'OKBLUE': '\033[94m',
            'OKGREEN': '\033[92m',
            'WARNING': '\033[93m',
            'FAIL': '\033[91m',
            'ENDC': '\033[0m',
            'BOLD': '\033[1m',
            'UNDERLINE': '\033[4m'
        }


def get_time():
    timestamp = datetime.fromtimestamp(int(time.mktime(datetime.now().timetuple()))).strftime('%d-%m-%Y-%H_%M')
    print (timestamp)
    return get_time


def login_to_zabbix(url, user, password):
    # You can use the connection__timeout
    connection__timeout = 45
    # Verify SSL
    verify__ssl = False
    # Connect to zabbix-server
    zapi = ZabbixAPI(url, timeout=connection__timeout)
    zapi.session.verify = verify__ssl
    if not verify__ssl:
        from requests.packages.urllib3.exceptions import InsecureRequestWarning
        requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
    zapi.login(user, password)
    zapi.session.auth = (user, password)
    # You can re-define connection__timeout after
    zapi.timeout = connection__timeout
    return zapi


def get_needed_groups(z_host, z_user, z_password, z_groups):
    needed_groups = []
    zapi = login_to_zabbix(z_host, z_user, z_password)

    if z_groups is not None:
        get_groups = zapi.hostgroup.get(filter={"name": z_groups}, output=['groupid', 'name'])
        for group_name in get_groups:
            needed_groups.append(group_name)
    else:
        print(Bgcolors().get['FAIL'], 'Please set/add [--group]', Bgcolors().get['ENDC'])
        print(Bgcolors().get['OKGREEN'], 'For help, use: script_name.py -h', Bgcolors().get['ENDC'])
        exit(0)

    return needed_groups


def get_needed_templates(z_host, z_user, z_password, z_templates):
    needed_templates = []
    zapi = login_to_zabbix(z_host, z_user, z_password)

    if z_templates is not None:
        get_templates = zapi.template.get(filter={"name": z_templates}, output=['templateid', 'name'])
        for template in get_templates:
            needed_templates.append(template)
    else:
        print(Bgcolors().get['FAIL'], 'Please set/add [--template]', Bgcolors().get['ENDC'])
        print(Bgcolors().get['OKGREEN'], 'For help, use: script_name.py -h', Bgcolors().get['ENDC'])
        exit(0)

    return needed_templates


def get_needed_discoveryrules(z_host, z_user, z_password, discoveryrule_name):
    discoveryrules = []
    zapi = login_to_zabbix(z_host, z_user, z_password)
    get_discoveryrules = zapi.action.get(search={"name": discoveryrule_name}, output=['actionid', 'name'])
    if len(get_discoveryrules) is not 0:
        for discoveryrule in get_discoveryrules:
            discoveryrules.append(discoveryrule['name'])
    else:
        discoveryrules.append('None')

    return discoveryrules


def create_group(z_host, z_user, z_password, z_groups):
    zapi = login_to_zabbix(z_host, z_user, z_password)
    for group in z_groups:
        get_group = zapi.hostgroup.get(filter={"name": group}, output=['groupid', 'name'])
        if len(get_group) is 0:
            zapi.hostgroup.create({"name": group})
            print(Bgcolors().get['OKGREEN'], 'Group: [' + group + '] has been created', Bgcolors().get['ENDC'])
        else:
            print(Bgcolors().get['FAIL'], 'Group already exist: ' + group, Bgcolors().get['ENDC'])

    return create_group


def create_discoveryrule(z_host, z_user, z_password, z_groups, z_templates, z_rule_name, z_conditions, z_formula):
    zapi = login_to_zabbix(z_host, z_user, z_password)
    groups = get_needed_groups(z_host, z_user, z_password, z_groups)
    templates = get_needed_templates(z_host, z_user, z_password, z_templates)

    if len(groups) is 0:
        print(Bgcolors().get['FAIL'], 'Group(s) do/does not exist in Zabbix!', Bgcolors().get['ENDC'])
        print('Set the following groups: ', z_groups)
        exit(0)
    else:
        groups_array = []
        for group in groups:
            g_id = group['groupid']
            g = {"groupid": g_id}
            groups_array.append(g)

    if len(templates) is 0:
        print(Bgcolors().get['FAIL'], 'Template(s) do/does not exist in Zabbix!', Bgcolors().get['ENDC'])
        print(z_templates)
        exit(0)
    else:
        templates_array = []
        for template in templates:
            t_id = template['templateid']
            t = {"templateid": t_id}
            templates_array.append(t)

    if z_conditions is None:
        print(Bgcolors().get['FAIL'], 'Please set/add [--condition]', Bgcolors().get['ENDC'])
        print(Bgcolors().get['OKGREEN'], 'For help, use: script_name.py -h', Bgcolors().get['ENDC'])
        exit(0)
    else:
        conditions_array = []
        formula_ids_array = []
        formula_ids = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
                       'T', 'U', 'V', 'W', 'X', 'Y', 'Z']

        i = 0
        while i < len(z_conditions):
            conditions = {
                "conditiontype": 24,
                "operator": '2',
                "value": str(z_conditions[i]),
                "formulaid": str(formula_ids[i]),
                }
            conditions_array.append(conditions)
            formula_ids_array.append(formula_ids[i])
            i += 1

    if z_formula is None:
        formula = " and ".join(formula_ids_array)
    else:
        formula = z_formula

    action_status = {'turn_on': '0', 'turn_off': '1'}
    eventsource = {'trigger': '0', 'discovery_rule': '1', 'auto_registration': '2', 'internal_event': '3'}
    evaltype = {'AND/OR': '0', 'AND': '1', 'OR': '2', 'CUSTOM': '3'}

    if z_rule_name is None:
        product = 'PRODUCT'
        env = 'ENV'
        color = ''
        service = 'SERVICE-test'
        if color is '':
            discovery_rule_name = 'ADD_%s_%s_%s' % (product, env, service)
        else:
            discovery_rule_name = 'ADD_%s_%s_%s_%s' % (product, env, color, service)
    else:
        discovery_rule_name = z_rule_name
    found_discoveryrules = get_needed_discoveryrules(z_host, z_user, z_password, discovery_rule_name)
    if found_discoveryrules[0] is not 'None':
        print(
            Bgcolors().get['FAIL'], 'Please use another name for discovery rule',
            Bgcolors().get['ENDC'])
        print('I have found the following occurrences:')
        print(Bgcolors().get['OKGREEN'], found_discoveryrules, Bgcolors().get['ENDC'])
        exit(0)
    else:
        rules = {
            "name": discovery_rule_name,
            "eventsource": eventsource['auto_registration'],
            "status": action_status['turn_on'],
            "esc_period": '0',
            "def_shortdata": 'Auto registration: {HOST.HOST}',
            "def_longdata": 'Host name: {HOST.HOST}\r\nHost IP: {HOST.IP}\r\nAgent port: {HOST.PORT}',
            "recovery_msg": '0',
            "r_shortdata": '',
            "filter": {
                "evaltype": evaltype['CUSTOM'],
                "formula": formula,
                "conditions": conditions_array,
            },
            "operations": [
                {
                    "operationtype": '2',
                    "esc_step_from": '1',
                    "esc_step_to": '1',
                    "esc_period": '0',
                    "evaltype": '0',
                    "opconditions": [],
                },
                {
                    "esc_step_from": '1',
                    "esc_period": '0',
                    "operationtype": '4',
                    "esc_step_to": '1',
                    "opconditions": [],
                    "opgroup": groups_array,
                },
                {
                    "esc_step_from": '1',
                    "esc_period": '0',
                    "operationtype": '6',
                    "esc_step_to": '1',
                    "opconditions": [],
                    "optemplate": templates_array,
                },

            ]
        }
        zapi.action.create(rules)
        print(Bgcolors().get['OKGREEN'],'Discoveryrule [' + discovery_rule_name  + '] has been created',
              Bgcolors().get['ENDC'])
              
    return create_discoveryrule


def main():
    start__time = time.time()
    parser = argparse.ArgumentParser(prog='python3 script_name.py -h',
                                     usage='python3 script_name.py {ARGS}',
                                     add_help=True,
                                     prefix_chars='--/',
                                     epilog='''created by Vitalii Natarov''')
    parser.add_argument('--version', action='version', version='v1.0.0')
    parser.add_argument('--group', nargs='+', dest='group', help='Group name of zabbix', default=None)
    parser.add_argument('--template', nargs='+', dest='template', help='Template name of zabbix', default=None)
    parser.add_argument('--condition', nargs='+', dest='condition', help='Set condition name of zabbix (hostmetadata)',
                        default=None)
    parser.add_argument('--formula', dest='formula', help='Set formula. Default - AND', default=None)
    parser.add_argument('--name', dest='rule_name', help='Set name of zabbix rule', default=None)
    parser.add_argument('--zabbix-host', dest='zabbix_host',
                        help='Zabbix host',
                        default=None)
    parser.add_argument('--zabbix-user', dest='zabbix_user',
                        help='Zabbix user',
                        default=None)
    parser.add_argument('--zabbix-password', dest='zabbix_password',
                        help='Zabbix password of user',
                        default=None)

    group = parser.add_mutually_exclusive_group(required=False)
    group.add_argument('--create-group', dest='create_group', help='Create group in zabbix', action='store_true')
    group.add_argument('--gcreate', dest='create_group', help='Create group in zabbix', action='store_true')

    results = parser.parse_args()
    group_name = results.group
    template_name = results.template
    condition = results.condition
    formula = results.formula
    rule_name = results.rule_name
    # host, login, password to connect to zabbix-server
    zabbix__host = results.zabbix_host
    zabbix__user = results.zabbix_user
    zabbix__password = results.zabbix_password

    if (zabbix__host is not None) and (zabbix__user is not None) and (zabbix__password is not None):
        if results.create_group:
            create_group(zabbix__host, zabbix__user, zabbix__password, group_name)
        else:
            create_discoveryrule(zabbix__host, zabbix__user, zabbix__password, group_name, template_name, rule_name,
                                 condition, formula)
    else:
        print(Bgcolors().get['FAIL'], 'Please set/add [--zabbix-user] or [--zabbix-password]', Bgcolors().get['ENDC'])
        print(Bgcolors().get['OKGREEN'], 'For help, use: script_name.py -h', Bgcolors().get['ENDC'])
        exit(0)
    # get_needed_discoveryrules(zabbix__host, zabbix__user, zabbix__password, 'test')
    # get_needed_templates(zabbix__host, zabbix__user, zabbix__password, group_name)
    # get_needed_groups(zabbix__host, zabbix__user, zabbix__password, group_name)

    end__time = round(time.time() - start__time, 2)
    print("--- %s seconds ---" % end__time)
    print(
        Bgcolors().get['OKGREEN'], "============================================================",
        Bgcolors().get['ENDC'])
    print(
        Bgcolors().get['OKGREEN'], "==========================FINISHED==========================",
        Bgcolors().get['ENDC'])
    print(
        Bgcolors().get['OKGREEN'], "============================================================",
        Bgcolors().get['ENDC'])


if __name__ == '__main__':
    main()

Если его запустить вот так:

(captain@Macbook)─(✓)─(07:16 PM Fri Jun 08)
└─(~)─(19 files, 2312b)─> python3 add_discoveryrules_to_zabbix.py
 Please set/add [--zabbix-user] or [--zabbix-password]
 For help, use: script_name.py -h

┌(captain@Macbook)─(✓)─(07:16 PM Fri Jun 08)
└─(~)─(19 files, 2312b)─>

То выдает подсказки что ему неоходимо. Помощь можно получить:

$ python3 add_discoveryrules_to_zabbix.py --h

usage: python3 script_name.py {ARGS}

optional arguments:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  --group GROUP [GROUP ...]
                        Group name of zabbix
  --template TEMPLATE [TEMPLATE ...]
                        Template name of zabbix
  --condition CONDITION [CONDITION ...]
                        Set condition name of zabbix (hostmetadata)
  --formula FORMULA     Set formula. Default - AND
  --name RULE_NAME      Set name of zabbix rule
  --zabbix-host ZABBIX_HOST
                        Zabbix host
  --zabbix-user ZABBIX_USER
                        Zabbix user
  --zabbix-password ZABBIX_PASSWORD
                        Zabbix password of user
  --create-group        Create group in zabbix
  --gcreate             Create group in zabbix

created by Vitalii Natarov

Наглядный пример как создать группы:

$ python3 add_discoveryrules_to_zabbix.py --create-group "CUSTOMER_PRE-PROD" "CUSTOMER_PRE-PROD_TOMCAT"

После чего, можно запустить создание автодискавери рулов:

$ $ add_discoveryrules_to_zabbix.py --group "CUSTOMER_PRE-PROD" "CUSTOMER_PRE-PROD_TOMCAT" --template "Template_env_CUSTOMER_PRE-PROD" "Template_role_CUSTOMER_SOLR_system" --condition "CUSTOMER_" "_SOLR_system" --name "TEST"

Вроде бы я предусмотрел и на момент использования меня и коллег, не было обнаружено проблем.

Полезные статьи:

Экспортирование zabbix templates

Импортирование zabbix templates

На этом у меня все, статья «Создание autodiscovery правил в Zabbix» завершена.

The post Создание autodiscovery правил в Zabbix first appeared on linux-notes.org.]]>
https://linux-notes.org/sozdanie-autodiscovery-pravil-v-zabbix/feed/ 0
Page_c76a3fcf https://linux-notes.org/jeksport-zabbix-triggers/ https://linux-notes.org/jeksport-zabbix-triggers/#respond Wed, 30 May 2018 18:05:42 +0000 http://linux-notes.org/?p=15591 Экспорт zabbix triggers У меня на работе, появилась задача — выполнить проверку всех имеющихся триггеров в заббиксе + обновить документацию. Я очень ленивый и всегда стараюсь оптимизировать процесс так, чтобы в последующие разы я тратил как можно меньше времени. Так произошло и в этот раз! 🙂 Для этой цели, я создал скрипт: # cat get_triggers.py […]

The post Экспорт zabbix triggers first appeared on linux-notes.org.]]>

Экспорт zabbix triggers

У меня на работе, появилась задача — выполнить проверку всех имеющихся триггеров в заббиксе + обновить документацию. Я очень ленивый и всегда стараюсь оптимизировать процесс так, чтобы в последующие разы я тратил как можно меньше времени. Так произошло и в этот раз! 🙂

Для этой цели, я создал скрипт:

# cat get_triggers.py

Который имеет следующее содержание:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import requests
import argparse
import time
import os

from datetime import datetime
from pyzabbix import ZabbixAPI
from pathlib import Path


class Bgcolors:
    def __init__(self):
        self.get = {
            'HEADER': '\033[95m',
            'OKBLUE': '\033[94m',
            'OKGREEN': '\033[92m',
            'WARNING': '\033[93m',
            'FAIL': '\033[91m',
            'ENDC': '\033[0m',
            'BOLD': '\033[1m',
            'UNDERLINE': '\033[4m'
        }


def login_to_zabbix(url, user, password):
    # You can use the connection__timeout
    connection__timeout = 45
    # Verify SSL
    verify__ssl = False
    # Connect to zabbix-server
    zapi = ZabbixAPI(url, timeout=connection__timeout)
    zapi.session.verify = verify__ssl
    if not verify__ssl:
        from requests.packages.urllib3.exceptions import InsecureRequestWarning
        requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
    zapi.login(user, password)
    zapi.session.auth = (user, password)
    # You can re-define connection__timeout after
    zapi.timeout = connection__timeout
    return zapi


def get_needed_groups(z_host, z_user, z_password, z_group):
    needed_groups = []
    zapi = login_to_zabbix(z_host, z_user, z_password)
    if z_group is None:
        get_groups = zapi.hostgroup.get(filter={"name": z_group}, output=['groupid', 'name'])
        for group_name in get_groups:
            needed_groups.append(group_name)
    else:
        get_groups = zapi.hostgroup.get(search={"name": z_group}, output=['groupid', 'name'])
        for group_name in get_groups:
            needed_groups.append(group_name)

    return needed_groups


def get_needed_templates(z_host, z_user, z_password, z_group):
    needed_templates = []
    zapi = login_to_zabbix(z_host, z_user, z_password)
    groups = get_needed_groups(z_host, z_user, z_password, z_group)

    needed_group_ids = []
    for group in groups:
        needed_group_ids.append(group['groupid'])

    get_templates = zapi.template.get(groupids=needed_group_ids, output=['templateid', 'name'])
    for template in get_templates:
        needed_templates.append(template)

    return needed_templates


def get_needed_triggers(z_host, z_user, z_password, z_group):
    needed_triggers = []
    zapi = login_to_zabbix(z_host, z_user, z_password)
    templates = get_needed_templates(z_host, z_user, z_password, z_group)

    needed_template_ids = []
    for template in templates:
        needed_template_ids.append(template['templateid'])

    get_triggers = zapi.trigger.get(templateids=needed_template_ids,
                                    output=['status', 'priority', 'description'],
                                    sortfield='priority',
                                    sortorder='DESC'
                                    )
    for trigger in get_triggers:
        needed_triggers.append({'status': trigger['status'],
                                'priority': trigger['priority'],
                                'description': trigger['description']})

    return needed_triggers


def write_data_to_file(z_host, z_user, z_password, z_group, z_severity):
    severity = {'Not_classified': '0', 'Information': '1', 'Warning': '2', 'Average': '3', 'High': '4', 'Disaster': '5'}

    name_out = './' + str(z_group) + '.txt'
    my_file = Path(name_out)
    if my_file.is_file():
        os.remove(name_out)

    triggers = get_needed_triggers(z_host, z_user, z_password, z_group)
    sorted_triggers = []
    for trigger in triggers:
        if trigger['priority'] >= severity[z_severity]:
            if trigger not in sorted_triggers:
                sorted_triggers.append(trigger)

    for trigger in sorted_triggers:
        try:
            f = open(name_out, 'a')
            f.write(trigger['description'] + '\n')
            f.close()
        except ValueError:
            print ('I cant write to file: ', ValueError)

    return write_data_to_file


def main():
    start__time = time.time()
    parser = argparse.ArgumentParser(prog='python3 script_name.py -h',
                                     usage='python3 script_name.py {ARGS}',
                                     add_help=True,
                                     prefix_chars='--/',
                                     epilog='''created by Vitalii Natarov''')
    parser.add_argument('--version', action='version', version='v1.0.0')
    parser.add_argument('--group', dest='group', help='Group name', default=None)
    parser.add_argument('--zabbix-host', dest='zabbix_host',
                        help='Zabbix host',
                        default='https://zabbix.local')
    parser.add_argument('--zabbix-user', dest='zabbix_user',
                        help='Zabbix user',
                        default='Vitalii_Natarov')
    parser.add_argument('--zabbix-password', dest='zabbix_password',
                        help='Zabbix password of user',
                        default='PASSWORD')
    parser.add_argument('--zabbix-severity', dest='zabbix_severity', help='Set Zabbix severity for triggers',
                        default='Average')

    # group = parser.add_mutually_exclusive_group(required=False)
    # group.add_argument('--show-acc', dest='show_acc', help='Show account names', action='store_true')
    # group.add_argument('--s', dest='show_acc', help='Show account names', action='store_true')
    results = parser.parse_args()
    group_name = results.group
    # host, login, password to connect to zabbix-server
    zabbix__host = results.zabbix_host
    zabbix__user = results.zabbix_user
    zabbix__password = results.zabbix_password
    zabbix__trigger_severity = results.zabbix_severity

    write_data_to_file(zabbix__host, zabbix__user, zabbix__password, group_name, zabbix__trigger_severity)

    end__time = round(time.time() - start__time, 2)
    print("--- %s seconds ---" % end__time)
    print(
        Bgcolors().get['OKGREEN'], "============================================================",
        Bgcolors().get['ENDC'])
    print(
        Bgcolors().get['OKGREEN'], "==========================FINISHED==========================",
        Bgcolors().get['ENDC'])
    print(
        Bgcolors().get['OKGREEN'], "============================================================",
        Bgcolors().get['ENDC'])


if __name__ == '__main__':
    main()

Запускаем:

# python3 get_triggers.py --group "CM-Shared"

Вывод получим:

--- 2.97 seconds ---
 ============================================================
 ==========================FINISHED==========================
 ============================================================

Т.е за 3 секунды, мой скрипт прошелся по всем группам (которая имеет вхождение — «CM-Shared»), нашел какие прилинкованы к группам шаблоны. И по каждому шаблону, вывел триггеры. Конечно, чтобы не было повторений, я отсеял мусор.  Есть идея дописать скрипт так, чтобы он генерировал полностью пейджу для конфлюенса. Не сложно, но было бы желание — появится и результат! 😉

На данный скрипт ушло около 2-х часов моего времени. Если бы я руками все это делал — часов 5, не меньше!

Полезные статьи:

Экспортирование zabbix templates

Импортирование zabbix templates

На этом у меня все, статья «Экспорт zabbix triggers» завершена.

The post Экспорт zabbix triggers first appeared on linux-notes.org.]]>
https://linux-notes.org/jeksport-zabbix-triggers/feed/ 0
Page_c76a3fcf https://linux-notes.org/ustanovka-s-tui-v-unix-linux/ https://linux-notes.org/ustanovka-s-tui-v-unix-linux/#respond Wed, 21 Feb 2018 22:55:41 +0000 http://linux-notes.org/?p=15219 Установка s-tui в Unix/Linux S-tui — бесплатный пользовательский интерфейс с открытым исходным кодом для мониторинга вашего компьютера. Утилита s-tui позволяет контролировать температуру процессора, частоту и его мощность. Данная тулза, написана на Python и требует root права для ее использования. Установка s-tui в Unix/Linux Для этой утилиты, понадобится PIP, установить его можно по следующей статье: Установка […]

The post Установка s-tui в Unix/Linux first appeared on linux-notes.org.]]>

Установка s-tui в Unix/Linux

S-tui — бесплатный пользовательский интерфейс с открытым исходным кодом для мониторинга вашего компьютера. Утилита s-tui позволяет контролировать температуру процессора, частоту и его мощность. Данная тулза, написана на Python и требует root права для ее использования.

Установка s-tui в Unix/Linux

Для этой утилиты, понадобится PIP, установить его можно по следующей статье:

Установка pip/setuptools/wheel в Unix/Linux

Так же, понадобится утилита stress.

Установка stress в Mac OS X

Стоит установить homebrew — Установка homebrew на Mac OS X и после чего, выполняем:

$ brew install stress

Установка stress в Debian/Ubuntu

Установка очень простая, выполняем:

# apt-get install stress

Установка stress в CentOS/Redhat/Fedora

Установка очень простая, выполняем:

# yum -y install stress

Установка s-tui в Unix/Linux

Чтобы установить утилиту s-tui выполняем:

# pip install s-tui

ИЛИ:

# pip3 install s-tui

Перейдем к использованию.

Использование s-tui в Unix/Linux

Использование очень простое, стоит выполнить:

$ sudo s-tui

Вот как выглядит утилита в работе:

Установка s-tui в Unix/Linux

Для помощи, можно использовать команду:

$ s-tui --help

Вот и все, статья «Установка s-tui в Unix/Linux» завершена.

The post Установка s-tui в Unix/Linux first appeared on linux-notes.org.]]>
https://linux-notes.org/ustanovka-s-tui-v-unix-linux/feed/ 0
Page_c76a3fcf https://linux-notes.org/nastrojka-new-relic-s-grafana-v-unix-linux/ https://linux-notes.org/nastrojka-new-relic-s-grafana-v-unix-linux/#respond Fri, 22 Dec 2017 08:14:45 +0000 http://linux-notes.org/?p=14412 Настройка New Relic с Grafana в Unix/Linux New Relic — это инструмент для мониторинга приложений. Grafana — это инструмент, который позволяет отображать метрики, стоить графики (дашборды) и умеет работать с различными инструментами (Prometheus, InfluxDB, ElasticSearch и многие другие). У меня на работе, имеется заббикс сервер, графана и некоторые люди используют нью релик. Как по мне, […]

The post Настройка New Relic с Grafana в Unix/Linux first appeared on linux-notes.org.]]>

Настройка New Relic с Grafana в Unix/Linux

New Relic — это инструмент для мониторинга приложений.

Grafana — это инструмент, который позволяет отображать метрики, стоить графики (дашборды) и умеет работать с различными инструментами (Prometheus, InfluxDB, ElasticSearch и многие другие).

У меня на работе, имеется заббикс сервер, графана и некоторые люди используют нью релик. Как по мне, все должно (это очень удобно) быть в одном месте.

Я описывал процесс установки данных компонентов в своих статьях:

Установка New Relic Platform Installer (NPI) в Unix/Linux

Мониторинг приложений с New Relic в Unix/Linux

Установка плагинов для New Relic

Установка grafana в Unix/Linux

Настройка Grafana с Graphite/Zabbix/Prometheus/MySQL/InfluxDB/Elasticsearch/CloudWatch для сбора и отображения метрик в Unix/Linux

Экспорт дашбордов из grafana в Unix/Linux

И так, приступим к настройке!

Настройка New Relic с Grafana в Unix/Linux

Я предпологаю что уже имеется установленный New Relic на нодах которые стоит мониторить и уже мониторится все. Так же, я предпологаю что уже имеется сервер с grafana.

Устанавливаем git, статья тут:

Установка GIT на RedHat/CentOS/Fedora или Установка git на CentOS, для других ОС, нет ничего сложного чтобы установить.

Перейдем в папку с плагинами самой графаны:

# cd /var/lib/grafana/plugins

И клонируем плагин:

$ git clone https://github.com/wevanscfi/grafana-newrelic-apm-datasource.git

Далее, открываем сайт с new relic, логинимся в него и регистрируем токен. Я не буду офишировать его, по этому не сделаю скрин.

Открываем сайт с графана и переходим в «plugins» -> «APPS» -> «newrelic-app». В Поле «Api key» вводим API ключ с new relic-а:

Активация grafana-newrelic-apm-datasource плагина для grafana

Затем, переходим в «datasources» и, нажимаем на » Add data source». В поле «type» выбираем наш установленный плагин в качестве БД:

Добавляем datasource в grafana

В поле «Aplication» выбираем апликейшин для мониторинга. По идее, можно не выбирать, он все равно будет выбиратся из листинга (в дальнейшем). Нажимаем на «add» для добавления датасорса. Собственно — это и вся установка. Осталось создать дашборд и вывести необходимые метрики.

Вот пример моего тестового дашборда:

new relic + grafana

Вот и все, статья «Настройка New Relic с Grafana в Unix/Linux» завершена.

The post Настройка New Relic с Grafana в Unix/Linux first appeared on linux-notes.org.]]>
https://linux-notes.org/nastrojka-new-relic-s-grafana-v-unix-linux/feed/ 0
Page_c76a3fcf https://linux-notes.org/e-ksport-dashbordov-iz-grafana-v-unix-linux/ https://linux-notes.org/e-ksport-dashbordov-iz-grafana-v-unix-linux/#comments Fri, 24 Nov 2017 00:51:36 +0000 http://linux-notes.org/?p=14174 Экспорт дашбордов из grafana в Unix/Linux У меня на работе, установлена grafana и ее активно используют коллеги для снятия различных метрик по дашбордам. Как у нас частенько бывает — ложатся сервера и если нет бэкапов, то все печально! Руками бэкапить дашборды с графаны — это нормально, но я люблю автоматизацию. И решил написать скрипт для […]

The post Экспорт дашбордов из grafana в Unix/Linux first appeared on linux-notes.org.]]>

Экспорт дашбордов из grafana в Unix/Linux

У меня на работе, установлена grafana и ее активно используют коллеги для снятия различных метрик по дашбордам. Как у нас частенько бывает — ложатся сервера и если нет бэкапов, то все печально! Руками бэкапить дашборды с графаны — это нормально, но я люблю автоматизацию. И решил написать скрипт для экспорта всех дашбордов из grafana себе на компьютер. Я совсем не много пишу на питон и по этому — хотел написать на нем (так и будет немного позже)….. но на скорую руку пришелся — bash.

Полезное чтиво:

Установка grafana в Unix/Linux

Настройка Grafana с Graphite/Zabbix/Prometheus/MySQL/InfluxDB/Elasticsearch/CloudWatch для сбора и отображения метрик в Unix/Linux

-=== СПОСОБ 1 — Использование BASH===-

Предположим, скрипт у меня лежит прям в текущей директории:

# cat get_grafana_dashes.sh

Собственно, вот сие чудо:

#!/bin/bash -x
#
# Vitaliy Natarov
#
# Set some colors for status OK, FAIL and titles
SETCOLOR_SUCCESS="echo -en \\033[1;32m"
SETCOLOR_FAILURE="echo -en \\033[1;31m"
SETCOLOR_NORMAL="echo -en \\033[0;39m"

SETCOLOR_TITLE="echo -en \\033[1;36m" #Fuscia
SETCOLOR_TITLE_GREEN="echo -en \\033[0;32m" #green
SETCOLOR_TITLE_PURPLE="echo -en \\033[0;35m" #purple 
SETCOLOR_NUMBERS="echo -en \\033[0;34m" #BLUE

KEY="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
HOST="http://graffana-server.local"
DASH_DIR="/home/captain/Grafana/dashboards"

if [ ! -d "$DASH_DIR" ]; then
	 mkdir -p dashboards 
else
	 $SETCOLOR_TITLE_PURPLE
	 echo "|-------------------------------------------------------------------------------|";
	 echo "| A $DASH_DIR directory is already exist! |";
	 echo "|-------------------------------------------------------------------------------|";
	 $SETCOLOR_NORMAL
fi
  
#curl -sS -k -H "Authorization: Bearer $KEY" $HOST/api/search\?query\=\& |tr ']{' '\n'| cut -d ':' -f4| cut -d ',' -f1| cut -d '"' -f2 | grep -Ev "(^$|\[)"| cut -c 4-

for dash in $(curl -sS -k -H "Authorization: Bearer $KEY" $HOST/api/search\?query\=\& |tr ']{' '\n'| cut -d ':' -f4| cut -d ',' -f1| cut -d '"' -f2 | grep -Ev "(^$|\[)"| cut -c 4-); do
	curl -sS -k -H "Authorization: Bearer $KEY" $HOST/api/dashboards/db/$dash > dashboards/$dash.json
	$SETCOLOR_TITLE_GREEN
	echo "The [ $dash ] dashboard has been exported"  
	$SETCOLOR_NORMAL
done

$SETCOLOR_TITLE
echo "|-------------------------------------------------------------------------------|";
echo "|----------------------------------FINISHED-------------------------------------|";
echo "|-------------------------------------------------------------------------------|";
$SETCOLOR_NORMAL

Где:

  • KEY=»XXXXXXXXXXXXXXXXXXXXXXXX» — Ключ для использования API. Можно сгенерировать в админ-панеле самой графаны.
  • HOST=»http://graffana-server.local» — УРЛ где находится графана-сервер.
  • DASH_DIR=»/home/captain/Grafana/dashboards» — Путь где будут лежать все шаблоны (дашборды) после экспорта.

Запускаем:

$ bash Get_grafana_dashes.sh

Получаем:

Экспорт дашбордов из grafana в Unix/Linux

Экспорт дашбордов из grafana в Unix/Linux

Вроде бы все нормально. Кому режит глаза, могут убрать расскраску 🙂

-=== СПОСОБ 2 — Использование PYTHON===-

Будет скоро, постараюсь написать на днях. Возможно после выходных….

Так вот, прошло несколько дней и мой скрипт — готов.

Открываю его:

$ vim grafana_dashboards.py

Он имеет следующее содержание:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import requests
import time
import os
import argparse
import json
import glob

# from datetime import datetime
from requests.packages.urllib3.exceptions import InsecureRequestWarning


class Bgcolors:
    def __init__(self):
        self.get = {
            'HEADER': '\033[95m',
            'OKBLUE': '\033[94m',
            'OKGREEN': '\033[92m',
            'WARNING': '\033[93m',
            'FAIL': '\033[91m',
            'ENDC': '\033[0m',
            'BOLD': '\033[1m',
            'UNDERLINE': '\033[4m'
        }


def get_grafana_dashboards(g_url, g_token):
    dashboards_array = []
    headers = {'Authorization': str('Bearer ' + g_token), 'Content-type': 'application/json'}
    get_data_req = requests.get(g_url + '/api/search?query=&', headers=headers)

    pars_json = json.loads(get_data_req.text)
    for dash in pars_json:
        # print(dash['uri'][3::])
        dashboards_array.append(dash['uri'][3::])

    return dashboards_array


def export_grafana_dashboards(g_token, g_url, dir_path, e_dash):
    headers = {'Authorization': str('Bearer ' + g_token),
               'Content-type': 'application/json'
               }
    if not os.path.exists(dir_path):
        os.makedirs(dir_path)
        print(dir_path, 'has been created')

    dashboard_names = get_grafana_dashboards(g_url, g_token)
    dash_count = 1

    if e_dash == 'all':
        # print('I will export ALL DASHes!')
        for d in dashboard_names:
            dashboard_name_out = dir_path + '/' + d + '.json'
            get_dashboard = requests.get(g_url + '/api/dashboards/db/' + d, headers=headers)
            try:
                f = open(dashboard_name_out, 'w')
                f.write(json.dumps(get_dashboard.json(), indent=4))
                f.close()
                print('[', dash_count, ']', d)
                dash_count += 1
            except EOFError:
                print('I cant write to file: ', EOFError)

    else:
        # print('I will export %s dashbourd(s)!' % e_dash)
        for d in dashboard_names:
            for dd in e_dash:
                if d == dd:
                    dashboard_name_out = dir_path + '/' + d + '.json'
                    get_dashboard = requests.get(g_url + '/api/dashboards/db/' + d, headers=headers)
                    try:
                        f = open(dashboard_name_out, 'w+')
                        f.write(json.dumps(get_dashboard.json(), indent=4))
                        f.close()
                        print('[', dash_count, ']', d)
                        dash_count += 1
                    except ValueError:
                        print('I cant write to file: ', ValueError)
    #

    return export_grafana_dashboards


def import_grafana_dashboards(g_token, g_url, dir_path, i_dash):
    headers = {'Authorization': str('Bearer ' + g_token),
               'Content-type': 'application/json',
               'Accept': 'application/json'
               }
    dash_count = 1

    if i_dash == 'all':
        # print('I will import ALL DASHes!')
        files = glob.glob(dir_path + "/" + "*.json")
    else:
        # print('I will import %s dashbourd(s)!' % i_dash)
        for d in i_dash:
            files = glob.glob(str(dir_path) + "/" + str(d) + ".json")
    for f in files:
        d = f.split('.')[0].split('/')[1]

        with open(f, 'r') as file:
            dashboard = file.read()
            try:
                print('[%s] Need to create an import to grafana [%s]' % (dash_count, f))
                datas = json.loads(dashboard)

                protocol = g_url.split(':')[0]
                if protocol == "http":
                    i__dash = requests.post(g_url + '/api/dashboards/db/', headers=headers, json=datas)
                elif protocol == "https":
                    verify = False
                    if not verify:
                        requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
                    i__dash = requests.post(g_url + '/api/dashboards/db/', headers=headers, json=datas, verify=verify)
                    if i__dash.status_code != 200:
                        print(i__dash.status_code)
                        exit(0)
                else:
                    print('Incorrect URL! Use url with http|https protocol')
                    exit(0)
                print(i__dash)
            except EOFError as e:
                print(e)
        dash_count += 1

    return import_grafana_dashboards


def main():
    start__time = time.time()
    parser = argparse.ArgumentParser(prog='python3 script_name.py -h',
                                     usage='python3 script_name.py {ARGS}',
                                     add_help=True,
                                     prefix_chars='--/',
                                     epilog='''created by Vitalii Natarov''')
    parser.add_argument('--version', action='version', version='v1.0.0')
    parser.add_argument('--dash', '--dashboard', nargs='+', dest='dashboard', help='Indicate a dashboard(s)',
                        default='all')
    parser.add_argument('--gtoken', '--token', dest='gtoken', help='Token of grafana server', default=None)
    parser.add_argument('--gurl', '--url', dest='gurl', help='URL from grafana', default=None)
    parser.add_argument('--dir', '--directory', dest='dashboards_dir', help='Indicate a folder for dashboard(s)',
                        default='CM-Shared_Grafana', metavar='folder')

    group = parser.add_mutually_exclusive_group(required=False)
    group.add_argument('--i', dest='imports', help='Import function', action='store_true')
    group.add_argument('--import', dest='imports', help='Import function', action='store_true')

    group2 = parser.add_mutually_exclusive_group(required=False)
    group2.add_argument('--e', dest='exports', help='Export function', action='store_true', default=argparse.SUPPRESS)
    group2.add_argument('--export', dest='exports', help='Export function', action='store_true')

    results = parser.parse_args()
    dashboards_dir = results.dashboards_dir
    dashboard = results.dashboard
    grafana_token = results.gtoken
    grafana_url = results.gurl

    if (grafana_token is not None) and (grafana_url is not None):
        if results.exports:
            print('EXPORT function!')
            export_grafana_dashboards(grafana_token, grafana_url, dashboards_dir, dashboard)

        elif results.imports:
            print('IMPORT function')
            import_grafana_dashboards(grafana_token, grafana_url, dashboards_dir, dashboard)
    else:
        print('Please add [--gurl] and/or [--gtoken] option(s).Use "--e" to export, "--i" to import dashboards as well')
        print('For help, use: script_name.py -h')
        exit(0)
    end__time = round(time.time() - start__time, 2)
    print("--- %s seconds ---" % end__time)

    print(
        Bgcolors().get['OKGREEN'], "============================================================",
        Bgcolors().get['ENDC'])
    print(
        Bgcolors().get['OKGREEN'], "==========================FINISHED==========================",
        Bgcolors().get['ENDC'])
    print(
        Bgcolors().get['OKGREEN'], "============================================================",
        Bgcolors().get['ENDC'])


if __name__ == '__main__':
    main()

Для помощи можно использовать:

$ python3 grafana_dashboards.py -h
usage: python3 script_name.py {ARGS}

optional arguments:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  --dash DASHBOARD [DASHBOARD ...], --dashboard DASHBOARD [DASHBOARD ...]
                        Indicate a dashboard(s)
  --dir folder, --directory folder
                        Indicate a folder for dashboard(s)
  --i                   Import function
  --import              Import function
  --e                   Export function
  --export              Export function

created by Vitalii Natarov

Чтобы выполнить экспорт шалонов, выполняем:

$ python3 grafana_dashboards.py --e --gurl GRAFANA_URL_HERE --gtoken GRAFANA_TOKEN_HERE

Можно указать другую директорию:

$ python3 grafana_dashboards.py --e --dir some_another_dir --gurl GRAFANA_URL_HERE --gtoken GRAFANA_TOKEN_HERE

Или, можно экспортировать не все шаблоны, а только выбранные, — например:

$ python3 grafana_dashboards.py --e --dir --dash some_dashboard --gurl GRAFANA_URL_HERE --gtoken GRAFANA_TOKEN_HERE

Для импортирования, служит другая команда:

$ python3 grafana_dashboards.py --i

-=== СПОСОБ 3 — Использование модуля для grafana===-

Для начала, потребуется python3 + pip3:

Установка pip/setuptools/wheel в Unix/Linux

Ставим нужный пакет:

$ pip3 install grafcli

Теперь создайте конфигурационный файл grafcli.conf. Пока это в вашем рабочем каталоге в порядке:

[grafcli]
editor = vim
verbose = off

[hosts]
$GRAFANA_URL = on

[$GRAFANA_URL]
type = api
url = https://$GRAFANA_URL:$PORT
ssl = on
user = admin
password = $GRAFANA_ADMIN_PASSWORD
#token = $GRAFANA_TOKEN

[resources]
data-dir = ~/.grafcli

Если вы используете token, то вам не нужно прописывать user/password. Чтобы проверить, действительно ли ваш файл конфигурации настроен корректно, попробуйте выполнить:

$ grafcli ls remote

Он должен показать URL-адрес Grafana, который вы прописали. Чтобы создать резервную копию всех дашбордов, используйте команду:

$ grafcli backup remote/$GRAFANA_URL/ backup.tgz

Восстановление из резервной копии также простое:

$ grafcli restore backup.tgz remote/$GRAFANA_URL/

Вот и все, статья «Экспорт дашбордов из grafana в Unix/Linux» завершена.

The post Экспорт дашбордов из grafana в Unix/Linux first appeared on linux-notes.org.]]>
https://linux-notes.org/e-ksport-dashbordov-iz-grafana-v-unix-linux/feed/ 4
Page_c76a3fcf https://linux-notes.org/dobavlenie-rds-hostov-v-zabbix-c-ispol-zovaniem-boto3-python3/ https://linux-notes.org/dobavlenie-rds-hostov-v-zabbix-c-ispol-zovaniem-boto3-python3/#respond Fri, 13 Oct 2017 23:15:19 +0000 http://linux-notes.org/?p=13730 Добавление RDS хостов в zabbix c использованием boto3 + python3 На работе потребовалось добавлять RDS хосты (с различных учеток AWS) в заббикс. Руками делать, — это конечно нормальное явление, но я люблю оптимизацию и автоматизацию. И для этого готов был написать скрипт. Пал выбор на питон. Полезное чтиво: Установка Zabbix + nginx+php-fpm + mariaDB в […]

The post Добавление RDS хостов в zabbix c использованием boto3 + python3 first appeared on linux-notes.org.]]>

Добавление RDS хостов в zabbix c использованием boto3 + python3

На работе потребовалось добавлять RDS хосты (с различных учеток AWS) в заббикс. Руками делать, — это конечно нормальное явление, но я люблю оптимизацию и автоматизацию. И для этого готов был написать скрипт. Пал выбор на питон.

Полезное чтиво:

Установка Zabbix + nginx+php-fpm + mariaDB в Unix/Linux

Установка Zabbix-agent в Unix/Linux

Установка pip/setuptools/wheel в Unix/Linux

Автоматическое выключение хостов в zabbix

Автоматическое удаление хостов в zabbix

Открываем файл:

# vim Add_Hosts_from_AWS_RDS_to_Zabbix.py

Он выглядит следующим образом:

#!/bin/env python3
# -*- coding: utf-8 -*-
import requests
import sys
import boto3
import glob
import smtplib

from pyzabbix import ZabbixAPI, ZabbixAPIException
#


class bgcolors:
    def __init__(self):
        self.colors = {
            'HEADER': '\033[95m',
            'OKBLUE': '\033[94m',
            'OKGREEN': '\033[92m',
            'WARNING': '\033[93m',
            'FAIL': '\033[91m',
            'ENDC': '\033[0m',
            'BOLD': '\033[1m',
            'UNDERLINE': '\033[4m'
        }

def get_creds_from_assum_role():
    auth_params = []

    # create an STS client object that represents a live connection to the
    # STS service

    #sts_client = boto3.setup_default_session(region_name='us-east-1')
    sts_client = boto3.client('sts', region_name='us-east-1')
    #
    Assum_Roles = ['arn:aws:iam::93388403184:role/CW-RDS-READ-ONLY'
        , 'arn:aws:iam::4131648289989:role/CLOUDWATCH-READONLY-ACCESS-CMSHARED'
        , 'arn:aws:iam::067785372661:role/CLOUDWATCH-READONLY-ACCESS-DEV'
        , 'arn:aws:iam::66803035257:role/CLOUDWATCH-READONLY-ACCESS-CMSHARED'
        , 'arn:aws:iam::505163668321:role/CLOUDWATCH-READONLY-ACCESS-ZABBIX'
        , 'arn:aws:iam::378494444851:role/CLOUDWATCH-READONLY-ACCESS-ZABBIX']

    # Call the assume_role method of the STSConnection object and pass the role
    # ARN and a role session name.

    for Assum_Role in Assum_Roles:
        assumedRoleObject = sts_client.assume_role(
            RoleArn=Assum_Role,
            RoleSessionName="ElastiCache"
        )

        # From the response that contains the assumed role, get the temporary
        # credentials that can be used to make subsequent API calls

        credentials = assumedRoleObject['Credentials']
        auth_param = {
            'access_key': credentials['AccessKeyId'],
            'secret_key': credentials['SecretAccessKey'],
            'session_token': credentials['SessionToken']
        }
        auth_params.append(auth_param)
    # print(auth_params)
    return auth_params


def get_rds_hosts_from_assum_role():
    hosts_from_rds = []
    # RDS
    Creds_Data = get_creds_from_assum_role()
    for get_greds_from_acc in Creds_Data:
        access_key = get_greds_from_acc['access_key']
        secret_key = get_greds_from_acc['secret_key']
        session_token = get_greds_from_acc['session_token']
        #
        rds_client = boto3.setup_default_session(region_name='us-east-1'
                                                 , aws_access_key_id=access_key
                                                 , aws_secret_access_key=secret_key
                                                 , aws_session_token=session_token)
        rds_client = boto3.client('rds'
                              , region_name='us-east-1'
                              , aws_access_key_id=access_key
                              , aws_secret_access_key=secret_key
                              , aws_session_token=session_token)
        try:
            # get all of the db instances
            rdses = rds_client.describe_db_instances()
            for rds in rdses['DBInstances']:
                hosts_from_rds.append(rds['Endpoint']['Address'])
        except Exception as error:
            print (error)
    # print(hosts_from_rds)
    return hosts_from_rds  # def get_elasticache_hosts_from_assum_role():


def login_to_zabbix():
    # host, login, password to connect to DEV zabbix-server
    Zabbix_Host = 'https://zabbix.com/'
    Zabbix_User = 'apiuser'
    Zabbix_Password = 'gkjhjhvjh5uigkjhg'
    # You can use the Connection_Timeout
    Connection_Timeout = 25
    # Verify SSL
    Verify_SSL = False
    # Connect to zabbix-server
    zapi = ZabbixAPI(Zabbix_Host, timeout=Connection_Timeout)
    zapi.session.verify = Verify_SSL
    if not Verify_SSL:
        from requests.packages.urllib3.exceptions import InsecureRequestWarning
        requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
    r = requests.get(Zabbix_Host, verify=Verify_SSL)
    #
    zapi.login(Zabbix_User, Zabbix_Password)
    zapi.session.auth = (Zabbix_User, Zabbix_Password)
    # You can re-define Connection_Timeout after
    zapi.timeout = Connection_Timeout
    return zapi


def add_group_to_zabbix(group):
    zapi = login_to_zabbix()
    zapi.hostgroup.create(name=group)
    return add_group_to_zabbix


def add_host_to_zabbix(host, group, template, port=666):
    zapi = login_to_zabbix()
    Get_Templates = zapi.template.get(search={"name": template})
    for template in Get_Templates:
        # print(template['templateid'])
        templateid = template['templateid']
    Get_Groups = zapi.hostgroup.get(search={"name": group})
    for group in Get_Groups:
        if len(host) > 64:
            print ('Host is more than 64 characters: ', host)
            sender = 'captain@localhost'
            receivers = 'vitalii_natarov@epam.com'
            message = ('Host is more than 64 characters: %s' % host)
            smtpObj = smtplib.SMTP('localhost')
            smtpObj.sendmail(sender, receivers, message)
        else:
            zapi.host.create({"host": host,
                              "interfaces": [{
                                "type": 1,
                                "main": 1,
                                "useip": 0,
                                "ip": "",
                                "dns": host,
                                "port": port,
                                }],
                              "groups": [{
                                "groupid": group['groupid'],
                                }],
                              "templates": [{
                                "templateid": templateid,
                                }],
                            })
    return add_host_to_zabbix

def add_template_to_zabbix():
    zapi = login_to_zabbix()
    rules = {
        'applications': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'discoveryRules': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'graphs': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'groups': {
            'createMissing': 'true'
        },
        'hosts': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'images': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'items': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'maps': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'screens': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'templateLinkage': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'templates': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'templateScreens': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'triggers': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
    }
    path = 'Zabbix_Templates/Template_AWS_RDS.xml'
    files = glob.glob(path)
    for file in files:
        with open(file, 'r') as f:
            template = f.read()
            try:
                zapi.confimport('xml', template, rules)
            except ZabbixAPIException as e:
                print(e)
    return add_template_to_zabbix


def main():
    zapi = login_to_zabbix()
    Zabbix_Version = zapi.do_request('apiinfo.version')
    print(bgcolors().colors['OKGREEN'],"============================================================", bgcolors().colors['ENDC'])
    print(bgcolors().colors['OKGREEN'],'Zabbix Version:', Zabbix_Version['result'] + bgcolors().colors['ENDC'])
    print(bgcolors().colors['OKGREEN'],"============================================================", bgcolors().colors['ENDC'])
    # find needed group, template, host
    Needed_groups = ['AWS RDS']
    Needed_IPs = get_rds_hosts_from_assum_role()
    Needed_Templates = ['Template_AWS_RDS']
    Get_Templates = zapi.template.get(search={"name": Needed_Templates})
    for template in Get_Templates:
        Needed_Template = template['name']
    for Needed_group in Needed_groups:
        Get_Groups = zapi.hostgroup.get(search={"name": Needed_group})
        if (len(Get_Groups)) is not 0:
            # check host in provided group
            for Needed_IP in Needed_IPs:
                Get_Hosts = zapi.host.get(search={"name": Needed_IP})
                if (len(Get_Hosts)) is 0:
                    #for h in Get_Hosts:
                     add_host_to_zabbix(Needed_IP, Needed_group, Needed_Template)
                     print('Added ', Needed_IP, 'host to zabbix')
                else:
                    #pass
                    print ('The', Needed_IP, 'already exist')
        else:
            add_group_to_zabbix(Needed_group)
            print ('Added the', Needed_group, 'group to zabbix')
            # find needed template
            for Needed_Template in Needed_Templates:
                Get_Templates = zapi.hostgroup.get(filter={"name": Needed_Templates})
                if (len(Get_Templates)) is 0:
                    add_template_to_zabbix()
                    print('Added', Needed_Template, 'template to zabbix')
                else:
                    pass
            for Needed_IP in Needed_IPs:
                Get_Hosts = zapi.host.get(filter={"name": Needed_IP}, output=['hostid', 'host', 'name', 'status'])
                if (len(Get_Hosts)) is 0:
                    add_host_to_zabbix(Needed_IP, Needed_group, Needed_Template)
                    print('Added ', Needed_IP, 'host to zabbix')
                else:
                    pass
    print(bgcolors().colors['OKGREEN'], "============================================================", bgcolors().colors['ENDC'])
    print(bgcolors().colors['OKGREEN'], "==========================FINISHED==========================", bgcolors().colors['ENDC'])
    print(bgcolors().colors['OKGREEN'], "============================================================", bgcolors().colors['ENDC'])

if __name__ == '__main__':
    main()

В теле скрипта нужно изменить некоторые переменные. Я не буду рассказывать что нужно менять, думаю и так очевидно, если нет — то можете написать в комментариях и я помогу с этим.

Создаем темплейт:

# mkdir Zabbix_Templates

Открываем файл:

# vim Zabbix_Templates/Template_AWS_RDS.xml

И вставляем в него:

<?xml version="1.0" encoding="UTF-8"?>
<zabbix_export>
    <version>2.0</version>
    <date>2017-08-18T17:25:33Z</date>
    <groups>
        <group>
            <name>AWS RDS</name>
        </group>
        <group>
            <name>Templates</name>
        </group>
    </groups>
    <templates>
        <template>
            <template>Template_AWS_RDS</template>
            <name>Template_AWS_RDS</name>
            <description>AWS RDS monitoring</description>
            <groups>
                <group>
                    <name>AWS RDS</name>
                </group>
                <group>
                    <name>Templates</name>
                </group>
            </groups>
            <applications>
                <application>
                    <name>RDS</name>
                </application>
            </applications>
            <items>
                <item>
                    <name>RDS::BinLogDiskUsage</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.BinLogDiskUsage.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>B</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The amount of disk space occupied by binary logs on the master. Applies to MySQL read replicas.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::CPUUtilization</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.CPUUtilization.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>%</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The percentage of CPU utilization.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::DatabaseConnections</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.DatabaseConnections.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units/>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The number of database connections in use.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::DiskQueueDepth</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.DiskQueueDepth.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units/>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The number of outstanding IOs (read/write requests) waiting to access the disk.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::FreeableMemory</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.FreeableMemory.Minimum</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>B</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The amount of available random access memory.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::FreeStorageSpace</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.FreeStorageSpace.Minimum</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>B</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The amount of available storage space.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::NetworkReceiveThroughput</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.NetworkReceiveThroughput.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>B/s</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The incoming (Receive) network traffic on the DB instance, including both customer database traffic and Amazon RDS traffic used for monitoring and replication.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::NetworkTransmitThroughput</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.NetworkTransmitThroughput.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>B/s</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The outgoing (Transmit) network traffic on the DB instance, including both customer database traffic and Amazon RDS traffic used for monitoring and replication.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::ReadIOPS</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.ReadIOPS.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>ops/s</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The average number of disk I/O operations per second.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::ReadLatency</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.ReadLatency.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>s</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The average amount of time taken per disk I/O operation.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::ReadThroughput</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.ReadThroughput.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>B/s</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The average number of bytes read from disk per second.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::ReplicaLag</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.ReplicaLag.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>s</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The amount of time a Read Replica DB Instance lags behind the source DB Instance. Applies to MySQL read replicas.&#13;
&#13;
The ReplicaLag metric reports the value of the Seconds_Behind_Master field of the MySQL SHOW SLAVE STATUS command.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::SwapUsage</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.SwapUsage.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>B</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The amount of swap space used on the DB Instance.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::WriteIOPS</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.WriteIOPS.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>ops/s</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The average number of disk I/O operations per second.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::WriteLatency</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.WriteLatency.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>s</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The average amount of time taken per disk I/O operation.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::WriteThroughput</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.WriteThroughput.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>B/s</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The average number of bytes written to disk per second.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
            </items>
            <discovery_rules/>
            <macros>
                <macro>
                    <macro>{$TH_P2_FREE_STORAGE}</macro>
                    <value>1G</value>
                </macro>
                <macro>
                    <macro>{$TH_P2_LATENCY}</macro>
                    <value>0.2</value>
                </macro>
                <macro>
                    <macro>{$TH_P3_CPU_USAGE}</macro>
                    <value>90</value>
                </macro>
                <macro>
                    <macro>{$TH_P3_FREE_STORAGE}</macro>
                    <value>2G</value>
                </macro>
                <macro>
                    <macro>{$TH_P3_LATENCY}</macro>
                    <value>0.1</value>
                </macro>
                <macro>
                    <macro>{$TH_P4_CPU_USAGE}</macro>
                    <value>85</value>
                </macro>
            </macros>
            <templates/>
            <screens>
                <screen>
                    <name>RDS::Statistics</name>
                    <hsize>2</hsize>
                    <vsize>3</vsize>
                    <screen_items>
                        <screen_item>
                            <resourcetype>0</resourcetype>
                            <width>500</width>
                            <height>100</height>
                            <x>0</x>
                            <y>0</y>
                            <colspan>1</colspan>
                            <rowspan>1</rowspan>
                            <elements>0</elements>
                            <valign>1</valign>
                            <halign>2</halign>
                            <style>0</style>
                            <url/>
                            <dynamic>0</dynamic>
                            <sort_triggers>0</sort_triggers>
                            <resource>
                                <name>RDS::DB Connections</name>
                                <host>Template_AWS_RDS</host>
                            </resource>
                            <max_columns>3</max_columns>
                            <application/>
                        </screen_item>
                        <screen_item>
                            <resourcetype>0</resourcetype>
                            <width>500</width>
                            <height>100</height>
                            <x>1</x>
                            <y>0</y>
                            <colspan>1</colspan>
                            <rowspan>1</rowspan>
                            <elements>0</elements>
                            <valign>1</valign>
                            <halign>1</halign>
                            <style>0</style>
                            <url/>
                            <dynamic>0</dynamic>
                            <sort_triggers>0</sort_triggers>
                            <resource>
                                <name>RDS::Latency</name>
                                <host>Template_AWS_RDS</host>
                            </resource>
                            <max_columns>3</max_columns>
                            <application/>
                        </screen_item>
                        <screen_item>
                            <resourcetype>0</resourcetype>
                            <width>500</width>
                            <height>100</height>
                            <x>0</x>
                            <y>1</y>
                            <colspan>1</colspan>
                            <rowspan>1</rowspan>
                            <elements>0</elements>
                            <valign>1</valign>
                            <halign>2</halign>
                            <style>0</style>
                            <url/>
                            <dynamic>0</dynamic>
                            <sort_triggers>0</sort_triggers>
                            <resource>
                                <name>RDS::Storage Stats</name>
                                <host>Template_AWS_RDS</host>
                            </resource>
                            <max_columns>3</max_columns>
                            <application/>
                        </screen_item>
                        <screen_item>
                            <resourcetype>0</resourcetype>
                            <width>500</width>
                            <height>100</height>
                            <x>1</x>
                            <y>1</y>
                            <colspan>1</colspan>
                            <rowspan>1</rowspan>
                            <elements>0</elements>
                            <valign>1</valign>
                            <halign>1</halign>
                            <style>0</style>
                            <url/>
                            <dynamic>0</dynamic>
                            <sort_triggers>0</sort_triggers>
                            <resource>
                                <name>RDS::System Stats</name>
                                <host>Template_AWS_RDS</host>
                            </resource>
                            <max_columns>3</max_columns>
                            <application/>
                        </screen_item>
                        <screen_item>
                            <resourcetype>0</resourcetype>
                            <width>500</width>
                            <height>100</height>
                            <x>0</x>
                            <y>2</y>
                            <colspan>1</colspan>
                            <rowspan>1</rowspan>
                            <elements>0</elements>
                            <valign>1</valign>
                            <halign>2</halign>
                            <style>0</style>
                            <url/>
                            <dynamic>0</dynamic>
                            <sort_triggers>0</sort_triggers>
                            <resource>
                                <name>RDS::Network Stats</name>
                                <host>Template_AWS_RDS</host>
                            </resource>
                            <max_columns>3</max_columns>
                            <application/>
                        </screen_item>
                        <screen_item>
                            <resourcetype>0</resourcetype>
                            <width>500</width>
                            <height>100</height>
                            <x>1</x>
                            <y>2</y>
                            <colspan>1</colspan>
                            <rowspan>1</rowspan>
                            <elements>0</elements>
                            <valign>1</valign>
                            <halign>1</halign>
                            <style>0</style>
                            <url/>
                            <dynamic>0</dynamic>
                            <sort_triggers>0</sort_triggers>
                            <resource>
                                <name>RDS::IO Stats</name>
                                <host>Template_AWS_RDS</host>
                            </resource>
                            <max_columns>3</max_columns>
                            <application/>
                        </screen_item>
                    </screen_items>
                </screen>
            </screens>
        </template>
    </templates>
    <triggers>
        <trigger>
            <expression>{Template_AWS_RDS:RDS.CPUUtilization.Average.min(#3)}&gt;{$TH_P4_CPU_USAGE} and {Template_AWS_RDS:RDS.CPUUtilization.Average.max(#3)}&lt;{$TH_P3_CPU_USAGE}</expression>
            <name>RDS::High CPU Usage (LV={ITEM.VALUE})</name>
            <url/>
            <status>0</status>
            <priority>2</priority>
            <description/>
            <type>0</type>
            <dependencies/>
        </trigger>
        <trigger>
            <expression>{Template_AWS_RDS:RDS.CPUUtilization.Average.min(#3)}&gt;{$TH_P3_CPU_USAGE}</expression>
            <name>RDS::High CPU Usage (LV={ITEM.VALUE})</name>
            <url/>
            <status>0</status>
            <priority>3</priority>
            <description/>
            <type>0</type>
            <dependencies/>
        </trigger>
        <trigger>
            <expression>{Template_AWS_RDS:RDS.ReadLatency.Average.last()}&gt;{$TH_P3_LATENCY} and {Template_AWS_RDS:RDS.ReadLatency.Average.last()}&lt;{$TH_P2_LATENCY}</expression>
            <name>RDS::High Read Latency (LV={ITEM.VALUE})</name>
            <url/>
            <status>0</status>
            <priority>3</priority>
            <description/>
            <type>0</type>
            <dependencies/>
        </trigger>
        <trigger>
            <expression>{Template_AWS_RDS:RDS.ReadLatency.Average.last()}&gt;{$TH_P2_LATENCY}</expression>
            <name>RDS::High Read Latency (LV={ITEM.VALUE})</name>
            <url/>
            <status>0</status>
            <priority>4</priority>
            <description/>
            <type>0</type>
            <dependencies/>
        </trigger>
        <trigger>
            <expression>{Template_AWS_RDS:RDS.WriteLatency.Average.last()}&gt;{$TH_P2_LATENCY}</expression>
            <name>RDS::High Write Latency (LV={ITEM.VALUE})</name>
            <url/>
            <status>0</status>
            <priority>4</priority>
            <description/>
            <type>0</type>
            <dependencies/>
        </trigger>
        <trigger>
            <expression>{Template_AWS_RDS:RDS.WriteLatency.Average.last()}&gt;{$TH_P3_LATENCY} and {Template_AWS_RDS:RDS.WriteLatency.Average.last()}&lt;{$TH_P2_LATENCY}</expression>
            <name>RDS::High Write Latency (LV={ITEM.VALUE})</name>
            <url/>
            <status>0</status>
            <priority>3</priority>
            <description/>
            <type>0</type>
            <dependencies/>
        </trigger>
        <trigger>
            <expression>{Template_AWS_RDS:RDS.FreeStorageSpace.Minimum.last()}&lt;{$TH_P3_FREE_STORAGE} and {Template_AWS_RDS:RDS.FreeStorageSpace.Minimum.last()}&gt;{$TH_P2_FREE_STORAGE}</expression>
            <name>RDS::Low free storage space (LV={ITEM.VALUE})</name>
            <url/>
            <status>0</status>
            <priority>3</priority>
            <description/>
            <type>0</type>
            <dependencies/>
        </trigger>
        <trigger>
            <expression>{Template_AWS_RDS:RDS.FreeStorageSpace.Minimum.last()}&lt;{$TH_P2_FREE_STORAGE}</expression>
            <name>RDS::Low free storage space (LV={ITEM.VALUE})</name>
            <url/>
            <status>0</status>
            <priority>4</priority>
            <description/>
            <type>0</type>
            <dependencies/>
        </trigger>
    </triggers>
    <graphs>
        <graph>
            <name>RDS::DB Connections</name>
            <width>800</width>
            <height>200</height>
            <yaxismin>0.0000</yaxismin>
            <yaxismax>100.0000</yaxismax>
            <show_work_period>1</show_work_period>
            <show_triggers>1</show_triggers>
            <type>0</type>
            <show_legend>1</show_legend>
            <show_3d>0</show_3d>
            <percent_left>0.0000</percent_left>
            <percent_right>0.0000</percent_right>
            <ymin_type_1>1</ymin_type_1>
            <ymax_type_1>0</ymax_type_1>
            <ymin_item_1>0</ymin_item_1>
            <ymax_item_1>0</ymax_item_1>
            <graph_items>
                <graph_item>
                    <sortorder>0</sortorder>
                    <drawtype>5</drawtype>
                    <color>00C800</color>
                    <yaxisside>1</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.DatabaseConnections.Average</key>
                    </item>
                </graph_item>
            </graph_items>
        </graph>
        <graph>
            <name>RDS::IO Stats</name>
            <width>800</width>
            <height>200</height>
            <yaxismin>0.0000</yaxismin>
            <yaxismax>100.0000</yaxismax>
            <show_work_period>1</show_work_period>
            <show_triggers>1</show_triggers>
            <type>0</type>
            <show_legend>1</show_legend>
            <show_3d>0</show_3d>
            <percent_left>0.0000</percent_left>
            <percent_right>0.0000</percent_right>
            <ymin_type_1>1</ymin_type_1>
            <ymax_type_1>0</ymax_type_1>
            <ymin_item_1>0</ymin_item_1>
            <ymax_item_1>0</ymax_item_1>
            <graph_items>
                <graph_item>
                    <sortorder>0</sortorder>
                    <drawtype>5</drawtype>
                    <color>00CC00</color>
                    <yaxisside>1</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.ReadIOPS.Average</key>
                    </item>
                </graph_item>
                <graph_item>
                    <sortorder>1</sortorder>
                    <drawtype>5</drawtype>
                    <color>DDDD00</color>
                    <yaxisside>1</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.WriteIOPS.Average</key>
                    </item>
                </graph_item>
                <graph_item>
                    <sortorder>2</sortorder>
                    <drawtype>0</drawtype>
                    <color>CC0000</color>
                    <yaxisside>0</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.DiskQueueDepth.Average</key>
                    </item>
                </graph_item>
            </graph_items>
        </graph>
        <graph>
            <name>RDS::Latency</name>
            <width>800</width>
            <height>200</height>
            <yaxismin>0.0000</yaxismin>
            <yaxismax>100.0000</yaxismax>
            <show_work_period>1</show_work_period>
            <show_triggers>1</show_triggers>
            <type>0</type>
            <show_legend>1</show_legend>
            <show_3d>0</show_3d>
            <percent_left>0.0000</percent_left>
            <percent_right>0.0000</percent_right>
            <ymin_type_1>1</ymin_type_1>
            <ymax_type_1>0</ymax_type_1>
            <ymin_item_1>0</ymin_item_1>
            <ymax_item_1>0</ymax_item_1>
            <graph_items>
                <graph_item>
                    <sortorder>0</sortorder>
                    <drawtype>5</drawtype>
                    <color>00CC00</color>
                    <yaxisside>1</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.ReadThroughput.Average</key>
                    </item>
                </graph_item>
                <graph_item>
                    <sortorder>1</sortorder>
                    <drawtype>5</drawtype>
                    <color>DDDD00</color>
                    <yaxisside>1</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.WriteThroughput.Average</key>
                    </item>
                </graph_item>
                <graph_item>
                    <sortorder>2</sortorder>
                    <drawtype>0</drawtype>
                    <color>0000DD</color>
                    <yaxisside>0</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.ReadLatency.Average</key>
                    </item>
                </graph_item>
                <graph_item>
                    <sortorder>3</sortorder>
                    <drawtype>0</drawtype>
                    <color>DD0000</color>
                    <yaxisside>0</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.WriteLatency.Average</key>
                    </item>
                </graph_item>
            </graph_items>
        </graph>
        <graph>
            <name>RDS::Network Stats</name>
            <width>800</width>
            <height>200</height>
            <yaxismin>0.0000</yaxismin>
            <yaxismax>100.0000</yaxismax>
            <show_work_period>1</show_work_period>
            <show_triggers>1</show_triggers>
            <type>0</type>
            <show_legend>1</show_legend>
            <show_3d>0</show_3d>
            <percent_left>0.0000</percent_left>
            <percent_right>0.0000</percent_right>
            <ymin_type_1>1</ymin_type_1>
            <ymax_type_1>0</ymax_type_1>
            <ymin_item_1>0</ymin_item_1>
            <ymax_item_1>0</ymax_item_1>
            <graph_items>
                <graph_item>
                    <sortorder>0</sortorder>
                    <drawtype>5</drawtype>
                    <color>0000DD</color>
                    <yaxisside>1</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.NetworkReceiveThroughput.Average</key>
                    </item>
                </graph_item>
                <graph_item>
                    <sortorder>1</sortorder>
                    <drawtype>5</drawtype>
                    <color>00CC00</color>
                    <yaxisside>1</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.NetworkTransmitThroughput.Average</key>
                    </item>
                </graph_item>
            </graph_items>
        </graph>
        <graph>
            <name>RDS::Storage Stats</name>
            <width>800</width>
            <height>200</height>
            <yaxismin>0.0000</yaxismin>
            <yaxismax>100.0000</yaxismax>
            <show_work_period>1</show_work_period>
            <show_triggers>1</show_triggers>
            <type>0</type>
            <show_legend>1</show_legend>
            <show_3d>0</show_3d>
            <percent_left>0.0000</percent_left>
            <percent_right>0.0000</percent_right>
            <ymin_type_1>1</ymin_type_1>
            <ymax_type_1>0</ymax_type_1>
            <ymin_item_1>0</ymin_item_1>
            <ymax_item_1>0</ymax_item_1>
            <graph_items>
                <graph_item>
                    <sortorder>0</sortorder>
                    <drawtype>5</drawtype>
                    <color>0000DD</color>
                    <yaxisside>1</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.BinLogDiskUsage.Average</key>
                    </item>
                </graph_item>
                <graph_item>
                    <sortorder>1</sortorder>
                    <drawtype>5</drawtype>
                    <color>00CC00</color>
                    <yaxisside>1</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.FreeStorageSpace.Minimum</key>
                    </item>
                </graph_item>
            </graph_items>
        </graph>
        <graph>
            <name>RDS::System Stats</name>
            <width>800</width>
            <height>200</height>
            <yaxismin>0.0000</yaxismin>
            <yaxismax>100.0000</yaxismax>
            <show_work_period>1</show_work_period>
            <show_triggers>1</show_triggers>
            <type>0</type>
            <show_legend>1</show_legend>
            <show_3d>0</show_3d>
            <percent_left>0.0000</percent_left>
            <percent_right>0.0000</percent_right>
            <ymin_type_1>1</ymin_type_1>
            <ymax_type_1>0</ymax_type_1>
            <ymin_item_1>0</ymin_item_1>
            <ymax_item_1>0</ymax_item_1>
            <graph_items>
                <graph_item>
                    <sortorder>0</sortorder>
                    <drawtype>5</drawtype>
                    <color>0000EE</color>
                    <yaxisside>1</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.SwapUsage.Average</key>
                    </item>
                </graph_item>
                <graph_item>
                    <sortorder>1</sortorder>
                    <drawtype>5</drawtype>
                    <color>00C800</color>
                    <yaxisside>1</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.FreeableMemory.Minimum</key>
                    </item>
                </graph_item>
                <graph_item>
                    <sortorder>2</sortorder>
                    <drawtype>2</drawtype>
                    <color>EE0000</color>
                    <yaxisside>0</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.CPUUtilization.Average</key>
                    </item>
                </graph_item>
            </graph_items>
        </graph>
    </graphs>
</zabbix_export>

Запускаем скрипт:

# python3 Add_Hosts_from_AWS_RDS_to_Zabbix.py

PS: Не забываем ставить зависимости через pip3.

Вот и все, статья «Добавление RDS хостов в zabbix c использованием boto3 + python3» завершена.

The post Добавление RDS хостов в zabbix c использованием boto3 + python3 first appeared on linux-notes.org.]]>
https://linux-notes.org/dobavlenie-rds-hostov-v-zabbix-c-ispol-zovaniem-boto3-python3/feed/ 0
Page_c76a3fcf https://linux-notes.org/importirovanie-zabbix-templates/ https://linux-notes.org/importirovanie-zabbix-templates/#respond Tue, 26 Sep 2017 23:07:51 +0000 http://linux-notes.org/?p=13831 Импортирование zabbix templates Люблю оптимизировать рабочий процесс и данная тема — еще одно подтверждение моих слов. Я описывал процесс экспортирования заббикс шаблонов в своей статье: Экспортирование zabbix templates И сейчас я расскажу как я реализовал обратное действие — импортирование заббикс темплейтов. Мне пришлось немного потратить времени, чтобы написать данную реализацию. Мой скрипт: # vim zabbix_templates.py Он […]

The post Импортирование zabbix templates first appeared on linux-notes.org.]]>

Импортирование zabbix templates

Люблю оптимизировать рабочий процесс и данная тема — еще одно подтверждение моих слов.

Я описывал процесс экспортирования заббикс шаблонов в своей статье:

Экспортирование zabbix templates

И сейчас я расскажу как я реализовал обратное действие — импортирование заббикс темплейтов.

Мне пришлось немного потратить времени, чтобы написать данную реализацию.

Мой скрипт:

# vim zabbix_templates.py

Он выглядит следующим образом:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import requests
import time
import os
import xml.dom.minidom
import argparse
import gitlab
import glob
import sys

from datetime import datetime
from pyzabbix import ZabbixAPI, ZabbixAPIException
# from setuptools import setup, find_packages
from sys import exit


class Bgcolors:
    def __init__(self):
        self.get = {
            'HEADER': '\033[95m',
            'OKBLUE': '\033[94m',
            'OKGREEN': '\033[92m',
            'WARNING': '\033[93m',
            'FAIL': '\033[91m',
            'ENDC': '\033[0m',
            'BOLD': '\033[1m',
            'UNDERLINE': '\033[4m'
        }


def login_to_zabbix(z_host, z_user, z_password):
    # You can use the connection__timeout
    connection__timeout = 45
    # Verify SSL
    verify__ssl = False
    # Connect to zabbix-server
    zapi = ZabbixAPI(z_host, timeout=connection__timeout)
    zapi.session.verify = verify__ssl
    if not verify__ssl:
        from requests.packages.urllib3.exceptions import InsecureRequestWarning
        requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
    zapi.login(z_user, z_password)
    zapi.session.auth = (z_user, z_password)
    # You can re-define connection__timeout after
    zapi.timeout = connection__timeout
    return zapi


def get_template(z_host, z_user, z_password, template):
    zapi = login_to_zabbix(z_host, z_user, z_password)
    get__template = zapi.template.get(filter={"name": template}, output=['templateid', 'name'])
    return get__template


def export_template(z_host, z_user, z_password, dir_path, template):
    zapi = login_to_zabbix(z_host, z_user, z_password)
    get_template_name = get_template(template)
    if not os.path.exists(dir_path):
        os.makedirs(dir_path)
    template_id = get_template_name[0]['templateid']
    template_name = get_template_name[0]['name']
    rules = {
        "options": {
            "templates": [template_id]
        },
        "format": "xml"
    }
    template_name_out = dir_path + '/' + template_name + '.xml'
    result = zapi.do_request('configuration.export', rules)
    template = xml.dom.minidom.parseString(result['result'].encode('utf-8'))
    date = template.getElementsByTagName("date")[0]
    # We are backing these up to git, steralize date so it doesn't appear to change
    # each time we export the templates
    date.firstChild.replaceWholeText('1970-01-01T01:01:01Z')
    try:
        f = open(template_name_out, 'wb')
        f.write(template.toprettyxml().encode('utf-8'))
        f.close()
        print (template_name + '.xml', 'file has been created')
    except ValueError:
        print ('I cant write to file: ', ValueError)

    return export_template


def get_templates(z_host, z_user, z_password):
    templates = []
    zapi = login_to_zabbix(z_host, z_user, z_password)
    get__templates = zapi.template.get(output=['templateid', 'name'])
    for template in get__templates:
        templates.append(template)
    return templates


def export_templates(z_host, z_user, z_password, dir_path):
    zapi = login_to_zabbix(z_host, z_user, z_password)
    templates = get_templates(z_host, z_user, z_password)

    if not os.path.exists(dir_path):
        os.makedirs(dir_path)
    for template in templates:
        template_id = template['templateid']
        template_name = template['name']

        template_name_out = dir_path + '/' + template_name + '.xml'
        result = zapi.configuration.export(
            options={"templates": [template_id]},
            format='xml'
        )
        template = xml.dom.minidom.parseString(result.encode('utf-8'))
        date = template.getElementsByTagName("date")[0]
        # We are backing these up to git, steralize date so it doesn't appear to change
        # each time we export the templates
        date.firstChild.replaceWholeText('1970-01-01T01:01:01Z')
        try:
            f = open(template_name_out, 'wb')
            f.write(template.toprettyxml().encode('utf-8'))
            f.close()
            print (template_name + '.xml', 'file has been created')
        except ValueError:
            print('I cant write to file')

    return export_templates


def import_templates(z_host, z_user, z_password, dir_path, templates):
    global files
    zapi = login_to_zabbix(z_host, z_user, z_password)

    rules = {
        'applications': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'discoveryRules': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'graphs': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'groups': {
            'createMissing': 'true'
        },
        'hosts': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'images': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'items': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'maps': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'screens': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'templateLinkage': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'templates': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'templateScreens': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'triggers': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
    }
    if templates == 'all':
        files = glob.glob(dir_path + "/" + "*.xml")
    else:
        for template in templates:
            files = glob.glob(str(dir_path) + "/" + str(template) + ".xml")
    for f in files:
        with open(f, 'r') as file:
            template = file.read()
            try:
                zapi.confimport('xml', template, rules)
            except ZabbixAPIException as e:
                print(e)
    return import_templates


def export_groups(z_host, z_user, z_password):
    file_out = 'exported_groups.txt'
    if os.path.isfile(file_out):
        os.remove(file_out)
    zapi = login_to_zabbix(z_host, z_user, z_password)
    get__groups = zapi.hostgroup.get(output=['groupid', 'name'])
    try:
        for group in get__groups:
            f = open(file_out, 'a')
            f.write(str(group['name'] + '\n'))
            f.close()
        print("All groups has been exported to %s!" % file_out)
    except ValueError:
        print('I cant write to file')

    return export_groups


def export_autodiscovery_rules(z_host, z_user, z_password):
    file_out = 'exported_autodiscovery_rules.txt'
    if os.path.isfile(file_out):
        os.remove(file_out)
    zapi = login_to_zabbix(z_host, z_user, z_password)
    get__actions = zapi.action.get(selectOperations='extend', selectFilter='extend', filter={"eventsource": 2})
    try:
        for action in get__actions:
            print (action)
            # f = open(file_out, 'a')
            # f.write(json.loads(action))
            # f.close()
        # print("All autodiscovery rules has been exported to %s!" % file_out)
    except TypeError:
        print('I cant write to file')

    return export_autodiscovery_rules


def main():
    start__time = time.time()

    parser = argparse.ArgumentParser(prog='python3 script_name.py -h',
                                     usage='python3 script_name.py {ARGS}',
                                     add_help=True,
                                     prefix_chars='--/',
                                     epilog='''created by Vitalii Natarov''')
    parser.add_argument('--version', action='version', version='v1.0.0')
    parser.add_argument('--t', '--template', nargs='+', dest='template', help='Indicate a template(s)', default='all')
    parser.add_argument('--d', '--dir', dest='templates_dir', help='Indicate a folder for template(s)',
                        default='exported_templates', metavar='folder')
    parser.add_argument('--zabbix-host', dest='zabbix_host', help='Zabbix host',
                        default=None)
    parser.add_argument('--zabbix-user', dest='zabbix_user', help='Zabbix user', default=None)
    parser.add_argument('--zabbix-password', dest='zabbix_password', help='Zabbix password of user',
                        default=None)

    group = parser.add_mutually_exclusive_group(required=False)
    group.add_argument('--i', dest='imports', help='Import function', action='store_true')
    group.add_argument('--import', dest='imports', help='Import function', action='store_true')

    group2 = parser.add_mutually_exclusive_group(required=False)
    group2.add_argument('--e', dest='exports', help='Export function', action='store_true', default=argparse.SUPPRESS)
    group2.add_argument('--export', dest='exports', help='Export function', action='store_true')

    results = parser.parse_args()
    template = results.template
    templates_dir = results.templates_dir

    # host, login, password to connect to zabbix-server
    zabbix__host = results.zabbix_host
    zabbix__user = results.zabbix_user
    zabbix__password = results.zabbix_password

    if (zabbix__host is not None) and (zabbix__user is not None) and (zabbix__password is not None):
        zapi = login_to_zabbix(zabbix__host, zabbix__user, zabbix__password)
        zabbix__version = zapi.do_request('apiinfo.version')
        print(
            Bgcolors().get['OKGREEN'], "============================================================",
            Bgcolors().get['ENDC'])
        print(
            Bgcolors().get['OKGREEN'],
            'Zabbix Version:',
            zabbix__version['result'] + Bgcolors().get['ENDC'])
        print(
            Bgcolors().get['OKGREEN'],
            "============================================================",
            Bgcolors().get['ENDC'])
        if results.exports:
            print ('EXPORT function!')
            if template == 'all':
                export_templates(zabbix__host, zabbix__user, zabbix__password, templates_dir)
            else:
                export_template(zabbix__host, zabbix__user, zabbix__password, templates_dir, template)
            export_groups(zabbix__host, zabbix__user, zabbix__password)
            #export_autodiscovery_rules(zabbix__host, zabbix__user, zabbix__password)
        elif results.imports:
            print('IMPORT function')
            import_templates(zabbix__host, zabbix__user, zabbix__password, templates_dir, template)
        else:
            print('Please add [--e] for export or [--i] for import')
            print('For help, use: script_name.py -h')
            exit(0)
    else:
        print('Please add [--zabbix-host] or [--zabbix-user] or [--zabbix-password]')
        print('For help, use: script_name.py -h')
        exit(0)

    end__time = round(time.time() - start__time, 2)
    print("--- %s seconds ---" % end__time)

    print(
        Bgcolors().get['OKGREEN'], "============================================================",
        Bgcolors().get['ENDC'])
    print(
        Bgcolors().get['OKGREEN'], "==========================FINISHED==========================",
        Bgcolors().get['ENDC'])
    print(
        Bgcolors().get['OKGREEN'], "============================================================",
        Bgcolors().get['ENDC'])


if __name__ == '__main__':
    main()

На мой взгляд, получилось не плохая реализация.

Для использования, введите:

# python3 zabbix_templates.py -h

Это выведит помощь:

usage: python3 script_name.py {ARGS}

optional arguments:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  --t TEMPLATE [TEMPLATE ...], --template TEMPLATE [TEMPLATE ...]
                        Indicate a template(s)
  --d folder, --dir folder
                        Indicate a folder for template(s)
  --i                   Import function
  --import              Import function
  --e                   Export function
  --export              Export function

created by Vitalii Natarov

Т.е, чтобы заэкспортировать все щаблоны, используйте:

$ python3 Export_Templates_from_Zabbix.py --zabbix-host "https://zabbix.local" --zabbix-user "cleanup_apiuser" --zabbix-password "fdsdsfdsfs" --e

PS: Так же, можно указать папку, в которую будет складыватся шаблоны:

$ python3 Export_Templates_from_Zabbix.py --zabbix-host "https://zabbix.local" --zabbix-user "cleanup_apiuser" --zabbix-password "fdsdsfdsfs" --d some_folder

Если не нужно экспортировать все шаблоны, а есть необходимость в одном, можно использовать:

$ python3 Export_Templates_from_Zabbix.py --zabbix-host "https://zabbix.local" --zabbix-user "cleanup_apiuser" --zabbix-password "fdsdsfdsfs" --d some_folder --t "some_template"

Для импорта, аналогичные действия:

$ python3 Export_Templates_from_Zabbix.py --zabbix-host "https://ui-zabbix.local" --zabbix-user "cleanup_apiuser" --zabbix-password "fdsdsfdsfs" --i

Или:

$ python3 Export_Templates_from_Zabbix.py --zabbix-host "https://zabbix.local" --zabbix-user "cleanup_apiuser" --zabbix-password "fdsdsfdsfs" --i --d some_folder

Или:

$ python3 Export_Templates_from_Zabbix.py --zabbix-host "https://zabbix.local" --zabbix-user "cleanup_apiuser" --zabbix-password "fdsdsfdsfs" --i --d some_folder --t "some_template"

Он полностью готовый, только нужно вписать URL, USER, PASSWORD для заббикса.

А на этом, я завершаю свою статью «Импортирование zabbix templates».

The post Импортирование zabbix templates first appeared on linux-notes.org.]]>
https://linux-notes.org/importirovanie-zabbix-templates/feed/ 0
Page_c76a3fcf https://linux-notes.org/e-ksportirovanie-zabbix-templates/ https://linux-notes.org/e-ksportirovanie-zabbix-templates/#respond Wed, 30 Aug 2017 20:44:41 +0000 http://linux-notes.org/?p=13749 Экспортирование zabbix templates В последнее время, я начал плотно изучать python и zabbix API для автоматизации различных процессов. Последнее что пришло на ум — это выполнить экспорт всех zabbix шаблонов. Для этой цели, я создал скрипт: # cat Export_Templates_from_Zabbix.py Который имеет следующее содержание: #!/usr/bin/env python3 # -*- coding: utf-8 -*- import requests import time import os […]

The post Экспортирование zabbix templates first appeared on linux-notes.org.]]>

Экспортирование zabbix templates

В последнее время, я начал плотно изучать python и zabbix API для автоматизации различных процессов. Последнее что пришло на ум — это выполнить экспорт всех zabbix шаблонов.

Для этой цели, я создал скрипт:

# cat Export_Templates_from_Zabbix.py

Который имеет следующее содержание:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import requests
import time
import os
import xml.dom.minidom
import argparse
import gitlab
import glob
import sys

from datetime import datetime
from pyzabbix import ZabbixAPI, ZabbixAPIException
# from setuptools import setup, find_packages
from sys import exit


class Bgcolors:
    def __init__(self):
        self.get = {
            'HEADER': '\033[95m',
            'OKBLUE': '\033[94m',
            'OKGREEN': '\033[92m',
            'WARNING': '\033[93m',
            'FAIL': '\033[91m',
            'ENDC': '\033[0m',
            'BOLD': '\033[1m',
            'UNDERLINE': '\033[4m'
        }


def login_to_zabbix(z_host, z_user, z_password):
    # You can use the connection__timeout
    connection__timeout = 45
    # Verify SSL
    verify__ssl = False
    # Connect to zabbix-server
    zapi = ZabbixAPI(z_host, timeout=connection__timeout)
    zapi.session.verify = verify__ssl
    if not verify__ssl:
        from requests.packages.urllib3.exceptions import InsecureRequestWarning
        requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
    zapi.login(z_user, z_password)
    zapi.session.auth = (z_user, z_password)
    # You can re-define connection__timeout after
    zapi.timeout = connection__timeout
    return zapi


def get_template(z_host, z_user, z_password, template):
    zapi = login_to_zabbix(z_host, z_user, z_password)
    get__template = zapi.template.get(filter={"name": template}, output=['templateid', 'name'])
    return get__template


def export_template(z_host, z_user, z_password, dir_path, template):
    zapi = login_to_zabbix(z_host, z_user, z_password)
    get_template_name = get_template(template)
    if not os.path.exists(dir_path):
        os.makedirs(dir_path)
    template_id = get_template_name[0]['templateid']
    template_name = get_template_name[0]['name']
    rules = {
        "options": {
            "templates": [template_id]
        },
        "format": "xml"
    }
    template_name_out = dir_path + '/' + template_name + '.xml'
    result = zapi.do_request('configuration.export', rules)
    template = xml.dom.minidom.parseString(result['result'].encode('utf-8'))
    date = template.getElementsByTagName("date")[0]
    # We are backing these up to git, steralize date so it doesn't appear to change
    # each time we export the templates
    date.firstChild.replaceWholeText('1970-01-01T01:01:01Z')
    try:
        f = open(template_name_out, 'wb')
        f.write(template.toprettyxml().encode('utf-8'))
        f.close()
        print (template_name + '.xml', 'file has been created')
    except ValueError:
        print ('I cant write to file: ', ValueError)

    return export_template


def get_templates(z_host, z_user, z_password):
    templates = []
    zapi = login_to_zabbix(z_host, z_user, z_password)
    get__templates = zapi.template.get(output=['templateid', 'name'])
    for template in get__templates:
        templates.append(template)
    return templates


def export_templates(z_host, z_user, z_password, dir_path):
    zapi = login_to_zabbix(z_host, z_user, z_password)
    templates = get_templates(z_host, z_user, z_password)

    if not os.path.exists(dir_path):
        os.makedirs(dir_path)
    for template in templates:
        template_id = template['templateid']
        template_name = template['name']

        template_name_out = dir_path + '/' + template_name + '.xml'
        result = zapi.configuration.export(
            options={"templates": [template_id]},
            format='xml'
        )
        template = xml.dom.minidom.parseString(result.encode('utf-8'))
        date = template.getElementsByTagName("date")[0]
        # We are backing these up to git, steralize date so it doesn't appear to change
        # each time we export the templates
        date.firstChild.replaceWholeText('1970-01-01T01:01:01Z')
        try:
            f = open(template_name_out, 'wb')
            f.write(template.toprettyxml().encode('utf-8'))
            f.close()
            print (template_name + '.xml', 'file has been created')
        except ValueError:
            print('I cant write to file')

    return export_templates


def import_templates(z_host, z_user, z_password, dir_path, templates):
    global files
    zapi = login_to_zabbix(z_host, z_user, z_password)

    rules = {
        'applications': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'discoveryRules': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'graphs': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'groups': {
            'createMissing': 'true'
        },
        'hosts': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'images': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'items': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'maps': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'screens': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'templateLinkage': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'templates': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'templateScreens': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'triggers': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
    }
    if templates == 'all':
        files = glob.glob(dir_path + "/" + "*.xml")
    else:
        for template in templates:
            files = glob.glob(str(dir_path) + "/" + str(template) + ".xml")
    for f in files:
        with open(f, 'r') as file:
            template = file.read()
            try:
                zapi.confimport('xml', template, rules)
            except ZabbixAPIException as e:
                print(e)
    return import_templates


def export_groups(z_host, z_user, z_password):
    file_out = 'exported_groups.txt'
    if os.path.isfile(file_out):
        os.remove(file_out)
    zapi = login_to_zabbix(z_host, z_user, z_password)
    get__groups = zapi.hostgroup.get(output=['groupid', 'name'])
    try:
        for group in get__groups:
            f = open(file_out, 'a')
            f.write(str(group['name'] + '\n'))
            f.close()
        print("All groups has been exported to %s!" % file_out)
    except ValueError:
        print('I cant write to file')

    return export_groups


def export_autodiscovery_rules(z_host, z_user, z_password):
    file_out = 'exported_autodiscovery_rules.txt'
    if os.path.isfile(file_out):
        os.remove(file_out)
    zapi = login_to_zabbix(z_host, z_user, z_password)
    get__actions = zapi.action.get(selectOperations='extend', selectFilter='extend', filter={"eventsource": 2})
    try:
        for action in get__actions:
            print (action)
            # f = open(file_out, 'a')
            # f.write(json.loads(action))
            # f.close()
        # print("All autodiscovery rules has been exported to %s!" % file_out)
    except TypeError:
        print('I cant write to file')

    return export_autodiscovery_rules


def main():
    start__time = time.time()

    parser = argparse.ArgumentParser(prog='python3 script_name.py -h',
                                     usage='python3 script_name.py {ARGS}',
                                     add_help=True,
                                     prefix_chars='--/',
                                     epilog='''created by Vitalii Natarov''')
    parser.add_argument('--version', action='version', version='v1.0.0')
    parser.add_argument('--t', '--template', nargs='+', dest='template', help='Indicate a template(s)', default='all')
    parser.add_argument('--d', '--dir', dest='templates_dir', help='Indicate a folder for template(s)',
                        default='exported_templates', metavar='folder')
    parser.add_argument('--zabbix-host', dest='zabbix_host', help='Zabbix host',
                        default=None)
    parser.add_argument('--zabbix-user', dest='zabbix_user', help='Zabbix user', default=None)
    parser.add_argument('--zabbix-password', dest='zabbix_password', help='Zabbix password of user',
                        default=None)

    group = parser.add_mutually_exclusive_group(required=False)
    group.add_argument('--i', dest='imports', help='Import function', action='store_true')
    group.add_argument('--import', dest='imports', help='Import function', action='store_true')

    group2 = parser.add_mutually_exclusive_group(required=False)
    group2.add_argument('--e', dest='exports', help='Export function', action='store_true', default=argparse.SUPPRESS)
    group2.add_argument('--export', dest='exports', help='Export function', action='store_true')

    results = parser.parse_args()
    template = results.template
    templates_dir = results.templates_dir

    # host, login, password to connect to zabbix-server
    zabbix__host = results.zabbix_host
    zabbix__user = results.zabbix_user
    zabbix__password = results.zabbix_password

    if (zabbix__host is not None) and (zabbix__user is not None) and (zabbix__password is not None):
        zapi = login_to_zabbix(zabbix__host, zabbix__user, zabbix__password)
        zabbix__version = zapi.do_request('apiinfo.version')
        print(
            Bgcolors().get['OKGREEN'], "============================================================",
            Bgcolors().get['ENDC'])
        print(
            Bgcolors().get['OKGREEN'],
            'Zabbix Version:',
            zabbix__version['result'] + Bgcolors().get['ENDC'])
        print(
            Bgcolors().get['OKGREEN'],
            "============================================================",
            Bgcolors().get['ENDC'])
        if results.exports:
            print ('EXPORT function!')
            if template == 'all':
                export_templates(zabbix__host, zabbix__user, zabbix__password, templates_dir)
            else:
                export_template(zabbix__host, zabbix__user, zabbix__password, templates_dir, template)
            export_groups(zabbix__host, zabbix__user, zabbix__password)
            #export_autodiscovery_rules(zabbix__host, zabbix__user, zabbix__password)
        elif results.imports:
            print('IMPORT function')
            import_templates(zabbix__host, zabbix__user, zabbix__password, templates_dir, template)
        else:
            print('Please add [--e] for export or [--i] for import')
            print('For help, use: script_name.py -h')
            exit(0)
    else:
        print('Please add [--zabbix-host] or [--zabbix-user] or [--zabbix-password]')
        print('For help, use: script_name.py -h')
        exit(0)

    end__time = round(time.time() - start__time, 2)
    print("--- %s seconds ---" % end__time)

    print(
        Bgcolors().get['OKGREEN'], "============================================================",
        Bgcolors().get['ENDC'])
    print(
        Bgcolors().get['OKGREEN'], "==========================FINISHED==========================",
        Bgcolors().get['ENDC'])
    print(
        Bgcolors().get['OKGREEN'], "============================================================",
        Bgcolors().get['ENDC'])


if __name__ == '__main__':
    main()

Запускаем:

# python3 Export_Templates_from_Zabbix.py --zabbix-host "https://zabbix.local" --zabbix-user "cleanup_apiuser" --zabbix-password "fdsfsdff" --dir exported_zabbix_templates_PROD_OLD --e

Вывод получим:

 ============================================================
 Zabbix Version: 2.4.8
 ============================================================
Template OS Linux.xml file has been created
Template App Zabbix Server.xml file has been created
Template App Zabbix Proxy.xml file has been created
Template App Zabbix Agent.xml file has been created
Template SNMP Interfaces.xml file has been created
Template SNMP Generic.xml file has been created
Template SNMP Device.xml file has been created
Template SNMP OS Windows.xml file has been created
Template SNMP Disks.xml file has been created
Template SNMP OS Linux.xml file has been created
Template SNMP Processors.xml file has been created
Template IPMI Intel SR1530.xml file has been created
Template IPMI Intel SR1630.xml file has been created
Template App MySQL.xml file has been created
Template OS OpenBSD.xml file has been created
Template OS FreeBSD.xml file has been created
Template OS AIX.xml file has been created
Template OS HP-UX.xml file has been created
Template OS Solaris.xml file has been created
Template OS Mac OS X.xml file has been created
Template OS Windows.xml file has been created
Template JMX Generic.xml file has been created
Template JMX Tomcat.xml file has been created
Template Virt VMware.xml file has been created
Template Virt VMware Guest.xml file has been created
Template Virt VMware Hypervisor.xml file has been created
Template App FTP Service.xml file has been created
Template App HTTP Service.xml file has been created
Template App HTTPS Service.xml file has been created
Template App IMAP Service.xml file has been created
Template App LDAP Service.xml file has been created
Template App NNTP Service.xml file has been created
Template App NTP Service.xml file has been created
Template App POP Service.xml file has been created
Template App SMTP Service.xml file has been created
Template App SSH Service.xml file has been created
Template_role_App_Puppet.xml file has been created
Template_AWS_RDS.xml file has been created
--- 223.18 seconds ---
 ============================================================
 ==========================FINISHED==========================
 ============================================================

PS: Данный скрипт поддерживает и импорт дашбордов. Но кое-что в нем все еще чтоит оптимизировать!

Для поддержки, можно выполнить:

$ python3 Export_Templates_from_Zabbix.py --h

usage: python3 script_name.py {ARGS}

optional arguments:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  --t TEMPLATE [TEMPLATE ...], --template TEMPLATE [TEMPLATE ...]
                        Indicate a template(s)
  --d folder, --dir folder
                        Indicate a folder for template(s)
  --zabbix-host ZABBIX_HOST
                        Zabbix host
  --zabbix-user ZABBIX_USER
                        Zabbix user
  --zabbix-password ZABBIX_PASSWORD
                        Zabbix password of user
  --i                   Import function
  --import              Import function
  --e                   Export function
  --export              Export function

created by Vitalii Natarov

Такой скрипт, можно закинуть в crontab, чтобы выполнялся бэкап автоматически. У меня появилась идея  — это в указанную папку, установить GIT, который будет коммитить (версионировать) ваши шаблоны в определенную, созданную ветку. При необходимости, можно будет смерджить в мастер (как вариант). Это даст возможность откатить все изменения до нужного состояния.

На этом у меня все, статья «Экспортирование zabbix templates» завершена.

The post Экспортирование zabbix templates first appeared on linux-notes.org.]]>
https://linux-notes.org/e-ksportirovanie-zabbix-templates/feed/ 0
Page_c76a3fcf https://linux-notes.org/ustanovka-collectd-v-unix-linux/ https://linux-notes.org/ustanovka-collectd-v-unix-linux/#respond Mon, 14 Aug 2017 10:32:33 +0000 http://linux-notes.org/?p=11759 Установка Collectd в Unix/Linux Collectd — это легковесный демон, который собирает статы (каждые 10 сек) о использовании системных ресурсов. Он позволяет собирать данные с нескольких хостов и отправлять их на централизованный сервер для дальнейшего использования (Например, можно использовать influxDB и потом с данной БД, строить графики в grafana). Главное отличие данного ПО, — это в […]

The post Установка Collectd в Unix/Linux first appeared on linux-notes.org.]]>

Установка Collectd в Unix/Linux

Collectd — это легковесный демон, который собирает статы (каждые 10 сек) о использовании системных ресурсов. Он позволяет собирать данные с нескольких хостов и отправлять их на централизованный сервер для дальнейшего использования (Например, можно использовать influxDB и потом с данной БД, строить графики в grafana). Главное отличие данного ПО, — это в том, что работает как push (а не poll/pull). Это означает что он находится в ожидании и ждет пока другие хосты пришлют ему данные по серверу.

Установка Collectd в Unix/Linux

Сейчас я, расскажу как можно установить данную утилиту на различные Unix/Linux ОС.

Установка Collectd в CentOS/Fedora/RedHat

Я приведу несколько способов по установке данного ПО.

-===СПОСОБ 1===-

Подключаем EPEL репозиторий —включить EPEL репозиторий и потом выполняем:

# yum install collectd -y

-===СПОСОБ 2===-

Поскольку мы собираем CollectD из исходного кода, нам нужен компилятор:

# yum install -y bzip2 wget
# yum install -y make automake gcc gcc-c++ kernel-devel perl-devel

Загружаем CollectD (на момент написания статьи, я использовал самую новую версию):

# cd /usr/local/src/ && wget https://collectd.org/files/collectd-5.7.2.tar.bz2
# tar -jxf collectd-*.tar.bz2
# cd collectd-5.5.0

PS: Компилятор Fedora может выдать ошибку, которая выглядят следующим образом:

error: #warning “_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE” [-Werror=cpp]

Для этого стоит выключить «warning»:

export CFLAGS="-Wno-error"

Ну что, пришло время компиляции:

# ./configure && make all install

Чтобы менеджить CollectD на CentOS/Fedora с использованием systemd, можно следующим образом:

# cd /etc/systemd/system/ && wget https://raw.githubusercontent.com/martin-magakian/collectd-script/master/collectd.service
# chmod +x collectd.service

CollectD теперь будет запускаться при запуске ОС, но вы все равно сможете управлять им вручную:

# systemctl start collectd.service
# systemctl stop collectd.service
# systemctl status collectd.service
# systemctl restart collectd.service

Полезное чтиво по systemd:

Система инициализации в Unix/Linux

Система инициализации Systemd

Пишем systemd Unit файл

PS:  Так же можно найти init.d скрипт в архиве и его можно использовать:

# cp -r /usr/local/src/contrib/redhat/init.d-collectd /etc/init.d/collectd
# chmod +x /etc/init.d/collectd

И для запуска будет служить следующая команда:

# service collectd start

По умолчанию, вы можете найти:

  • Конфиг-файл —  /opt/collectd/etc/collectd.conf
  • Бинарник с collectd — /opt/collectd/sbin/collectd

Можно добавить службу в автозагурзку ОС:

# chkconfig collectd on
# chkconfig --level 5 collectd on

Или, если используете systemd:

# systemctl enable collectd

Вот и все.

Установка Collectd в Debian/Ubuntu

Я приведу несколько способов по установке данного ПО.

-===СПОСОБ 1===-

Установка очень простая, нужно выполнить:

# apt-get install collectd -y

Если имеется Debian, можно использовать репозиторий, т.к в дебиановских стандартных портах, collectd — нет, для этого нам надо подключить backports:

# vim /etc/apt/sources.list.d/backports.repo

Добавляем строчку:

deb http://backports.debian.org/debian-backports squeeze-backports main

В нашем случае это будет выглядеть как

# apt-get -t squeeze-backports install "collectd"

-===СПОСОБ 2===-

Поскольку мы собираем CollectD из исходного кода, нам нужен компилятор:

# apt-get install build-essential

Загружаем CollectD (на момент написания статьи, я использовал самую новую версию):

# cd /usr/local/src/ && wget https://collectd.org/files/collectd-5.7.2.tar.bz2 
# tar -jxf collectd-*.tar.bz2
# cd collectd-* && ./configure && make all install

По умолчанию, вы можете найти:

  • Конфиг-файл —  /opt/collectd/etc/collectd.conf
  • Бинарник с collectd — /opt/collectd/sbin/collectd

Чтобы менеджить CollectD на Debian/Ubuntu, можно следующим образом:

# wget -O /etc/init.d/collectd https://raw.githubusercontent.com/martin-magakian/collectd-script/master/collectd.init
# chmod 744 /etc/init.d/collectd

CollectD теперь будет запускаться при запуске ОС, но вы все равно сможете управлять им вручную:

service collectd start
service collectd stop
service collectd status
service collectd restart

Можно добавить службу в автозагурзку ОС:

# update-rc.d collectd enable
# update-rc.d rc.local enable

Вот и все.

Установка Collectd на другие Unix/Linux ОС

Я приведу несколько способов по установке данного ПО.

-===СПОСОБ 1===-

Использовать docker, но мне это не нужно было еще. По этому, я опишу данный процесс немного позже (как прийдет время).

-===СПОСОБ 2===-

Использовать исходный код (я описывал данный процесс выше).

Установка дополнительные компоненты для Collectd

Выполняем установку ПО для Deb’s ОС:

# apt-get install git -y
# apt-get install librrds-perl libjson-perl libhtml-parser-perl -y

Выполняем установку ПО для RPM’s ОС:

# yum install git -y
# yum install rrdtool rrdtool-devel rrdtool-perl perl-HTML-Parser perl-JSON -y

Скачиваем Collectd-Web:

# cd /usr/local/ && git clone https://github.com/httpdss/collectd-web.git

Выставим права:

# chmod +x /usr/local/collectd-web/cgi-bin/graphdefs.cgi

По умолчанию, веб-сервер будет работать на 127.0.0.1. Чтобы можно было подключаться из-вне, нужно отредактировать скрипт runerver.py и изменить IP-адрес 127.0.1.1 на 0.0.0.0:

# vim /usr/local/collectd-web/runserver.py

PS: Так же, можно изменить порт (по умолчанию используется 8888).

После того как вы изменили скрипт, запустите сервер в фоновом режиме, выпустив следующую команду:

# python /usr/local/collectd-web/runserver.py &

Теперь, можно открыть URL с указанным портом и использовать.

Чтобы легче управлять сервисом (запуск, стоп или просмотр состояния), создайте следующий баш-скрипт:

# vim /usr/local/bin/collectd-server

И прописываем в него:

#!/bin/bash
PORT="8888"
case $1 in
start)
cd /usr/local/collectd-web/
python runserver.py 2> /tmp/collectd.log &
sleep 1
stat=`netstat -tlpn 2>/dev/null | grep $PORT | grep "python"| cut -d":" -f2 | cut -d" " -f1`
if [[ $PORT -eq $stat ]]; then
sock=`netstat -tlpn 2>/dev/null | grep $PORT | grep "python"`
echo -e "Server is  still running:\n$sock"
else
echo -e "Server has stopped"
fi
;;
stop)
pid=`ps -x | grep "python runserver.py" | grep -v "color"`
kill -9 $pid 2>/dev/null
stat=`netstat -tlpn 2>/dev/null | grep $PORT | grep "python"| cut -d":" -f2 | cut -d" " -f1`
if [[ $PORT -eq $stat ]]; then
sock=`netstat -tlpn 2>/dev/null | grep $PORT | grep "python"`
echo -e "Server is  still running:\n$sock"
else
echo -e "Server has stopped"
fi
;;
status)
stat=`netstat -tlpn 2>/dev/null |grep $PORT| grep "python" | cut -d":" -f2 | cut -d" " -f1`
if [[ $PORT -eq $stat ]]; then
sock=`netstat -tlpn 2>/dev/null | grep $PORT | grep "python"`
echo -e "Server is running:\n$sock"
else
echo -e "Server is stopped"
fi
;;
*)
echo "Use $0 start|stop|status"
;;
esac

Начнем юзать его, но нужно еще выставить нужные права:

# chmod +x /usr/local/bin/collectd-server

Использование:

# collectd-server start 
# collectd-server status 
# collectd-server stop

Вот и все.

Настройка Collectd в Unix/Linux

И так, уже подошли к настройке данного сервиса. Открываем конфиг-файл:

# cat /etc/collectd.conf

И, изменяем хостнейм:

Hostname "grafana.local"
FQDNLookup true

Остальное пока что оставим как есть.

Настройка плагинов для CollectD

У collectd довольно большое количество встроенных плагинов. Я приведу пример некоторых из них.

Плагин для MYSQL

Добавляем (можно раскоментировать) следующую строку (секция LoadPlugin section):

LoadPlugin mysql

И добавляем следующие строки, в секцию «Plugin configuration»:

<Plugin mysql>
  <Database Your_DB_Name_1>
    Host "Your_IP_or_HOST"
    Port "3306"
    User "Your_User_Name"
    Password "Your_PassWord_for_Your_User_Name"
    Database "databasename"
    MasterStats true
  </Database>
  <Database Your_DB_Name_2>
    Host "Your_IP_or_HOST"
    Port "3306"
    User "Your_User_Name"
    Password "Your_PassWord_for_Your_User_Name"
    Database "databasename2"
    MasterStats true
  </Database>
</Plugin>

Нужно изменить некоторые из параметров. Но тут интуитивно все понятно, я не хотел бы заострять внимание на этом шаге.

Плагин для NGINX

Проверяем, установлен ли HttpStubStatusModule с помощью следующей команды:

# nginx -V 2>&1 | grep -o with-http_stub_status_module

В ваш конфиг самого nginx, дописываем следующую секцию:

location /nginx_status {
    stub_status on;
    access_log off;
    allow YOUR_ALLOWED_IP; 
    deny all;
  }

По аналогии с предыдущим плагином, подключаем плагин для nginx:

LoadPlugin nginx

И прописываем настройки:

<Plugin nginx>
URL "https://your_domain_name/nginx_status"
VerifyPeer false
VerifyHost false
</Plugin>

Плагины cpu, uptime, memory, users

В конфиг добавляем строки:

LoadPlugin memory
LoadPlugin uptime
LoadPlugin users
LoadPlugin cpu

Данные плагины не нуждаются в настройках.

Плагин swap

Если юзаете SWAP и нужно отмониторить его, то можете использовать данный плагин для этой цели. Сново, открываем конфиг-файл и прописываем:

LoadPlugin swap

И добавляем:

<Plugin swap>
ReportByDevice false
ReportBytes true
</Plugin>

Плагин vmem

В тот самый файл с конфигурацией, прописываем:

LoadPlugin vmem

И для плагина вписываем настройки:

<Plugin vmem>
Verbose false
</Plugin>

Плагин syslog

В тот самый файл с конфигурацией, прописываем:

LoadPlugin syslog

И для плагина вписываем настройки:

<Plugin syslog>
LogLevel info
</Plugin>

Плагин bind

Если используете bind9 в качестве DNS-сервера, то подключите этот плагин. Добавляем:

LoadPlugin bind

Вписываем настройки для плагина:

<Plugin "bind">
URL "http://localhost:8053/"

ParseTime false

OpCodes true
QTypes true
ServerStats true
ZoneMaintStats true
ResolverStats false
MemoryStats true

<View "_default">
QTypes true
ResolverStats true
CacheRRSets true
Zone "your.domain.com/IN" # Тут указываем зону, которую плагин будет проверять
</View>
<View "_default2">
# Таких секций может быть много
</View>
</Plugin>

Плагин df

Нужен для проверки места на вашем диске. Загружаем плагин:

LoadPlugin df

Вписываем настройки для плагина:

<Plugin df>
Device "/dev/sda1" 
MountPoint "/" 
FSType "ext3" 
FSType rootfs
FSType sysfs
FSType proc
FSType devtmpfs
FSType devpts
FSType tmpfs
FSType fusectl
FSType cgroup
IgnoreSelected true
ReportByDevice false
ReportReserved false
ReportInodes false
ValuesAbsolute true
ValuesPercentage false
</Plugin>

Где:

  • Device «/dev/sda1»  — стоит указать имя вашего раздела
  • MountPoint «/»  — служит точкой монтирования раздела
  • FSType «ext3» — собственно, тип ФС

Плагин disk

Данный плагин, имеет что-то общее с предыдущим плагином, но выводит др метрики. Сново, загружаем плагин:

LoadPlugin disk

Вписываем настройки для плагина:

<Plugin disk>
Disk "sda" 
Disk "/sda[1,2,3,4,5,6,7,8,9]/" # Список разделов по номерам
IgnoreSelected false
</Plugin>

Где:

  • Disk «sda»  —  Имя диска
  • Disk «/sda[1,2,3,4,5,6,7,8,9]/» — Список разделов по номерам

Плагин ping

Загружаем плагин:

LoadPlugin ping

Вписываем настройки для плагина:

<Plugin ping>
Host "www.google.com"
Interval 1.0
Timeout 0.9
TTL 255
SourceAddress "8.8.8.8"
Device "eth0"
MaxMissed -1
</Plugin>

Плагин StatD для CollectD

Загружаем:

LoadPlugin statsd

Вписываем настройки для плагина:

<Plugin statsd>
  Host "0.0.0.0"
  Port "8125"
  DeleteSets     true
</Plugin>

Собственно, если есть необходимость, то измените 0.0.0.0 чтобы слушал только определенный IP адрес (сейчас слушает все).

Для проверки, можно вызвать:

$ echo "my_first.metric:1|c" | nc -w 1 -u 127.0.0.1 8125
$ echo "my_first.metric:4|c" | nc -w 1 -u 127.0.0.1 8125

Записывать CollectD метрики в InfluxDB

Загружаем плагин:

LoadPlugin network

Вписываем настройки для плагина:

<Plugin network>
#       # client setup:
#       Server "ff18::efc0:4a42" "25826"
       <Server "your_influxdb_server_or_IP" "25826">
#               SecurityLevel Encrypt
#               Username "user"
#               Password "secret"
#               Interface "eth0"
       </Server>
#       TimeToLive "128"
#
#       # server setup:
#       Listen "ff18::efc0:4a42" "25826"
        #<Listen "192.168.13.187" "25826">
#        <Listen "your_influxdb_server_or_IP" "25826">
                #SecurityLevel Sign
                #AuthFile "/etc/collectd/passwd"
                #Interface "eth0"
#        </Listen>
#       MaxPacketSize 1024
#
#       # proxy setup (client and server as above):
#       Forward true
#
#       # statistics about the network plugin itself
#       ReportStats false
#
#       # "garbage collection"
#       CacheFlush 1800
</Plugin>

Где:

  • your_influxdb_server_or_IP — Это URL или IP-адрес вашего сервера с InfluxDB.
  • 25826 — Это порт на котором InfluxDB будет слушать метрики с CollectD.

Запускаем (перезапускаем):

# service collectd restart

Смотрим чтобы слушался интерфейс:

# netstat -tulpn| grep collectd

Можно настроить шифрованное соединение и весь трафик будет шифроваться, для этого:

# mkdir /etc/collectd && htpasswd -c /etc/collectd/passwd collectd_user

Смотрим какой пользователь и пароль создался ( я имею ввиду в шифрованном виде):

# cat /etc/collectd/passwd

После чего, открываем:

# vim /etc/collectd.conf

И приводим к виду:

<Plugin network>
#       # client setup:
#       Server "ff18::efc0:4a42" "25826"
        <Server "192.168.13.187" "25826">
                SecurityLevel Encrypt
                Username "collectd_user"
                Password "your_server_passwd_hash_password"
#               Interface "eth0"
        </Server>
#       TimeToLive "128"
#
#       # server setup:
#       Listen "ff18::efc0:4a42" "25826"
        #<Listen "192.168.13.187" "25826">
        <Listen "0.0.0.0" "25826">
                SecurityLevel Sign
                AuthFile "/etc/collectd/passwd"
                #Interface "eth0"
        </Listen>
#       MaxPacketSize 1024
#
#       # proxy setup (client and server as above):
#       Forward true
#
#       # statistics about the network plugin itself
#       ReportStats false
#
#       # "garbage collection"
#       CacheFlush 1800
</Plugin>

Перезапускаем службу:

# service collectd restart

PS: У меня это дело не заработала на 1-й машине. Пока что не знаю почему…. Постараюсь выяснить и исправить.

Полезное чтиво:

Установка InfluxDB в Unix/Linux

Настройка Grafana с Graphite/Zabbix/Prometheus/MySQL/InfluxDB/Elasticsearch/CloudWatch для сбора и отображения метрик в Unix/Linux

Открываем конфиг influxdb:

# cat /etc/influxdb/influxdb.conf

и приводим к виду:

[[collectd]]
  enabled = true
  #address = "0.0.0.0" # If not set, is actually set to bind-address.
  #port = 25826
  database = "collectd_db"
   bind-address = "collectd_server:25826"
  # The collectd service supports either scanning a directory for multiple types
  # db files, or specifying a single db file.
  typesdb = "/usr/share/collectd/types.db"

Можно перезапускать службы:

# service influxdb restart

Вот собственно и все, статья «Установка Collectd в Unix/Linux» завершена.

The post Установка Collectd в Unix/Linux first appeared on linux-notes.org.]]>
https://linux-notes.org/ustanovka-collectd-v-unix-linux/feed/ 0