From 97697ea741bf4491c3d7d3a5b8d3421a39950977 Mon Sep 17 00:00:00 2001 From: wunder957 Date: Tue, 12 Sep 2023 16:20:05 +0800 Subject: [PATCH] Switch to analyzer brief --- duetector/analyzer/db.py | 4 ++-- duetector/analyzer/models.py | 36 +++++++++++++++++++++++++++++++----- duetector/cli/main.py | 21 ++++++++++++++++++--- 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/duetector/analyzer/db.py b/duetector/analyzer/db.py index ebc750c..ceb1a35 100644 --- a/duetector/analyzer/db.py +++ b/duetector/analyzer/db.py @@ -277,7 +277,7 @@ def brief( ] return AnalyzerBrief( - tracers=[brief.tracer for brief in briefs], - collector_ids=[brief.collector_id for brief in briefs], + tracers=set([brief.tracer for brief in briefs]), + collector_ids=set([brief.collector_id for brief in briefs]), briefs=briefs, ) diff --git a/duetector/analyzer/models.py b/duetector/analyzer/models.py index d55da4a..da50e1d 100644 --- a/duetector/analyzer/models.py +++ b/duetector/analyzer/models.py @@ -1,7 +1,7 @@ from __future__ import annotations from datetime import datetime -from typing import Any, Dict, List, Optional +from typing import Any, Dict, List, Optional, Set import pydantic @@ -67,20 +67,46 @@ class Brief(pydantic.BaseModel): count: Optional[int] = None fields: Dict[str, Any] = {} + def __repr__(self): + fields_repr = ", ".join([f"{k}: {v.__name__}" for k, v in self.fields.items()]) + + s = f""" +{self.tracer}@{self.collector_id} with {self.count} records +from {self.start} to {self.end} +available fields: [{fields_repr}] +""" + + return s + + def __str__(self): + return self.__repr__() + class AnalyzerBrief(pydantic.BaseModel): """ Brief of analyzer. """ - tracers: List[str] + tracers: Set[str] """ - List of tracers + Set of tracers """ - collector_ids: List[str] + collector_ids: Set[str] """ - List of collector ids + Set of collector ids """ briefs: List[Brief] + + def __repr__(self): + briefs_repr = "\n".join([f"\n----------------{b}----------------" for b in self.briefs]) + s = f""" +Available tracers: {self.tracers} +Available collector ids: {self.collector_ids} +briefs: {briefs_repr} +""" + return s + + def __str__(self): + return self.__repr__() diff --git a/duetector/cli/main.py b/duetector/cli/main.py index 09892ba..75d8830 100644 --- a/duetector/cli/main.py +++ b/duetector/cli/main.py @@ -7,6 +7,7 @@ import click +from duetector.analyzer.db import DBAnalyzer from duetector.config import CONFIG_PATH, ConfigLoader from duetector.log import logger from duetector.monitors import BccMonitor, ShMonitor @@ -94,7 +95,9 @@ def generate_config(path): @click.command() @click.option( - "--config", default=CONFIG_PATH, help=f"Config file path, default: ``{CONFIG_PATH}``." + "--config", + default=CONFIG_PATH, + help=f"Config file path, default: ``{CONFIG_PATH}``.", ) @click.option( "--load_env", @@ -124,6 +127,11 @@ def generate_config(path): default=True, help=f"Set false or False to disable shell monitor, default: ``True``.", ) +@click.option( + "--brief", + default=True, + help=f"Print brief when exit, default: ``True``.", +) def start( config, load_env, @@ -131,6 +139,7 @@ def start( config_dump_dir, enable_bcc_monitor, enable_sh_monitor, + brief, ): """ Start A bcc monitor and wait for KeyboardInterrupt @@ -157,8 +166,14 @@ def _shutdown(sig=None, frame=None): logger.info("Exiting...") for m in monitors: m.shutdown() - for m in monitors: - logger.info(m.summary()) + logger.info("All monitors shutdown.") + if brief: + try: + logger.info("Generating brief...") + logger.info(str(DBAnalyzer(c).brief())) + except Exception as e: + logger.error("Exception when generating brief") + logger.exception(e) exit(0) signal.signal(signal.SIGINT, _shutdown)