def save_event(self, event): logging.info("Saving event: {}".format(str(event))) try: self._db["events"].insert_one(event) except Exception as e: logging.error("Failed to save event: {}, error: {}" .format(event, e))
def done_callback(future): if future.exception() is not None: logging.error("Failed to save event: {}, error: {}".format( category, message, future.exception())) import traceback tb = future.traceback() traceback.export_tb(tb)
def __init__(self, nats_hosts): self._nats = NATS() self._io_loop = asyncio.get_event_loop() try: asyncio.run_coroutine_threadsafe(self._initialize_nats(nats_hosts), self._io_loop) except Exception as e: logging.error("NATS initialization failed with exception: " "{!r}".format(e)) raise
def setup_db_client(host="mongodb://localhost:27017"): db_client = MongoClient(host) try: # Check if the connection is established db_client.admin.command("ismaster") except ConnectionFailure as e: logging.error("Mongo server is not available: {}".format(e)) raise else: return db_client
def __init__(self, db_hosts, db_name): self._client = MongoClient(db_hosts) try: # Check if connection is established self._client.admin.command("ismaster") self._db = self._client[db_name] except ConnectionFailure as e: logging.error("Mongo server is not available: {}".format(e)) raise except InvalidName: logging.error("Invalid Mongo database name being used: {}" .format(db_name)) raise
async def _initialize_nats(self, nats_host): options = { "servers": nats_host, "io_loop": self._io_loop, "max_reconnect_attemps": 60, "disconnected_cb": self._nats_disconnected_cb, "reconnected_cb": self._nats_reconnected_cb, "error_cb": self._nats_error_cb, "closed_cb": self._nats_closed_cb } try: await self._nats.connect(**options) except ErrNoServers as e: logging.error(str(e)) raise
def create(self, filename): if not isinstance(filename, str): filename = str(filename) try: # Create video writer writer = EventVideoWriter(filename, self._rel_out_dir, self._abs_out_dir, self._video_format, self._roi, self._fps, self._frame_size, self._back_margin_q.copy(), self._max_margin_in_frames) except RuntimeError as e: logging.error(str(e)) raise else: return writer
def terminate(self, timeout=5): assert self._driver_process is not None, "It's an error to attempt to \ terminate a driver before it has been started." try: self._driver_process.join(timeout) except TimeoutError: logging.error("The driver was not terminated for some reason " "(exitcode: {}), force to terminate it.".format( self._driver_process.exitcode)) self._driver_process.terminate() time.sleep(0.1) finally: self._sig_parent.close() self._sig_parent = None self._sig_child = None self._driver_process = None
def save_event(event): logging.info("Saving event: {}".format(str(event))) try: result = db_client["jager_test"]["events"].insert_one({ "analyzerId": anal_id, "type": event.name, "timestamp": event.timestamp, "date": datetime.datetime.fromtimestamp(event.timestamp), "content": event.content }) except Exception as e: logging.error("Failed to save event: {}".format(e))
def analyzer_main_func(signal, cluster, anal_id, name, source, pipelines): logging.info("Starts running Analyzer: {}".format(name)) config = get_config()["apps"]["base"] src_reader = VideoStreamReader() try: src_reader.open(source["url"]) except ConnectionError: signal.send("source_down") raise else: video_info = src_reader.get_video_info() try: # TODO: Get the address of scheduler from the configuration # file. dask = Client(cluster.scheduler_address) pipelines = create_pipeline(anal_id, pipelines, video_info["frame_size"]) signal.send("ready") while True: frames = src_reader.read(batch_size=config["read_batch_size"]) motions = vp.detect_motion(frames, config["motion_threshold"]) for p in pipelines: p.run(frames, motions) if signal.poll() and signal.recv() == "stop": break except ConnectionError: logging.error( "Error occurred when trying to connect to source {}".format( source["url"])) # TODO: Should push a notification of this error signal.send("source_down") finally: src_reader.release() for p in pipelines: if hasattr(p, "release"): p.release() dask.close() logging.info("Analyzer terminated: {}".format(name))
def push(self, category, content, timestamp=None): logging.info("Pushing notification: {}: {}".format(category, content)) if timestamp is None: timestamp = time.time() msg = { "timestamp": timestamp, "category": category, "content": content } try: self._nats.publish(CHANNEL_NAME, msg) except ErrConnectionClosed: logging.error("Connection closed prematurely.") raise except ErrTimeout: logging.error("Timeout occurred when publishing" " event: {}".format(event)) raise
def on_create(self, params): logging.info("Creating Analyzer, params: {}".format(params)) try: sid = params["id"] name = params["name"] source = params["source"] pipelines = params["pipelines"] # Create analyzer object self._analyzers[sid] = Analyzer(self._cluster, sid, name, source, pipelines) except KeyError as e: raise RuntimeError("Invalid request format: {}".format(e.args[0])) except ConnectionError: raise RuntimeError("Failed to establish connection to {}".format( source["url"])) except Exception as e: logging.error(e)
async def _initialize_nats(self, nats_hosts): options = { "servers": nats_hosts, "io_loop": self._io_loop, "max_reconnect_attempts": 60, "reconnect_time_wait": 2, "disconnected_cb": self._nats_disconnected_cb, "reconnected_cb": self._nats_reconnected_cb, "error_cb": self._nats_error_cb, "closed_cb": self._nats_closed_cb } try: await self._nats.connect(**options) logging.info("NATS connection for Notification is established.") except ErrNoServers as e: logging.error(str(e)) raise except Exception as e: logging.error(str(e)) raise
def _output(self, catched, motion, frames): event = None ev_frames = EventVideoFrames( frames, gen_metadata(frames, motion, catched, self._state)) if self._state == IntrusionDetector.STATE_NORMAL: self._event_video_agent.append_back_margin_queue(ev_frames) if any(catched): try: timestamp = frames[0].timestamp self._current_writer = self._event_video_agent.create( timestamp) logging.info("Creating event video: {}".format(timestamp)) except RuntimeError as e: logging.error(e) raise self._state = IntrusionDetector.STATE_ALERT_START elif self._state == IntrusionDetector.STATE_ALERT_START: self._current_writer.write(ev_frames, thumbnail=True) event = IntrusionDetectionEvent( timestamp=ev_frames.raw[0].timestamp, content={ "video": self._current_writer.rel_video_filename, "thumbnail": self._current_writer.rel_thumbnail_filename, "metadata": self._current_writer.rel_metadata_filename, "triggered": ev_frames.get_triggered() }) self._state = IntrusionDetector.STATE_ALERTING elif self._state == IntrusionDetector.STATE_ALERTING: if any(catched): self._current_writer.reset_front_margin() try: self._current_writer.write(ev_frames) except EndOfMarginError: logging.info("End of event video") self._event_video_agent.clear_back_margin_queue() self._current_writer = None self._state = IntrusionDetector.STATE_NORMAL else: assert False, "Unknown state: {}".format(self._state) return event
async def push(self, category, message): logging.info("Pushing notification: ({}: {})".format(category, message)) try: await self._nats.publish(CHANNEL_NAME, json.dumps( {"category": category, "message": message}).encode()) except ErrConnectionClosed: logging.error("Connection closed prematurely.") raise except ErrTimeout: logging.error("Timeout occurred when publishing" " event: {}".format(event)) raise except Exception as e: logging.error("Failed to publish notification: {}".format(e)) raise
async def _nats_error_cb(self, e): logging.error("[NATS] ERROR: {}".format(e))
def analyzer_main_func(signal, cluster, anal_id, name, source, pipelines): logging.info("Starts running Analyzer: {}".format(name)) executor = ThreadPoolExecutor(max_workers=1) notification = Notification(["nats://localhost:4222"]) try: db_client = setup_db_client() except ConnectionFailure: return def save_event(event): logging.info("Saving event: {}".format(str(event))) try: result = db_client["jager_test"]["events"].insert_one({ "analyzerId": anal_id, "type": event.name, "timestamp": event.timestamp, "date": datetime.datetime.fromtimestamp(event.timestamp), "content": event.content }) except Exception as e: logging.error("Failed to save event: {}".format(e)) try: # TODO: Get the address of scheduler from the configuration # file. dask = Client(cluster.scheduler_address) src_reader = VideoStreamReader() src_reader.open(source["url"]) video_info = src_reader.get_video_info() pipelines = create_pipeline(anal_id, pipelines, video_info["frame_size"]) while True: frames = src_reader.read(batch_size=5) motion = vp.detect_motion(frames) results = [p.run(frames, motion) for p in pipelines] for event in results: if event is not None: notification_msg = { "type": event.name, "analyzerId": anal_id, "name": name } notification_msg.update(event.content) notification.push("Analyzer", notification_msg) executor.submit(save_event, event) if signal.poll() and signal.recv() == "stop": break except ConnectionBrokenError: logging.error( "Error occurred when trying to connect to source {}".format( source["url"])) # TODO: Should push a notifcation of this error signal.send("source_down") finally: src_reader.release() for p in pipelines: p.release() dask.close() executor.shutdown() logging.info("Analyzer terminated: {}".format(name))