Commits
Akeem Wells authored e58feaf5a24 Merge
1 - | import os |
2 - | import fnmatch |
3 - | import subprocess |
4 - | import tarfile |
5 - | from casac import casac |
6 - | import datetime |
7 - | import time |
8 - | import urllib2 |
9 - | import __casac__ |
10 - | import TelemetryLogMonitor |
11 - | import ssl |
12 - | |
13 - | class telemetry: |
14 - | |
15 - | def __init__(self, casa): |
16 - | |
17 - | self.setCasaVersion() |
18 - | self.setHostId() |
19 - | self.logdir = casa['dirs']['rc'] |
20 - | self.variantSuffix = "" |
21 - | if len(casa['variant'])>1: |
22 - | self.variantSuffix = "-" + casa['variant'] |
23 - | self.logpattern = 'casastats-' + self.casaver + '-' + self.hostid + '*' + self.variantSuffix + '.log' |
24 - | self.sendlogpattern = 'casastats-*'+ self.hostid + '*.log' |
25 - | self.stampfile = self.logdir + '/telemetry-' + self.hostid + '.stamp' |
26 - | self.casa = casa |
27 - | |
28 - | logfiles = [] |
29 - | |
30 - | # Check if user has defined a telemetry log location |
31 - | casa_util = __casac__.utils.utils() |
32 - | |
33 - | if (casa_util.getrc("TelemetryLogDirectory") != 'Unknown value'): |
34 - | self.logdir = casa_util.getrc("TelemetryLogDirectory") |
35 - | |
36 - | for file in os.listdir(self.logdir): |
37 - | if fnmatch.fnmatch(file, self.logpattern): |
38 - | #print "Matched: " + file |
39 - | logfiles.append(file) |
40 - | |
41 - | logfiles.sort(reverse=True) |
42 - | # Size of the existing (non-active) logfiles |
43 - | inactiveTLogSize = 0 |
44 - | |
45 - | if (logfiles and logfiles[0] != None): |
46 - | print "Found an existing telemetry logfile: " + self.logdir + "/" + logfiles[0] |
47 - | casa['files']['telemetry-logfile'] = self.logdir + "/" + logfiles[0] |
48 - | for i in range(1, len(logfiles)): |
49 - | inactiveTLogSize = inactiveTLogSize + os.path.getsize(self.logdir + "/" + logfiles[i])/1024 |
50 - | #print "Inactive log size: " + str(inactiveTLogSize) |
51 - | else : |
52 - | print "Creating a new telemetry file" |
53 - | self.setNewTelemetryFile() |
54 - | |
55 - | # Setup Telemetry log size monitoring |
56 - | # Size limit for the telemetry logs |
57 - | tLogSizeLimit = 20000 |
58 - | # File size check interval |
59 - | tLogSizeInterval = 60 |
60 - | try: |
61 - | tLogSizeLimit = int(casa_util.getrc("TelemetryLogLimit")) |
62 - | tLogSizeInterval = int(casa_util.getrc("TelemetryLogSizeInterval")) |
63 - | except: |
64 - | pass |
65 - | # Subtract the inactive log sizes from the total log file size limit |
66 - | tLogSizeLimit = tLogSizeLimit - inactiveTLogSize |
67 - | if (tLogSizeLimit <= 0): |
68 - | print "Telemetry log size limit exceeded. Disabling telemetry." |
69 - | casa['state']['telemetry-enabled'] = False |
70 - | else : |
71 - | tLogMonitor = TelemetryLogMonitor.TelemetryLogMonitor() |
72 - | tLogMonitor.start(casa['files']['telemetry-logfile'],tLogSizeLimit, tLogSizeInterval, casa) |
73 - | print "Telemetry initialized. Telemetry will send anonymized usage statistics to NRAO." |
74 - | print 'You can disable telemetry by adding the following line to your ~/.casarc file:' |
75 - | print 'EnableTelemetry: False' |
76 - | |
77 - | def setNewTelemetryFile(self): |
78 - | self.casa['files']['telemetry-logfile'] = self.logdir + '/casastats-' + self.casaver +'-' + self.hostid + "-" + time.strftime("%Y%m%d-%H%M%S", time.gmtime()) + self.variantSuffix + '.log' |
79 - | # Work around the chicken/egg problem with telemetry/logger initialization |
80 - | if hasattr(self, 'logger'): |
81 - | self.logger.setstatslogfile(self.casa['files']['telemetry-logfile']) |
82 - | |
83 - | def setCasaVersion(self): |
84 - | myUtils = casac.utils() |
85 - | ver = myUtils.version() |
86 - | self.casaver = str(ver[0])+ str(ver[1]) + str(ver[2])+ "-" + str(ver[3]) |
87 - | |
88 - | def setHostId(self): |
89 - | telemetryhelper = casac.telemetryhelper() |
90 - | self.hostid = telemetryhelper.getUniqueId() |
91 - | |
92 - | def setCasaLog(self, logger): |
93 - | self.logger = logger |
94 - | |
95 - | def submitStatistics(self): |
96 - | if (self.casa['state']['telemetry-enabled'] == True): |
97 - | self.logger.post("Checking telemetry submission interval") |
98 - | self.createStampFile() |
99 - | if (self.isSubmitInterval()): |
100 - | postingUrl = 'https://casa.nrao.edu/cgi-bin/crash-report.pl' |
101 - | if os.environ.has_key('CASA_CRASHREPORT_URL') : |
102 - | postingUrl = os.environ['CASA_CRASHREPORT_URL'] |
103 - | self.send(postingUrl) |
104 - | self.refreshStampFile() |
105 - | self.setNewTelemetryFile() |
106 - | |
107 - | |
108 - | def isSubmitInterval(self): |
109 - | currentTime = time.time() |
110 - | lastUpdateTime = time.time() |
111 - | if (os.path.isfile(self.stampfile)): |
112 - | lastUpdateTime = os.path.getmtime(self.stampfile) |
113 - | |
114 - | # Check update checkSubmitInterval |
115 - | interval = 604800 |
116 - | utils = casac.utils() |
117 - | if (utils.getrc("TelemetrySubmitInterval") != 'Unknown value'): |
118 - | interval = float(utils.getrc("TelemetrySubmitInterval")) |
119 - | if ((currentTime - lastUpdateTime)> interval): |
120 - | self.logger.post("Telemetry submit interval reached, submitting telemetry data.") |
121 - | return True |
122 - | else: |
123 - | self.logger.post("Telemetry submit interval not reached. Not submitting data.") |
124 - | #print "lastUpdateTime" +str(lastUpdateTime) |
125 - | #print "currentTime" +str(currentTime) |
126 - | self.logger.post("Next telemetry data submission in: " + str(datetime.timedelta( \ |
127 - | seconds=(interval-(currentTime-lastUpdateTime))))) |
128 - | return False |
129 - | |
130 - | def createStampFile(self): |
131 - | #print "Checking for stampfile " + self.stampfile |
132 - | if not os.path.isfile(self.stampfile): |
133 - | self.logger.post("Creating a new telemetry time stamp file." + self.stampfile) |
134 - | open(self.stampfile, 'a').close() |
135 - | |
136 - | def refreshStampFile(self): |
137 - | os.utime(self.stampfile, None) |
138 - | |
139 - | def send(self, telemetry_url): |
140 - | |
141 - | telemetryhelper = casac.telemetryhelper() |
142 - | logfiles = [] |
143 - | |
144 - | # Test if internet connection is available. |
145 - | context = ssl._create_unverified_context() |
146 - | try: |
147 - | urllib2.urlopen('https://casa.nrao.edu/', timeout=20, context=context) |
148 - | except urllib2.URLError as err: |
149 - | self.logger.post("No telemetry server available. Not submitting data") |
150 - | return |
151 - | |
152 - | # Find logfiles |
153 - | for file in os.listdir(self.logdir): |
154 - | if fnmatch.fnmatch(file, self.sendlogpattern): |
155 - | #print "Matched: " + file |
156 - | logfiles.append(file) |
157 - | |
158 - | if (len(logfiles) > 0): |
159 - | #Tar logfiles |
160 - | current_date = datetime.datetime.today().strftime('%Y%m%d%H%M%S') |
161 - | tarfileid = self.logdir + "/telemetry-" \ |
162 - | + telemetryhelper.getUniqueId() + "-" \ |
163 - | + current_date + ".tar.gz" |
164 - | try: |
165 - | tar = tarfile.open(tarfileid, "w:gz") |
166 - | for logfile in logfiles: |
167 - | tar.add(self.logdir + "/" + logfile, |
168 - | arcname='telemetry/'+logfile) |
169 - | tar.close() |
170 - | except Exception as e: |
171 - | self.logger.post("Couldn't create telemetry tarfile") |
172 - | self.logger.post(str(e)) |
173 - | |
174 - | try: |
175 - | file_param = 'file=@' + tarfileid #+ '\"' |
176 - | # Submit tarfile |
177 - | #print ['curl', '-F', file_param , telemetry_url] |
178 - | proc = subprocess.Popen(['curl', '-F', file_param , telemetry_url],stdout=subprocess.PIPE, stderr=subprocess.STDOUT) |
179 - | cmd_out, cmd_err = proc.communicate() |
180 - | if cmd_out != None: |
181 - | self.logger.post(cmd_out, 'DEBUG1') |
182 - | if cmd_err != None: |
183 - | self.logger.post(cmd_err, 'DEBUG1') |
184 - | except Exception as e: |
185 - | self.logger.post("Couldn't submit telemetry logs") |
186 - | self.logger.post(str(e)) |
187 - | |
188 - | # Remove files |
189 - | for logfile in logfiles: |
190 - | try: |
191 - | os.remove(self.logdir + "/" + logfile) |
192 - | except Exception as e: |
193 - | self.logger.post("Couldn't remove logfile " + self.logdir + "/" + logfile) |
194 - | self.logger.post(str(e)) |
195 - | #print "Removed " + self.logdir + "/" + logfile |
196 - | try: |
197 - | os.remove(tarfileid) |
198 - | self.logger.post("Removed" + tarfileid) |
199 - | except Exception as e: |
200 - | self.logger.post("Couldn't remove " + tarfileid) |
201 - | self.logger.post(str(e)) |
202 - | else: |
203 - | self.logger.post("No telemetry files to submit.") |