[PYTHON] J'ai essayé d'informer le serveur Zabbix d'une erreur d'exécution de la fonction AWS Lambda

introduction

Étant donné que le système de surveillance des opérations est géré de manière centralisée par Zabbix, je voulais informer Zabbix Server de l'erreur d'exécution de la fonction AWS Lambda, alors je l'ai essayé.

environnement

Ajout d'un hôte / élément / déclencheur au serveur Zabbix

Hôte ajouté

Paramètres> Hôtes> Créer un hôte

Onglet hôte

--Nom de l'hôte: lambda-trapper --Créer un nouveau groupe: Lambda

Article ajouté

[Paramètres]> [Hôtes]> [Articles]> [Créer un élément] de lambda-trapper dans la liste d'hôtes

--Nom: ErrorLog --Type: Trappeur Zabbix --Clé: journal des erreurs --Type de données: chaîne

Déclencheur ajouté

[Settings]> [Hosts]> [Trigger]> [Create Trigger] de lambda-trapper dans la liste d'hôtes

Onglet Trigger

--Name: erreur d'exécution de la fonction Lambda --Expression conditionnelle: {lambda-trapper: errorlog.str (exemple)} = 0 et {lambda-trapper: errorlog.nodata (30)} = 0 --Continuer à générer des événements d'échec: On

Ajout du processus de journalisation à la fonction AWS Lambda

Ajoutez le traitement de journalisation à la fonction AWS Lambda existante (la fonction dont vous souhaitez intercepter les erreurs d'exécution) comme suit.

code

lambda_function.py


# (réduction)

import logging

# (réduction)

#Initialisation de l'enregistreur
logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    try:

        # (réduction)

        logger.info("Execution succeeded.")
    except Exception, e:
        logger.error(e)
        raise(e)    #Décrit lorsque vous souhaitez enregistrer la trace de la pile Python dans le journal CloudWatch

En ajoutant le processus de journalisation, le résultat de l'exécution de la fonction AWS Lambda sera envoyé à CloudWatch. Exemple de journal de fin normal)

[INFO]	2017-03-01T08:18:31.149Z	a7afba37-fe57-11e6-a428-371557c5f4e7	Execution succeeded.

Exemple de journal de terminaison anormale)

[ERROR]	2017-03-01T09:38:37.966Z	d8c7ede3-fe62-11e6-b58a-7dce3a95f14a	cannot concatenate 'str' and 'int' objects

Créer une fonction AWS Lambda pour envoyer Zabbix

Créez une nouvelle fonction AWS Lambda pour envoyer Zabbix expulsé de CloudWatch. D'ailleurs, le module Zabbix Sender est publié dans "here". J'ai détourné le code.

Nom de la fonction AWS Lambda

cwl-to-zabbix

code

handler.py


import os
import json
from StringIO import StringIO
import base64
import gzip
from ZabbixSender import ZabbixSender
import logging

ZBX_SERVER = os.environ['ZBX_SERVER']
ZBX_HOST = os.environ['ZBX_HOST']
ZBX_ITEM = os.environ['ZBX_ITEM']
logger = logging.getLogger()
logger.setLevel(logging.INFO)

def sender(event, context):
    log_b64 = event['awslogs']['data']
    log_gz = StringIO(base64.b64decode(log_b64))
    jsonData = json.load(gzip.GzipFile(fileobj=log_gz, mode='rb'))
    status = jsonData['logEvents'][0]['extractedFields']['status']
    message = jsonData['logEvents'][0]['extractedFields']['event']
    timestamp = int(jsonData['logEvents'][0]['timestamp']) / 1000
    func = os.path.basename(jsonData['logGroup'])

    try:
        if status == "ERROR":
            errlog = func + ': ' + message
            sender = ZabbixSender(ZBX_SERVER)
            sender.add(ZBX_HOST, ZBX_ITEM, errlog, timestamp)
            sender.send()
        logger.info("Execution Succeeded.")
    except Exception, e:
        logger.error(e)
        raise(e)

ZabbixSender.py


import socket
import struct
import time
import json

class ZabbixSender:

    log = True

    def __init__(self, host='127.0.0.1', port=10051):
        self.address = (host, port)
        self.data    = []

    def __log(self, log):
        if self.log: print log

    def __connect(self):
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            self.sock.connect(self.address)
        except:
            raise Exception("Can't connect server.")

    def __close(self):
        self.sock.close()

    def __pack(self, request):
        string = json.dumps(request)
        header = struct.pack('<4sBQ', 'ZBXD', 1, len(string))
        return header + string

    def __unpack(self, response):
        header, version, length = struct.unpack('<4sBQ', response[:13])
        (data, ) = struct.unpack('<%ds'%length, response[13:13+length])
        return json.loads(data)

    def __request(self, request):
        self.__connect()
        try:
            self.sock.sendall(self.__pack(request))
        except Exception as e:
            raise Exception("Failed sending data.\nERROR: %s" % e)

        response = ''
        while True:
            data = self.sock.recv(4096)
            if not data:
                break
            response += data

        self.__close()
        return self.__unpack(response)

    def __active_checks(self):
        hosts = set()
        for d in self.data:
            hosts.add(d['host'])

        for h in hosts:
            request = {"request":"active checks", "host":h}
            self.__log("[active check] %s" % h)
            response = self.__request(request)
            if not response['response'] == 'success': self.__log("[host not found] %s" % h)

    def add(self, host, key, value, clock=None):
        if clock is None: clock = int(time.time())
        self.data.append({"host":host, "key":key, "value":value, "clock":clock})

    def send(self):
        if not self.data:
            self.__log("Not found sender data, end without sending.")
            return False

        self.__active_checks()
        request  = {"request":"sender data", "data":self.data}
        response = self.__request(request)
        result   = True if response['response'] == 'success' else False

        if result:
            for d in self.data:
                self.__log("[send data] %s" % d)
            self.__log("[send result] %s" % response['info'])
        else:
            raise Exception("Failed send data.")

        return result

Variable d'environnement

--ZBX_SERVER =

Réglage

※ Créez à l'avance un rôle avec les droits d'accès suivants et attribuez-lui ce rôle.

Créer un filtre d'abonnement

  1. Cliquez sur la fonction d'envoi de Zabbix (cwl-to-zabbix) dans la liste des fonctions AWS Lambda.
  2. Cliquez sur l'onglet Déclencheurs, puis sur Ajouter un déclencheur
  3. Cliquez sur le champ de la source de l'événement (à l'intérieur de la ligne interrompue) et sélectionnez [CloudWatch Logs] dans la liste des sources.
  4. Remplissez les champs comme indiqué ci-dessous et cliquez sur [Envoyer] --Groupe de journaux: (Sélectionnez le groupe de journaux de la fonction AWS Lambda existante) * --Nom du filtre: LambdaStream_cwl-to-zabbix --Modèle de filtre: `` [status =" ERROR ", timestamp = * Z, request_id =" * - * ", event] `

Résumé

Recommended Posts

J'ai essayé d'informer le serveur Zabbix d'une erreur d'exécution de la fonction AWS Lambda
J'ai essayé d'informer Slack de la mise à jour de Redmine
J'ai essayé d'obtenir une AMI en utilisant AWS Lambda
J'ai essayé de combattre le minimum local de la fonction Goldstein-Price
J'ai essayé d'obtenir l'index de la liste en utilisant la fonction énumérer
J'ai essayé le serveur asynchrone de Django 3.0
Résumé de l'écriture d'AWS Lambda
J'ai essayé de supprimer régulièrement les mauvais tweets avec l'API AWS Lambda + Twitter
[Lambda] J'ai essayé d'incorporer un module externe de python via S3
La première étape pour se débarrasser des requêtes lentes! J'ai essayé d'avertir Chatwork des requêtes lentes pour RDS pour MySQL à l'aide de Lambda et de l'AWS CLI v2
J'ai essayé de notifier la mise à jour de "Hameln" en utilisant "Beautiful Soup" et "IFTTT"
J'ai essayé la fonction de tableau croisé dynamique des pandas
J'ai essayé de trouver le rapport de circonférence par 100 millions de chiffres
J'ai essayé de corriger la forme trapézoïdale de l'image
Erreur de la fonction décorée par tf.function lors de la tentative de création de variables lors d'un autre appel. Dans tensorflow.keras
J'ai essayé de réduire les coûts en démarrant / arrêtant EC2 dans un lot avec AWS Lambda
J'ai essayé de connecter AWS Lambda à d'autres services
Résumé de l'étude de Python pour utiliser AWS Lambda
Je souhaite personnaliser l'apparence de zabbix
J'ai essayé d'utiliser Twitter Scraper avec AWS Lambda et cela n'a pas fonctionné.
J'ai essayé de vectoriser les paroles de Hinatazaka 46!
J'ai essayé de notifier la mise à jour de "Devenir romancier" en utilisant "IFTTT" et "Devenir un romancier API"
Je voulais utiliser la feuille de calcul Google avec AWS lambda, alors je l'ai essayé [Partie 2]
J'ai essayé d'entraîner la fonction péché avec chainer
J'ai essayé d'extraire des fonctionnalités avec SIFT d'OpenCV
J'ai essayé de résumer comment utiliser matplotlib de python
Je veux grep le résultat de l'exécution de strace
J'ai essayé de résumer la forme de base de GPLVM
J'ai essayé d'exécuter TensorFlow dans l'environnement AWS Lambda: Préparation
J'ai essayé d'approcher la fonction sin en utilisant le chainer
J'ai essayé de visualiser les informations spacha de VTuber
Je veux AWS Lambda avec Python sur Mac!
J'ai essayé d'effacer la partie négative de Meros
AWS Lambda prend désormais en charge Python, je l'ai donc essayé
[Python] J'ai essayé d'obtenir Json de squid ring 2
J'ai essayé d'implémenter le calcul automatique de la preuve de séquence
[Introduction à AWS] J'ai essayé de jouer avec la conversion voix-texte ♪
J'ai essayé de classer les voix des acteurs de la voix
J'ai essayé de résumer les opérations de chaîne de Python
J'ai essayé AWS CDK!
J'ai essayé de déboguer.
J'ai essayé AWS Iot
J'ai essayé de réécrire le serveur WEB de la 1ère édition de programmation Linux normale avec C ++ 14
J'ai essayé de trouver l'entropie de l'image avec python
[Courses de chevaux] J'ai essayé de quantifier la force du cheval de course
J'ai essayé d'obtenir les informations de localisation du bus Odakyu
J'ai essayé de trouver la moyenne de plusieurs colonnes avec TensorFlow
J'ai essayé de démarrer le serveur de Django avec VScode au lieu de Pycharm
J'ai essayé de notifier les informations de retard de train avec LINE Notify
J'ai fait une fonction pour vérifier le modèle de DCGAN
J'ai essayé d'ajouter un post-incrément à CPython. Liste de toutes les modifications
[Introduction à AWS] Mémorandum de création d'un serveur Web sur AWS
[Python] J'ai essayé de visualiser la relation de suivi de Twitter
J'ai essayé d'implémenter ListNet d'apprentissage de rang avec Chainer
J'ai essayé d'implémenter la fonction d'envoi de courrier en Python
J'ai essayé un peu le comportement de la fonction zip