-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathyrca.py
102 lines (90 loc) · 3.62 KB
/
yrca.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
# import Python default modules
import os,sys,getopt
# import parser's modules
from parser.templater.templater import Templater
# import explainer's modules
from parser.parser import parseEvents
from explainer.explainer import explain
def main(argv):
# parse command line arguments
try:
options,args = getopt.getopt(argv,"hn:r:v",["help","num=","root=","verbose"])
except:
cli_error("wrong options used")
exit(-1)
# options to customise the execution of the explainer (with default values)
nSols = None # number of possible explanations to find (default: all)
rootCause = None # value for root cause (default: all)
verbose = False # by default, only "compact" printing (service names, no instances/timestamps/messages)
# getting specified options
for option, value in options:
# help
if option in ["-h","--help"]:
cli_help()
exit(0)
# setting number of solutions to identify
elif option in ["-n","--num"]:
if value.isnumeric() and float(value)>0:
nSols = value
else:
cli_error("the amount of solutions to find must be a positive number")
exit(-2)
# setting root causing service
elif option in ["-r","--rootCause"]:
rootCause = value
# setting verbosity
elif option in ["-v","--verbose"]:
verbose = True
# check & process command line arguments
if len(args) < 3:
cli_error("missing input arguments")
exit(-1)
eventLogLine = args[0]
applicationLogs = args[1]
templater = Templater(args[2])
# ******************
# * PARSING INPUTS *
# ******************
# parse "event" to be explained and all events forming the "knowledgeBase"
event = "event.pl"
parseEvents(eventLogLine,event,templater)
knowledgeBase = "knowledgeBase.pl"
parseEvents(applicationLogs,knowledgeBase,templater)
# ***********************
# * ROOT CAUSE ANALYSIS *
# ***********************
rootCauses = explain(event,knowledgeBase,nSols,rootCause)
# *****************
# * PRINT RESULTS *
# *****************
if verbose:
rootCauses.print(templater)
else:
rootCauses.compactPrint(templater)
rootCauses.marshal(templater,"explanations.txt")
if rootCauses.size()==0:
rc = (" from " + rootCause) if rootCause!=None else ""
print("Found no failure cascade" + rc + " to the considered event")
else:
end = "s" if rootCauses.size() > 1 else "" # plural or singular
print("Found a total of " + str(rootCauses.size()) + " possible explanation" + end)
# Remove generated files
os.remove(event) # comment this, if needing to keep files for Prolog debugging
os.remove(knowledgeBase) # comment this, if needing to keep files for Prolog debugging
# function for printing cli erros, followed by cli usage
def cli_error(message):
print("ERROR: " + message + ".")
print()
cli_help()
# function for printing cli usage
def cli_help():
print("Usage of yrca.py is as follows:")
print(" yrca.py [OPTIONS] EVENT LOGS TEMPLATES")
print("where EVENT and LOGS are JSON files, TEMPLATES is a YAML file, and OPTIONS can be")
print(" [--help] to print a help on the usage of yrca.py")
print(" [-n N|--num=N] to set to N the amount of possible explanations to identify")
print(" [-r X|--root=X] to require X to be the root cause of identified explanations")
print(" [-v|--verbose] to print verbose analysis results")
print()
if __name__ == "__main__":
main(sys.argv[1:])