예제 #1
0
 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))
예제 #2
0
 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)
예제 #3
0
 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
예제 #4
0
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
예제 #5
0
 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
예제 #6
0
 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
예제 #7
0
 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
예제 #8
0
    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
예제 #9
0
 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))
예제 #10
0
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))
예제 #11
0
 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
예제 #12
0
    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)
예제 #13
0
 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
예제 #14
0
 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
예제 #15
0
 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
예제 #16
0
 async def _nats_error_cb(self, e):
     logging.error("[NATS] ERROR: {}".format(e))
예제 #17
0
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))