def thisServiceStatus(service): try: if service in SERVICE_NAMES: output = subprocess.Popen(["service", service, "status"], stdout=subprocess.PIPE) statusRawInit, errorStr = output.communicate() if not errorStr is None: util.debugPrint("Error String detected (status): " + str(errorStr)) return {STATUS: NOK, ERROR_MESSAGE: errorStr} statusRaw = statusRawInit.split() util.debugPrint("statusRaw: " + str(statusRaw)) if "running" in statusRaw: return {STATUS: OK, SERVICE_STATUS: "Running"} elif "stopped" in statusRaw: return {STATUS: OK, SERVICE_STATUS: "Stopped"} else: return {STATUS: OK, SERVICE_STATUS: "UNKNOWN"} else: util.errorPrint(service + " does not match a service") return { STATUS: NOK, ERROR_MESSAGE: service + " does not match a service" } except: print "Unexpected error:", sys.exc_info()[0] print sys.exc_info() traceback.print_exc() util.logStackTrace(sys.exc_info()) raise
def startStreamingServer(port): """ Start the streaming server and accept connections. """ global memCache if memCache is None: memCache = MemCache() soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) l_onoff = 1 l_linger = 0 soc.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, struct.pack('ii', l_onoff, l_linger)) portAssigned = False for p in range(port, port + 10, 2): try: print 'Trying port ', p soc.bind(('0.0.0.0', p)) soc.listen(10) socketServerPort = p memCache.setSocketServerPort(p) portAssigned = True util.debugPrint("DataStreaming: Bound to port " + str(p)) break except: print sys.exc_info() traceback.print_exc() util.debugPrint("DataStreaming: Bind failed - retry") if portAssigned: global occupancyQueue socketServer = startSocketServer(soc, socketServerPort) socketServer.start() else: util.errorPrint( "DataStreaming: Streaming disabled on worker - no port found.")
def sendMail(message, receiver, subject, link=False): if not Config.isMailServerConfigured(): util.debugPrint("Cant Send mail. Mail server is not configured") return try: util.debugPrint("sendMail: smtpEmail " + Config.getSmtpEmail()) util.debugPrint("sendMail: smtpServer " + Config.getSmtpServer()) server = smtplib.SMTP(Config.getSmtpServer(), Config.getSmtpPort(), timeout=30) sender = Config.getSmtpEmail() if link: message = MIMEText(message, 'html') else: message = MIMEText(message) message["From"] = Config.getSmtpEmail() message["To"] = receiver message["Subject"] = subject #message["Content-Type:"] = "text/html" server.sendmail(sender, [receiver], message.as_string()) server.quit() except: print "Unexpected error:", sys.exc_info()[0] print sys.exc_info() traceback.print_exc() util.errorPrint("Unexpected error: sendMail") util.logStackTrace(sys.exc_info())
def init(jsonData): threshold = _getThreshold(jsonData) if threshold is None: util.errorPrint("Threshold not set for " + str(jsonData)) raise Exception("Threshold not set - configuration error") jsonData['cutoff'] = int(threshold) jsonData[FREQ_RANGE] = _getFreqRange(jsonData)
def getResourceData(ws): """ Handle resource data streaming requests from the web browser. Token is of the form <sessionID> => len(parts)==1 """ try: util.debugPrint("ResourceDataStreaming:getResourceData") token = ws.receive() if token is None: #or len(parts) < 2: ws.close() return sessionId = token if not authentication.checkSessionId(sessionId, "admin"): ws.close() util.debugPrint( "ResourceDataStreamng:failed to authenticate: user != " + sessionId) return memCache = memcache.Client(['127.0.0.1:11211'], debug=0) keys = MemCacheKeys.RESOURCEKEYS resourceData = {} secondsPerFrame = 1 while True: for resource in keys: key = str(resource).encode("UTF-8") value = memCache.get(key) if value is not None: resourceData[str(key)] = float(value) else: util.errorPrint("Unrecognized resource key " + key) client = MongoClient(getDbHost(), 27017) collection = client.systemResources.dbResources dbResources = collection.find_one({}) if dbResources is not None and dbResources["Disk"] is not None: resourceData["Disk"] = float(dbResources["Disk"]) util.debugPrint("resource Data = " + str(json.dumps(resourceData, indent=4))) ws.send(json.dumps(resourceData)) sleepTime = secondsPerFrame gevent.sleep(sleepTime) except: traceback.print_exc() util.debugPrint("Error writing to resource websocket") util.logStackTrace(traceback) ws.close()
def restartSensor(sensorId): memCache = MemCache() pid = memCache.getStreamingServerPid(sensorId) if pid != -1: try: util.debugPrint("restartSensor: sensorId " + sensorId + " pid " + str(pid) + " sending sigint") os.kill(pid, signal.SIGINT) except: util.errorPrint("restartSensor: Pid " + str(pid) + " not found") else: util.debugPrint("restartSensor: pid not found")
def acquire(self): if not self.memcacheStarted: util.errorPrint("Memcache is not started. Locking disabled") return counter = 0 while True: self.mc.add("accountLock", self.key) val = self.mc.get("accountLock") if val == self.key: break else: counter = counter + 1 assert counter < 30, "AccountLock counter exceeded." time.sleep(0.1)
def decrementSubscriptionCount(self, sensorId): self.acquire() try: key = str(OCCUPANCY_SUBSCRIPTION_COUNT + sensorId).encode("UTF-8") subscriptionCount = self.mc.get(key) if subscriptionCount is None: return else: subscriptionCount = subscriptionCount - 1 self.mc.set(key, subscriptionCount) if subscriptionCount < 0: util.errorPrint( "DataStreaming: negative subscription count! " + sensorId) finally: self.release()
def log(): if DebugFlags.debug: data = request.data jsonValue = json.loads(data) if "message" in jsonValue: message = jsonValue["message"] else: message = "" if "ExceptionInfo" in jsonValue: exceptionInfo = jsonValue["ExceptionInfo"] else: exceptionInfo = {} if len(exceptionInfo) != 0: util.errorPrint("Client Log Message: " + message) util.errorPrint("Client Exception Info:") for i in range(0, len(exceptionInfo)): util.errorPrint("Exception Message:") exceptionMessage = exceptionInfo[i]["ExceptionMessage"] util.errorPrint("Client Stack Trace:") stackTrace = exceptionInfo[i]["StackTrace"] util.errorPrint(exceptionMessage) decodeStackTrace(stackTrace) if "Traceback" in jsonValue: traceback = jsonValue["Traceback"] util.errorPrint("Traceback: " + traceback) else: util.debugPrint("Client Log Message: " + message) return "OK"
def readFromInput(bbuf, conn): util.debugPrint("DataStreaming:readFromInput") soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sensorCommandDispatcherPid = None memCache = MemCache() try: while True: lengthString = "" while True: lastChar = bbuf.readChar() if lastChar is None: time.sleep(0.1) return if len(lengthString) > 1000: raise Exception("Formatting error") if lastChar == '{': headerLength = int(lengthString.rstrip()) break else: lengthString += str(lastChar) jsonStringBytes = "{" while len(jsonStringBytes) < headerLength: jsonStringBytes += str(bbuf.readChar()) jsonData = json.loads(jsonStringBytes) if not any(k in jsonData for k in (TYPE, SENSOR_ID, SENSOR_KEY)): err = "Sensor Data Stream: Missing a required field" util.errorPrint(err) util.errorPrint("Invalid message -- closing connection: " + json.dumps(jsonData, indent=4)) raise Exception("Invalid message") return sensorId = jsonData[SENSOR_ID] global mySensorId if mySensorId is None: mySensorId = sensorId elif mySensorId != sensorId: raise Exception("Sensor ID mismatch " + mySensorId + " / " + sensorId) sensorKey = jsonData[SENSOR_KEY] if not authentication.authenticateSensor(sensorId, sensorKey): util.debugPrint("jsonData " + json.dumps(jsonData, indent=4)) util.errorPrint("Sensor authentication failed: " + sensorId + " sensorKey " + sensorKey) raise Exception("Authentication failure") return if memCache.getStreamingServerPid(sensorId) == -1: memCache.setStreamingServerPid(sensorId) elif memCache.getStreamingServerPid(sensorId) != os.getpid(): util.errorPrint( "Handling connection for this sensor already " + str(os.getpid())) try: os.kill(memCache.getStreamingServerPid(sensorId), signal.SIGKILL) memCache.setStreamingServerPid(sensorId) except: print "Unexpected error:", sys.exc_info()[0] print sys.exc_info() traceback.print_exc() util.logStackTrace(sys.exc_info()) util.debugPrint( "Problem killing process " + str(memCache.getStreamingServerPid(sensorId))) if memCache.getStreamingCommandDispatcherPid(sensorId) != -1: try: os.kill( memCache.getStreamingCommandDispatcherPid( sensorId), signal.SIGKILL) except: memCache.removeStreamingCommandDispatcherPid(sensorId) util.debugPrint("Process not found. Proceeding ") util.debugPrint("DataStreaming: Message = " + dumps(jsonData, sort_keys=True, indent=4)) sensorObj = SensorDb.getSensorObj(sensorId) if not sensorObj.isStreamingEnabled( ) or sensorObj.getStreamingParameters() is None: raise Exception("Streaming is not enabled") return # the last time a data message was inserted if jsonData[TYPE] == DATA: util.debugPrint("pubsubPort: " + str(memCache.getPubSubPort(sensorId))) if "Sys2Detect" not in jsonData: jsonData[SYS_TO_DETECT] = "LTE" DataMessage.init(jsonData) t = Process(target=runSensorCommandDispatchWorker, args=(conn, sensorId)) t.start() sensorCommandDispatcherPid = t.pid childPids.append(sensorCommandDispatcherPid) cutoff = DataMessage.getThreshold(jsonData) n = DataMessage.getNumberOfFrequencyBins(jsonData) sensorId = DataMessage.getSensorId(jsonData) lastDataMessageReceivedAt[sensorId] = time.time() lastDataMessageOriginalTimeStamp[ sensorId] = DataMessage.getTime(jsonData) # Check if the measurement type reported by the sensor # matches that in the sensordb measurementType = DataMessage.getMeasurementType(jsonData) if sensorObj.getMeasurementType() != measurementType: err = "Measurement type mismatch " err += sensorObj.getMeasurementType() err += " / " err += measurementType raise Exception(err) # Check if the time per measurement reported by the sensor # matches that in the sensordb timePerMeasurement = sensorObj.getStreamingSecondsPerFrame() util.debugPrint("StreamingServer: timePerMeasurement " + str(timePerMeasurement)) if timePerMeasurement != DataMessage.getTimePerMeasurement( jsonData): err = "TimePerMeasurement mismatch " err += str(timePerMeasurement) err += "/" err += str(DataMessage.getTimePerMeasurement(jsonData)) raise Exception(err) # The sampling interval for write to the database. s = sensorObj.getStreamingSamplingIntervalSeconds() streamingSamplingIntervalSeconds = s # The number of measurements per capture measurementsPerCapture = int(streamingSamplingIntervalSeconds / timePerMeasurement) util.debugPrint("StreamingServer: measurementsPerCapture " + str(measurementsPerCapture)) # The number of power value samples per capture. samplesPerCapture = int( (streamingSamplingIntervalSeconds / timePerMeasurement) * n) # The number of spectrums per frame sent to the browser. spectrumsPerFrame = 1 jsonData[SPECTRUMS_PER_FRAME] = spectrumsPerFrame # The streaming filter of the sensor (MAX_HOLD or AVG) jsonData[STREAMING_FILTER] = sensorObj.getStreamingFilter() # The band name sys2detect:minfreq:maxfreq string for the # reported measurement. bandName = DataMessage.getFreqRange(jsonData) # Keep a copy of the last data message for periodic insertion # into the db memCache.setLastDataMessage(sensorId, bandName, json.dumps(jsonData)) # captureBufferCounter is a pointer into the capture buffer. captureBufferCounter = 0 powerArrayCounter = 0 timingCounter = 0 # initialize the "prev occupancy array" prevOccupancyArray = [-1 for i in range(0, n)] occupancyArray = [0 for i in range(0, n)] occupancyTimer = time.time() if sensorId not in lastDataMessage: lastDataMessage[sensorId] = jsonData powerVal = [0 for i in range(0, n)] startTime = time.time() sensorObj = SensorDb.getSensorObj(sensorId) if sensorObj is None: raise Exception("Sensor not found") if sensorObj.getSensorStatus() == DISABLED: bbuf.close() raise Exception("Sensor is disabled") if not sensorObj.isStreamingEnabled(): raise Exception("Streaming is disabled") enb = sensorObj.isStreamingCaptureEnabled() isStreamingCaptureEnabled = enb util.debugPrint("isStreamingCaptureEnabled : " + str(enb) + " samplesPerCapture " + str(samplesPerCapture)) if isStreamingCaptureEnabled: sensorData = [0 for i in range(0, samplesPerCapture)] while True: data = bbuf.readByte() if isStreamingCaptureEnabled: sensorData[captureBufferCounter] = data powerVal[powerArrayCounter] = data now = time.time() if isStreamingCaptureEnabled and captureBufferCounter + 1 == samplesPerCapture: # Buffer is full so push the data into mongod. util.debugPrint("Inserting Data message") captureBufferCounter = 0 # Time offset since the last data message was received. timeOffset = time.time( ) - lastDataMessageReceivedAt[sensorId] # Offset the capture by the time since the DataMessage header was received. lastDataMessage[sensorId]["t"] = int( lastDataMessageOriginalTimeStamp[sensorId] + int(timeOffset)) lastDataMessage[sensorId][ "nM"] = measurementsPerCapture lastDataMessage[sensorId]["mPar"]["td"] = int( now - occupancyTimer) lastDataMessage[sensorId]["mPar"][ "tm"] = timePerMeasurement headerStr = json.dumps(lastDataMessage[sensorId], indent=4) util.debugPrint("StreamingServer: headerStr " + headerStr) headerLength = len(headerStr) if isStreamingCaptureEnabled: # Start the db operation in a seperate process p = Process(target=populate_db.put_data, args=(headerStr, headerLength), kwargs={ "filedesc": None, "powers": sensorData }) p.start() lastDataMessageInsertedAt[sensorId] = time.time() occupancyTimer = time.time() else: captureBufferCounter = captureBufferCounter + 1 if data > cutoff: occupancyArray[powerArrayCounter] = 1 else: occupancyArray[powerArrayCounter] = 0 # print "occupancyArray", occupancyArray if (powerArrayCounter + 1) == n: # Get the occupancy subscription counter. if memCache.getSubscriptionCount(sensorId) != 0: if not np.array_equal(occupancyArray, prevOccupancyArray): port = memCache.getPubSubPort(sensorId) soc.sendto( json.dumps({sensorId: occupancyArray}), ("localhost", port)) prevOccupancyArray = np.array(occupancyArray) # sending data as CSV values to the browser listenerCount = memCache.getStreamingListenerCount( sensorId) if listenerCount > 0: sensordata = str(powerVal)[1:-1].replace(" ", "") memCache.setSensorData(sensorId, bandName, sensordata) # Record the occupancy for the measurements. # Allow for 10% jitter. if timingCounter == 1000 and checkForDataRate: if (((now - startTime) / 1000.0 < timePerMeasurement / 2) or ((now - startTime) / 1000.0 > timePerMeasurement * 2)): print " delta ", now - startTime, "global counter ", powerArrayCounter util.errorPrint( "Data coming in too fast or too slow - sensor configuration problem." ) raise Exception( "Data coming in too fast - sensor configuration problem." ) else: startTime = now lastdataseen = now if listenerCount > 0: memCache.setLastDataSeenTimeStamp( sensorId, bandName, lastdataseen) powerArrayCounter = 0 else: powerArrayCounter = powerArrayCounter + 1 timingCounter = timingCounter + 1 elif jsonData[TYPE] == SYS: util.debugPrint( "DataStreaming: Got a System message -- adding to the database" ) populate_db.put_data(jsonStringBytes, headerLength) elif jsonData[TYPE] == LOC: util.debugPrint( "DataStreaming: Got a Location Message -- adding to the database" ) populate_db.put_data(jsonStringBytes, headerLength) finally: util.debugPrint("Closing sockets for sensorId " + sensorId) memCache.removeStreamingServerPid(sensorId) port = memCache.getSensorArmPort(sensorId) sendCommandToSensor( sensorId, json.dumps({ "sensorId": sensorId, "command": "exit" })) memCache.releaseSensorArmPort(sensorId) bbuf.close() time.sleep(1) soc.close() # kill the command dispatcher for good measure. try: if sensorCommandDispatcherPid is not None: os.kill(sensorCommandDispatcherPid, signal.SIGKILL) except: util.debugPrint("Process not found. " + str(sensorCommandDispatcherPid))
def readResourceUsage(): util.debugPrint("ResourceStreaming:dataFromStreamingServer_PID") timePerMeasurement = 0.2 timePerCapture = 1 # 1 sec per capture measurementsPerCapture = timePerCapture / timePerMeasurement try: while True: if "firstTime" not in vars(): firstTime = True if "netSentValuePrev" not in vars(): netSentValuePrev = 0 if "netRecvValuePrev" not in vars(): netRecvValuePrev = 0 cpuData = 0 vmemData = 0 netSentData = 0 netRecvData = 0 bufferCounter = 0 while True: # all data is by system as a percent usage, could be modified to be by process #cpu = p.cpu_percent() #vmem = p.virtual_memory()._asdict()['percent'] cpu = psutil.cpu_percent() vmem = psutil.virtual_memory()._asdict()['percent'] hostName = Config.getHostName() monitoredInterface = None try: if hostName != "UNKNOWN": ipAddress = socket.gethostbyname(hostName) for interface in netifaces.interfaces(): if netifaces.AF_INET in netifaces.ifaddresses( interface): for link in netifaces.ifaddresses(interface)[ netifaces.AF_INET]: if link['addr'] == ipAddress: monitoredInterface = interface break except: util.errorPrint("Could not resolve hostname " + hostName) if monitoredInterface is not None: netSent = psutil.net_io_counters( pernic=True)[monitoredInterface]._asdict( )['bytes_sent'] netRecv = psutil.net_io_counters( pernic=True)[monitoredInterface]._asdict( )['bytes_recv'] else: netSent = 0 netRecv = 0 cpuData = cpuData + cpu vmemData = vmemData + vmem netSentData = netSentData + netSent netRecvData = netRecvData + netRecv bufferCounter = bufferCounter + 1 if bufferCounter == measurementsPerCapture: # Buffer is full so push the data into memcache. bufferCounter = 0 # avg values: cpuValue = cpuData / measurementsPerCapture vmemValue = vmemData / measurementsPerCapture netSentValueNew = netSentData / measurementsPerCapture netRecvValueNew = netRecvData / measurementsPerCapture if not firstTime: netSentValue = (netSentValueNew - netSentValuePrev) / timePerCapture netRecvValue = (netRecvValueNew - netRecvValuePrev) / timePerCapture else: netSentValue = 0 netRecvValue = 0 firstTime = False netSentValuePrev = netSentValueNew netRecvValuePrev = netRecvValueNew memCache.setResourceData(MemCacheKeys.RESOURCEKEYS_CPU, cpuValue) memCache.setResourceData(MemCacheKeys.RESOURCEKEYS_VIRTMEM, vmemValue) memCache.setResourceData( MemCacheKeys.RESOURCEKEYS_NET_SENT, netSentValue) memCache.setResourceData( MemCacheKeys.RESOURCEKEYS_NET_RECV, netRecvValue) break sleepTime = timePerMeasurement time.sleep(sleepTime) except: print "Unexpected error:", sys.exc_info()[0] print sys.exc_info() import traceback traceback.print_exc() util.logStackTrace(sys.exc_info())