summaryrefslogtreecommitdiffstats
path: root/LogActio/Reporters/QpidReporter.py
blob: 6c05df5aaa3240dc786a75628b87cd713ce55de8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#
#   logactio  -  simple framework for doing configured action on certain
#                log file events
#
#   Copyright 2012 - 2015   David Sommerseth <dazo@eurephia.org>
#
#   This program is free software; you can redistribute it and/or
#   modify it under the terms of the GNU General Public License
#   as published by the Free Software Foundation, version 2
#   of the License.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
#
#   For the avoidance of doubt the "preferred form" of this code is one which
#   is in an open unpatent encumbered format. Where cryptographic key signing
#   forms part of the process of creating an executable the information
#   including keys needed to generate an equivalently functional executable
#   are deemed to be part of the source code.
#

import sys, json
from qpid.util import connect
from qpid.connection import Connection
from qpid.datatypes import Message, RangedSet, uuid4
from qpid.queue import Empty
import LogActio.Message, LogActio.ReporterQueue


class QpidReporter(LogActio.ReporterQueue.ReporterQueue):
    """Simple LogActio reporter module, sending alerts to a Qpid broker

    Example configuration to be used in /etc/logactio.cfg

        [Reporter:QPID]
        module: QpidReporter
        broker: qpid.example.com
        port: 5672
        routing_key: LogActio.Alerts
        exchange: amq.topic

    This will send reports to the configured Qpid broker queue
    """

    def __init__(self, config, logger = None):
        if not config.has_key("broker"):
            raise Exception("QpidReporter is not configured with a broker host/address")
        if not config.has_key("routing_key"):
            raise Exception("QpidReporter is not configured with a Qpid routing key")
        if not config.has_key("exchange"):
            raise Exception("QpidReporter is not configured with a Qpid exchange")

        self.__log = logger and logger or self.__logfnc
        self.__broker = config["broker"]
        self.__port = config.has_key("port") and config["port"] or 5672
        self.__routkey = config["routing_key"]
        self.__exchange = config["exchange"]

        LogActio.ReporterQueue.ReporterQueue.__init__(self,
                                                      "QpidReporter",
                                                      "Qpid Reporter",
                                                      self.__processqueue)

    def __logfnc(self, lvl, msg):
        print "%s" % msg
        sys.stdout.flush()


    def __processqueue(self):
        # Connect to the Qpid broker
        qpidsock = connect(self.__broker, self.__port)
        qpidconn = Connection(sock=qpidsock,
                              service="qpidd", reconnect=True, heartbeat=30)
        qpidconn.start()
        qpidsess = qpidconn.session(str(uuid4()))
        qmsgprops = qpidsess.delivery_properties(routing_key=self.__routkey)

        self.__log(1, "[QpidReporter] Connection to %s:%i opened" % (
                self.__broker, self.__port))

        # Process the internal message queue
        done = False
        mcount = 0
        uuid = str(uuid4())
        while not done:
            msg = self._QueueGet()

            if( msg.MessageType() == LogActio.Message.MSG_SHUTDOWN ):
                # Prepare for shutdown
                done = True

            elif( msg.MessageType() == LogActio.Message.MSG_SEND ):
                m = msg.Message()

                try:
                    qm = Message(qmsgprops, m)
                    qpidsess.message_transfer(self.__exchange, message=qm)
                    mcount += 1
                    del qm
                except Exception, e:
                    self.__log(0, "** ERROR ** QpidReporter failed: %s" % str(e))

        qpidsess.close(timeout=30)
        self.__log(1, "[QpidReporter] Connection to %s:%i closed" % (
                self.__broker, self.__port))


    def ProcessEvent(self, logfile, prefix, msg, count, threshold):
        # Format the report message
        msg = {"prefix": prefix, "count": count, "threshold": threshold,
               "message": "|".join(msg), "logfile": logfile}

        # Queue the message for sending
        self._QueueMsg(0, json.dumps(msg))


def InitReporter(config, logger = None):
    return QpidReporter(config, logger)