-
Notifications
You must be signed in to change notification settings - Fork 0
/
BaseDetector.py
174 lines (140 loc) · 5.15 KB
/
BaseDetector.py
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
import pika
import json
import argparse
from datetime import datetime, timedelta
import sys
SECONDS_PER_UNIT = {
"s": 1,
"m": 60,
"h": 3600,
"d": 86400,
"w": 604800,
}
def to_time(s, now=None):
"""
Receives a delta of time string, and calculates a past time with that
delta. The string is formatted as <INT><UNIT>, where UNIT is one of s
(seconds), m (minutes), h (hours), d (days), w (weeks).
For example:
Using 1 day as delta.
>>> to_time('1d', now=datetime(2017, 02, 16, 2))
datetime.datetime(2017, 2, 15, 2, 0)
Using 1 week as delta.
>>> to_time('1w', now=datetime(2017, 02, 16, 2))
datetime.datetime(2017, 2, 9, 2, 0)
It should fail when the format is not recognized.
>>> to_time('1t')
Traceback (most recent call last):
...
SyntaxError: not a valid time unit: t, must be one of s, m, h, d, w
:param s: the delta of time as an string
:param now: optional now argument for easy testing
:return: a resulting datetime object
"""
try:
number = int(s[:-1])
except ValueError:
raise SyntaxError('not an integer number: %s' % s[:-1])
unit = s[-1]
if unit not in SECONDS_PER_UNIT:
raise SyntaxError('not a valid time unit: %s, '
'must be one of s, m, h, d, w' % unit)
if now is None:
now = datetime.utcnow()
else:
if not isinstance(now, datetime):
raise ValueError('`now` argument must be a datetime')
return now - timedelta(seconds=number * SECONDS_PER_UNIT[unit])
def args():
parser = argparse.ArgumentParser()
parser.add_argument('-l', '--last', type=str,
help='Time to query ES for last logs, overrides '
'from/to. Example: 1s, 1m, 2h, 3d, 5w')
parser.add_argument('-f', '--from-time', type=str,
help='Time lower limit in UTC')
parser.add_argument('-t', '--to-time', type=str,
help='Time upper limit in UTC')
parser.add_argument('-tp', '--true-positive', action='store_true',
help='Execute True Positive for this detector')
parser.add_argument('-fn', '--false-negative',action='store_true',
help='Execute False Negative for this detector')
parser.add_argument('--test', action='store_true',
help='Use this if you do not want to send an alarm')
opts = parser.parse_args()
if opts.last is not None:
fromTime = to_time(opts.last).isoformat()
toTime = datetime.utcnow().isoformat()
else:
toTime = opts.to_time if opts.to_time is not None else 'now'
fromTime = opts.from_time
# print opts.true_positive
if opts.true_positive:
tp = True
else:
tp = False
# print opts.false_negative
if opts.false_negative:
fn = True
else:
fn = False
return {
'from': fromTime,
'to': toTime,
'tp': tp,
'fn': fn
}
class BaseDetector(object):
def __init__(self,priority = 'DEBUG'):
self.dectectorName = None
self.report = 'Reporting alarm'
self.priority = priority
self.params = None
## error counter
self.errorCounter = 0
## RabbitMQ Parameters
# Magic Numbers
credentials = pika.PlainCredentials('alma', 'guest')
host = 'ariadne.osf.alma.cl'
port = 5672
self.alarmQueue = 'alarm'
# Connecting
parameters = pika.ConnectionParameters(host, port, '/', credentials)
connection = pika.BlockingConnection(parameters)
self.channel = connection.channel()
self.channel.queue_declare(queue=self.alarmQueue)
def configure(self,params):
self.params = params
def execute(self):
if self.params == 1:
return 0
elif self.params == 0:
return 0
def sendAlarm(self, occurrence_time, name, priority, body):
self.lastError= '=== START ERROR: ' + str(priority) + ' ===\n' \
'@timestamp: ' + str(occurrence_time) + '\n' + \
'Path: '+ str(name)+ '\n' \
'Priority: '+ str(priority) + '\n' \
'Body: '+ str(body) + '\n' \
'=== END ERROR ===\n'
## Printing in stdout
print self.lastError
if '--test' not in sys.argv:
## Send to RabbitMQ
jsonAlarm = json.dumps(self.__alarm2json(occurrence_time, name, priority, body))
self.channel.basic_publish(exchange='',
routing_key=self.alarmQueue,
body=jsonAlarm,
properties=pika.BasicProperties(delivery_mode=2))
self.errorCounter += 1
def executeTruePositive(self):
self.params = 0
def executeTrueNegative(self):
self.params = 1
def __alarm2json(self, occurrence_time, name, priority, body):
jsonFormat = {
"@timestamp": occurrence_time,
"path": name,
"priority": priority,
"body": body
}
return jsonFormat