DPDK patches and discussions
 help / color / mirror / Atom feed
From: "Juraj Linkeš" <juraj.linkes@pantheon.tech>
To: thomas@monjalon.net, Honnappa.Nagarahalli@arm.com,
	jspewock@iol.unh.edu, probb@iol.unh.edu, paul.szczepanek@arm.com,
	yoan.picchi@foss.arm.com, Luca.Vizzarro@arm.com
Cc: dev@dpdk.org, "Juraj Linkeš" <juraj.linkes@pantheon.tech>
Subject: [RFC PATCH v1 5/5] dts: refactor logging configuration
Date: Wed, 20 Dec 2023 11:33:31 +0100	[thread overview]
Message-ID: <20231220103331.60888-6-juraj.linkes@pantheon.tech> (raw)
In-Reply-To: <20231220103331.60888-1-juraj.linkes@pantheon.tech>

Refactor logging for improved configuration and flexibility,
investigating unclear arguments and exploring alternatives
for logging test suites into separate files. In addition,
efforts were made to ensure that the modules remained
independent from the logger module, enabling potential use
by other consumers.

Signed-off-by: Juraj Linkeš <juraj.linkes@pantheon.tech>
---
 dts/framework/logger.py                       | 162 ++++++++----------
 dts/framework/remote_session/__init__.py      |   4 +-
 dts/framework/remote_session/os_session.py    |   6 +-
 .../remote_session/remote/__init__.py         |   7 +-
 .../remote/interactive_remote_session.py      |   7 +-
 .../remote/interactive_shell.py               |   7 +-
 .../remote_session/remote/remote_session.py   |   8 +-
 .../remote_session/remote/ssh_session.py      |   5 +-
 dts/framework/runner.py                       |  13 +-
 dts/framework/test_result.py                  |   6 +-
 dts/framework/test_suite.py                   |   6 +-
 dts/framework/testbed_model/node.py           |  10 +-
 dts/framework/testbed_model/scapy.py          |   6 +-
 .../testbed_model/traffic_generator.py        |   5 +-
 dts/main.py                                   |   6 +-
 15 files changed, 124 insertions(+), 134 deletions(-)

diff --git a/dts/framework/logger.py b/dts/framework/logger.py
index bb2991e994..43c49c2d03 100644
--- a/dts/framework/logger.py
+++ b/dts/framework/logger.py
@@ -10,108 +10,98 @@
 
 import logging
 import os.path
-from typing import TypedDict
-
-from .settings import SETTINGS
+from enum import Enum
+from logging import FileHandler, StreamHandler
+from pathlib import Path
 
 date_fmt = "%Y/%m/%d %H:%M:%S"
-stream_fmt = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
+stream_fmt = "%(asctime)s - %(stage)s - %(name)s - %(levelname)s - %(message)s"
 
 
-class LoggerDictType(TypedDict):
-    logger: "DTSLOG"
-    name: str
-    node: str
+def init_logger(verbose: bool, output_dir: str):
+    logging.raiseExceptions = False
 
+    DTSLog._output_dir = output_dir
+    logging.setLoggerClass(DTSLog)
 
-# List for saving all using loggers
-Loggers: list[LoggerDictType] = []
+    root_logger = logging.getLogger()
+    root_logger.setLevel(1)
 
+    sh = StreamHandler()
+    sh.setFormatter(logging.Formatter(stream_fmt, date_fmt))
+    sh.setLevel(logging.INFO)
+    if verbose:
+        sh.setLevel(logging.DEBUG)
+    root_logger.addHandler(sh)
 
-class DTSLOG(logging.LoggerAdapter):
-    """
-    DTS log class for framework and testsuite.
-    """
+    if not os.path.exists(output_dir):
+        os.mkdir(output_dir)
 
-    _logger: logging.Logger
-    node: str
-    sh: logging.StreamHandler
-    fh: logging.FileHandler
-    verbose_fh: logging.FileHandler
+    add_file_handlers(Path(output_dir, "dts"))
 
-    def __init__(self, logger: logging.Logger, node: str = "suite"):
-        self._logger = logger
-        # 1 means log everything, this will be used by file handlers if their level
-        # is not set
-        self._logger.setLevel(1)
 
-        self.node = node
+def add_file_handlers(log_file_path: Path) -> list[FileHandler]:
+    root_logger = logging.getLogger()
 
-        # add handler to emit to stdout
-        sh = logging.StreamHandler()
-        sh.setFormatter(logging.Formatter(stream_fmt, date_fmt))
-        sh.setLevel(logging.INFO)  # console handler default level
+    fh = FileHandler(f"{log_file_path}.log")
+    fh.setFormatter(logging.Formatter(stream_fmt, date_fmt))
+    root_logger.addHandler(fh)
 
-        if SETTINGS.verbose is True:
-            sh.setLevel(logging.DEBUG)
+    verbose_fh = FileHandler(f"{log_file_path}.verbose.log")
+    verbose_fh.setFormatter(
+        logging.Formatter(
+            "%(asctime)s|%(stage)s|%(name)s|%(levelname)s|%(pathname)s|%(lineno)d|"
+            "%(funcName)s|%(process)d|%(thread)d|%(threadName)s|%(message)s",
+            datefmt=date_fmt,
+        )
+    )
+    root_logger.addHandler(verbose_fh)
 
-        self._logger.addHandler(sh)
-        self.sh = sh
+    return [fh, verbose_fh]
 
-        # prepare the output folder
-        if not os.path.exists(SETTINGS.output_dir):
-            os.mkdir(SETTINGS.output_dir)
 
-        logging_path_prefix = os.path.join(SETTINGS.output_dir, node)
+class DtsStage(Enum):
+    pre_execution = "pre-execution"
+    execution = "execution"
+    build_target = "build-target"
+    suite = "suite"
+    post_execution = "post-execution"
 
-        fh = logging.FileHandler(f"{logging_path_prefix}.log")
-        fh.setFormatter(
-            logging.Formatter(
-                fmt="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
-                datefmt=date_fmt,
-            )
-        )
+    def __str__(self) -> str:
+        return self.value
 
-        self._logger.addHandler(fh)
-        self.fh = fh
-
-        # This outputs EVERYTHING, intended for post-mortem debugging
-        # Also optimized for processing via AWK (awk -F '|' ...)
-        verbose_fh = logging.FileHandler(f"{logging_path_prefix}.verbose.log")
-        verbose_fh.setFormatter(
-            logging.Formatter(
-                fmt="%(asctime)s|%(name)s|%(levelname)s|%(pathname)s|%(lineno)d|"
-                "%(funcName)s|%(process)d|%(thread)d|%(threadName)s|%(message)s",
-                datefmt=date_fmt,
-            )
-        )
 
-        self._logger.addHandler(verbose_fh)
-        self.verbose_fh = verbose_fh
-
-        super(DTSLOG, self).__init__(self._logger, dict(node=self.node))
-
-    def logger_exit(self) -> None:
-        """
-        Remove stream handler and logfile handler.
-        """
-        for handler in (self.sh, self.fh, self.verbose_fh):
-            handler.flush()
-            self._logger.removeHandler(handler)
-
-
-def getLogger(name: str, node: str = "suite") -> DTSLOG:
-    """
-    Get logger handler and if there's no handler for specified Node will create one.
-    """
-    global Loggers
-    # return saved logger
-    logger: LoggerDictType
-    for logger in Loggers:
-        if logger["name"] == name and logger["node"] == node:
-            return logger["logger"]
-
-    # return new logger
-    dts_logger: DTSLOG = DTSLOG(logging.getLogger(name), node)
-    Loggers.append({"logger": dts_logger, "name": name, "node": node})
-    return dts_logger
+class DTSLog(logging.Logger):
+    _stage: DtsStage = DtsStage.pre_execution
+    _extra_file_handlers: list[FileHandler] = []
+    _output_dir: None | str = None
+
+    def makeRecord(self, *args, **kwargs):
+        record = super().makeRecord(*args, **kwargs)
+        record.stage = DTSLog._stage
+        return record
+
+    def set_stage(self, stage: DtsStage, log_file_name: str | None = None):
+        self._remove_extra_file_handlers()
+
+        if DTSLog._stage != stage:
+            self.info(f"Moving from stage '{DTSLog._stage}' to stage '{stage}'.")
+            DTSLog._stage = stage
+
+        if log_file_name:
+            if DTSLog._output_dir:
+                DTSLog._extra_file_handlers.extend(
+                    add_file_handlers(Path(DTSLog._output_dir, log_file_name))
+                )
+            else:
+                self.warning(
+                    f"Cannot log '{DTSLog._stage}' stage in separate file, "
+                    "output dir is not defined."
+                )
+
+    def _remove_extra_file_handlers(self) -> None:
+        if DTSLog._extra_file_handlers:
+            for extra_file_handler in DTSLog._extra_file_handlers:
+                self.root.removeHandler(extra_file_handler)
+
+            DTSLog._extra_file_handlers = []
diff --git a/dts/framework/remote_session/__init__.py b/dts/framework/remote_session/__init__.py
index 6124417bd7..a4ec2f40ae 100644
--- a/dts/framework/remote_session/__init__.py
+++ b/dts/framework/remote_session/__init__.py
@@ -11,10 +11,10 @@
 """
 
 # pylama:ignore=W0611
+import logging
 
 from framework.config import OS, NodeConfiguration
 from framework.exception import ConfigurationError
-from framework.logger import DTSLOG
 
 from .linux_session import LinuxSession
 from .os_session import InteractiveShellType, OSSession
@@ -30,7 +30,7 @@
 )
 
 
-def create_session(node_config: NodeConfiguration, name: str, logger: DTSLOG) -> OSSession:
+def create_session(node_config: NodeConfiguration, name: str, logger: logging.Logger) -> OSSession:
     match node_config.os:
         case OS.linux:
             return LinuxSession(node_config, name, logger)
diff --git a/dts/framework/remote_session/os_session.py b/dts/framework/remote_session/os_session.py
index 8a709eac1c..2524a4e669 100644
--- a/dts/framework/remote_session/os_session.py
+++ b/dts/framework/remote_session/os_session.py
@@ -2,6 +2,7 @@
 # Copyright(c) 2023 PANTHEON.tech s.r.o.
 # Copyright(c) 2023 University of New Hampshire
 
+import logging
 from abc import ABC, abstractmethod
 from collections.abc import Iterable
 from ipaddress import IPv4Interface, IPv6Interface
@@ -9,7 +10,6 @@
 from typing import Type, TypeVar, Union
 
 from framework.config import Architecture, NodeConfiguration, NodeInfo
-from framework.logger import DTSLOG
 from framework.remote_session.remote import InteractiveShell
 from framework.settings import SETTINGS
 from framework.testbed_model import LogicalCore
@@ -36,7 +36,7 @@ class OSSession(ABC):
 
     _config: NodeConfiguration
     name: str
-    _logger: DTSLOG
+    _logger: logging.Logger
     remote_session: RemoteSession
     interactive_session: InteractiveRemoteSession
 
@@ -44,7 +44,7 @@ def __init__(
         self,
         node_config: NodeConfiguration,
         name: str,
-        logger: DTSLOG,
+        logger: logging.Logger,
     ):
         self._config = node_config
         self.name = name
diff --git a/dts/framework/remote_session/remote/__init__.py b/dts/framework/remote_session/remote/__init__.py
index 06403691a5..4a22155153 100644
--- a/dts/framework/remote_session/remote/__init__.py
+++ b/dts/framework/remote_session/remote/__init__.py
@@ -4,8 +4,9 @@
 
 # pylama:ignore=W0611
 
+import logging
+
 from framework.config import NodeConfiguration
-from framework.logger import DTSLOG
 
 from .interactive_remote_session import InteractiveRemoteSession
 from .interactive_shell import InteractiveShell
@@ -16,12 +17,12 @@
 
 
 def create_remote_session(
-    node_config: NodeConfiguration, name: str, logger: DTSLOG
+    node_config: NodeConfiguration, name: str, logger: logging.Logger
 ) -> RemoteSession:
     return SSHSession(node_config, name, logger)
 
 
 def create_interactive_session(
-    node_config: NodeConfiguration, logger: DTSLOG
+    node_config: NodeConfiguration, logger: logging.Logger
 ) -> InteractiveRemoteSession:
     return InteractiveRemoteSession(node_config, logger)
diff --git a/dts/framework/remote_session/remote/interactive_remote_session.py b/dts/framework/remote_session/remote/interactive_remote_session.py
index 098ded1bb0..bf0996a747 100644
--- a/dts/framework/remote_session/remote/interactive_remote_session.py
+++ b/dts/framework/remote_session/remote/interactive_remote_session.py
@@ -2,7 +2,7 @@
 # Copyright(c) 2023 University of New Hampshire
 
 """Handler for an SSH session dedicated to interactive shells."""
-
+import logging
 import socket
 import traceback
 
@@ -16,7 +16,6 @@
 
 from framework.config import NodeConfiguration
 from framework.exception import SSHConnectionError
-from framework.logger import DTSLOG
 
 
 class InteractiveRemoteSession:
@@ -54,11 +53,11 @@ class InteractiveRemoteSession:
     username: str
     password: str
     session: SSHClient
-    _logger: DTSLOG
+    _logger: logging.Logger
     _node_config: NodeConfiguration
     _transport: Transport | None
 
-    def __init__(self, node_config: NodeConfiguration, _logger: DTSLOG) -> None:
+    def __init__(self, node_config: NodeConfiguration, _logger: logging.Logger) -> None:
         self._node_config = node_config
         self._logger = _logger
         self.hostname = node_config.hostname
diff --git a/dts/framework/remote_session/remote/interactive_shell.py b/dts/framework/remote_session/remote/interactive_shell.py
index 4db19fb9b3..b6074838c2 100644
--- a/dts/framework/remote_session/remote/interactive_shell.py
+++ b/dts/framework/remote_session/remote/interactive_shell.py
@@ -11,14 +11,13 @@
 elevated privileges to start it is expected that the method for gaining those
 privileges is provided when initializing the class.
 """
-
+import logging
 from abc import ABC
 from pathlib import PurePath
 from typing import Callable
 
 from paramiko import Channel, SSHClient, channel  # type: ignore[import]
 
-from framework.logger import DTSLOG
 from framework.settings import SETTINGS
 
 
@@ -58,7 +57,7 @@ class InteractiveShell(ABC):
     _stdin: channel.ChannelStdinFile
     _stdout: channel.ChannelFile
     _ssh_channel: Channel
-    _logger: DTSLOG
+    _logger: logging.Logger
     _timeout: float
     _app_args: str
     _default_prompt: str = ""
@@ -69,7 +68,7 @@ class InteractiveShell(ABC):
     def __init__(
         self,
         interactive_session: SSHClient,
-        logger: DTSLOG,
+        logger: logging.Logger,
         get_privileged_command: Callable[[str], str] | None,
         app_args: str = "",
         timeout: float = SETTINGS.timeout,
diff --git a/dts/framework/remote_session/remote/remote_session.py b/dts/framework/remote_session/remote/remote_session.py
index 719f7d1ef7..da78e5c921 100644
--- a/dts/framework/remote_session/remote/remote_session.py
+++ b/dts/framework/remote_session/remote/remote_session.py
@@ -2,14 +2,13 @@
 # Copyright(c) 2010-2014 Intel Corporation
 # Copyright(c) 2022-2023 PANTHEON.tech s.r.o.
 # Copyright(c) 2022-2023 University of New Hampshire
-
 import dataclasses
+import logging
 from abc import ABC, abstractmethod
 from pathlib import PurePath
 
 from framework.config import NodeConfiguration
 from framework.exception import RemoteCommandExecutionError
-from framework.logger import DTSLOG
 from framework.settings import SETTINGS
 
 
@@ -50,14 +49,14 @@ class RemoteSession(ABC):
     username: str
     password: str
     history: list[CommandResult]
-    _logger: DTSLOG
+    _logger: logging.Logger
     _node_config: NodeConfiguration
 
     def __init__(
         self,
         node_config: NodeConfiguration,
         session_name: str,
-        logger: DTSLOG,
+        logger: logging.Logger,
     ):
         self._node_config = node_config
 
@@ -120,7 +119,6 @@ def close(self, force: bool = False) -> None:
         """
         Close the remote session and free all used resources.
         """
-        self._logger.logger_exit()
         self._close(force)
 
     @abstractmethod
diff --git a/dts/framework/remote_session/remote/ssh_session.py b/dts/framework/remote_session/remote/ssh_session.py
index 1a7ee649ab..42441c4587 100644
--- a/dts/framework/remote_session/remote/ssh_session.py
+++ b/dts/framework/remote_session/remote/ssh_session.py
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright(c) 2023 PANTHEON.tech s.r.o.
-
+import logging
 import socket
 import traceback
 from pathlib import PurePath
@@ -20,7 +20,6 @@
 
 from framework.config import NodeConfiguration
 from framework.exception import SSHConnectionError, SSHSessionDeadError, SSHTimeoutError
-from framework.logger import DTSLOG
 
 from .remote_session import CommandResult, RemoteSession
 
@@ -49,7 +48,7 @@ def __init__(
         self,
         node_config: NodeConfiguration,
         session_name: str,
-        logger: DTSLOG,
+        logger: logging.Logger,
     ):
         super(SSHSession, self).__init__(node_config, session_name, logger)
 
diff --git a/dts/framework/runner.py b/dts/framework/runner.py
index 28570d4a1c..5c06e4ca1a 100644
--- a/dts/framework/runner.py
+++ b/dts/framework/runner.py
@@ -11,6 +11,7 @@
 from copy import deepcopy
 from dataclasses import dataclass
 from types import MethodType, ModuleType
+from typing import cast
 
 from .config import (
     BuildTargetConfiguration,
@@ -24,7 +25,7 @@
     SSHTimeoutError,
     TestCaseVerifyError,
 )
-from .logger import DTSLOG, getLogger
+from .logger import DTSLog, DtsStage
 from .settings import SETTINGS
 from .test_result import (
     BuildTargetResult,
@@ -68,12 +69,12 @@ def processed_config(self) -> ExecutionConfiguration:
 
 
 class DTSRunner:
-    _logger: DTSLOG
+    _logger: DTSLog
     _result: DTSResult
     _executions: list[Execution]
 
     def __init__(self, configuration: Configuration):
-        self._logger = getLogger("DTSRunner")
+        self._logger = cast(DTSLog, logging.getLogger("DTSRunner"))
         self._result = DTSResult(configuration, self._logger)
         self._executions = create_executions(configuration.executions)
 
@@ -146,6 +147,7 @@ def _run_execution(
         Run the given execution. This involves running the execution setup as well as
         running all build targets in the given execution.
         """
+        self._logger.set_stage(DtsStage.execution)
         self._logger.info(
             "Running execution with SUT "
             f"'{execution.config.system_under_test_node.name}'."
@@ -175,6 +177,7 @@ def _run_execution(
                 sut_node.tear_down_execution()
                 execution_result.update_teardown(Result.PASS)
             except Exception as e:
+                self._logger.set_stage(DtsStage.execution)
                 self._logger.exception("Execution teardown failed.")
                 execution_result.update_teardown(Result.FAIL, e)
 
@@ -189,6 +192,7 @@ def _run_build_target(
         """
         Run the given build target.
         """
+        self._logger.set_stage(DtsStage.build_target)
         self._logger.info(f"Running build target '{build_target.name}'.")
         build_target_result = execution_result.add_child_result(build_target)
 
@@ -209,6 +213,7 @@ def _run_build_target(
                 sut_node.tear_down_build_target()
                 build_target_result.update_teardown(Result.PASS)
             except Exception as e:
+                self._logger.set_stage(DtsStage.build_target)
                 self._logger.exception("Build target teardown failed.")
                 build_target_result.update_teardown(Result.FAIL, e)
 
@@ -265,6 +270,7 @@ def _run_test_suite(
         """
         test_suite = test_suite_setup.test_suite(sut_node, tg_node)
         test_suite_name = test_suite_setup.test_suite.__name__
+        self._logger.set_stage(DtsStage.suite, test_suite_name)
         test_suite_result = build_target_result.add_child_result(
             test_suite_setup.processed_config()
         )
@@ -397,6 +403,7 @@ def _exit_dts(self) -> None:
         self._result.process()
 
         if self._logger:
+            self._logger.set_stage(DtsStage.post_execution)
             self._logger.info("DTS execution has ended.")
 
         logging.shutdown()
diff --git a/dts/framework/test_result.py b/dts/framework/test_result.py
index dba2c55d36..221e75205e 100644
--- a/dts/framework/test_result.py
+++ b/dts/framework/test_result.py
@@ -6,6 +6,7 @@
 Generic result container and reporters
 """
 
+import logging
 import os.path
 from collections.abc import MutableSequence
 from enum import Enum, auto
@@ -24,7 +25,6 @@
     TestSuiteConfig,
 )
 from .exception import DTSError, ErrorSeverity
-from .logger import DTSLOG
 from .settings import SETTINGS
 
 
@@ -153,13 +153,13 @@ class DTSResult(BaseResult):
 
     dpdk_version: str | None
     _child_configs: list[ExecutionConfiguration]
-    _logger: DTSLOG
+    _logger: logging.Logger
     _errors: list[Exception]
     _return_code: ErrorSeverity
     _stats_result: Union["Statistics", None]
     _stats_filename: str
 
-    def __init__(self, configuration: Configuration, logger: DTSLOG):
+    def __init__(self, configuration: Configuration, logger: logging.Logger):
         super(DTSResult, self).__init__()
         self.dpdk_version = None
         self._child_configs = configuration.executions
diff --git a/dts/framework/test_suite.py b/dts/framework/test_suite.py
index e73206993d..9c9a8c1e08 100644
--- a/dts/framework/test_suite.py
+++ b/dts/framework/test_suite.py
@@ -6,6 +6,7 @@
 Base class for creating DTS test cases.
 """
 
+import logging
 from ipaddress import IPv4Interface, IPv6Interface, ip_interface
 from typing import Union
 
@@ -14,7 +15,6 @@
 from scapy.packet import Packet, Padding  # type: ignore[import]
 
 from .exception import TestCaseVerifyError
-from .logger import DTSLOG, getLogger
 from .testbed_model import SutNode, TGNode
 from .testbed_model.hw.port import Port, PortLink
 from .utils import get_packet_summaries
@@ -41,7 +41,7 @@ class TestSuite(object):
     sut_node: SutNode
     tg_node: TGNode
     is_blocking = False
-    _logger: DTSLOG
+    _logger: logging.Logger
     _port_links: list[PortLink]
     _sut_port_ingress: Port
     _sut_port_egress: Port
@@ -59,7 +59,7 @@ def __init__(
     ):
         self.sut_node = sut_node
         self.tg_node = tg_node
-        self._logger = getLogger(self.__class__.__name__)
+        self._logger = logging.getLogger(self.__class__.__name__)
         self._port_links = []
         self._process_links()
         self._sut_port_ingress, self._tg_port_egress = (
diff --git a/dts/framework/testbed_model/node.py b/dts/framework/testbed_model/node.py
index ef700d8114..a98c58df4f 100644
--- a/dts/framework/testbed_model/node.py
+++ b/dts/framework/testbed_model/node.py
@@ -6,7 +6,7 @@
 """
 A node is a generic host that DTS connects to and manages.
 """
-
+import logging
 from abc import ABC
 from ipaddress import IPv4Interface, IPv6Interface
 from typing import Any, Callable, Type, Union
@@ -16,7 +16,6 @@
     ExecutionConfiguration,
     NodeConfiguration,
 )
-from framework.logger import DTSLOG, getLogger
 from framework.remote_session import InteractiveShellType, OSSession, create_session
 from framework.settings import SETTINGS
 
@@ -43,7 +42,7 @@ class Node(ABC):
     name: str
     lcores: list[LogicalCore]
     ports: list[Port]
-    _logger: DTSLOG
+    _logger: logging.Logger
     _other_sessions: list[OSSession]
     _execution_config: ExecutionConfiguration
     virtual_devices: list[VirtualDevice]
@@ -51,7 +50,7 @@ class Node(ABC):
     def __init__(self, node_config: NodeConfiguration):
         self.config = node_config
         self.name = node_config.name
-        self._logger = getLogger(self.name)
+        self._logger = logging.getLogger(self.name)
         self.main_session = create_session(self.config, self.name, self._logger)
 
         self._logger.info(f"Connected to node: {self.name}")
@@ -137,7 +136,7 @@ def create_session(self, name: str) -> OSSession:
         connection = create_session(
             self.config,
             session_name,
-            getLogger(session_name, node=self.name),
+            logging.getLogger(session_name),
         )
         self._other_sessions.append(connection)
         return connection
@@ -237,7 +236,6 @@ def close(self) -> None:
             self.main_session.close()
         for session in self._other_sessions:
             session.close()
-        self._logger.logger_exit()
 
     @staticmethod
     def skip_setup(func: Callable[..., Any]) -> Callable[..., Any]:
diff --git a/dts/framework/testbed_model/scapy.py b/dts/framework/testbed_model/scapy.py
index 9083e92b3d..61058cd38a 100644
--- a/dts/framework/testbed_model/scapy.py
+++ b/dts/framework/testbed_model/scapy.py
@@ -13,6 +13,7 @@
 """
 
 import inspect
+import logging
 import marshal
 import time
 import types
@@ -24,7 +25,6 @@
 from scapy.packet import Packet  # type: ignore[import]
 
 from framework.config import OS, ScapyTrafficGeneratorConfig
-from framework.logger import DTSLOG, getLogger
 from framework.remote_session import PythonShell
 from framework.settings import SETTINGS
 
@@ -190,12 +190,12 @@ class ScapyTrafficGenerator(CapturingTrafficGenerator):
     rpc_server_proxy: xmlrpc.client.ServerProxy
     _config: ScapyTrafficGeneratorConfig
     _tg_node: TGNode
-    _logger: DTSLOG
+    _logger: logging.Logger
 
     def __init__(self, tg_node: TGNode, config: ScapyTrafficGeneratorConfig):
         self._config = config
         self._tg_node = tg_node
-        self._logger = getLogger(f"{self._tg_node.name} {self._config.traffic_generator_type}")
+        self._logger = logging.getLogger(f"{self._tg_node.name} {self._config.traffic_generator_type}")
 
         assert (
             self._tg_node.config.os == OS.linux
diff --git a/dts/framework/testbed_model/traffic_generator.py b/dts/framework/testbed_model/traffic_generator.py
index 28c35d3ce4..6b0838958a 100644
--- a/dts/framework/testbed_model/traffic_generator.py
+++ b/dts/framework/testbed_model/traffic_generator.py
@@ -7,12 +7,11 @@
 These traffic generators can't capture received traffic,
 only count the number of received packets.
 """
-
+import logging
 from abc import ABC, abstractmethod
 
 from scapy.packet import Packet  # type: ignore[import]
 
-from framework.logger import DTSLOG
 from framework.utils import get_packet_summaries
 
 from .hw.port import Port
@@ -24,7 +23,7 @@ class TrafficGenerator(ABC):
     Defines the few basic methods that each traffic generator must implement.
     """
 
-    _logger: DTSLOG
+    _logger: logging.Logger
 
     def send_packet(self, packet: Packet, port: Port) -> None:
         """Send a packet and block until it is fully sent.
diff --git a/dts/main.py b/dts/main.py
index 879ce5cb89..f2828148f0 100755
--- a/dts/main.py
+++ b/dts/main.py
@@ -8,18 +8,18 @@
 A test framework for testing DPDK.
 """
 
-import logging
-
 from framework.config import load_config
+from framework.logger import init_logger
 from framework.runner import DTSRunner
+from framework.settings import SETTINGS
 
 
 def main() -> None:
+    init_logger(SETTINGS.verbose, SETTINGS.output_dir)
     dts = DTSRunner(configuration=load_config())
     dts.run()
 
 
 # Main program begins here
 if __name__ == "__main__":
-    logging.raiseExceptions = True
     main()
-- 
2.34.1


  parent reply	other threads:[~2023-12-20 10:34 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-20 10:33 [RFC PATCH v1 0/5] test case blocking and logging Juraj Linkeš
2023-12-20 10:33 ` [RFC PATCH v1 1/5] dts: convert dts.py methods to class Juraj Linkeš
2023-12-20 10:33 ` [RFC PATCH v1 2/5] dts: move test suite execution logic to DTSRunner Juraj Linkeš
2023-12-20 10:33 ` [RFC PATCH v1 3/5] dts: process test suites at the beginning of run Juraj Linkeš
2023-12-20 10:33 ` [RFC PATCH v1 4/5] dts: block all testcases when earlier setup fails Juraj Linkeš
2023-12-20 10:33 ` Juraj Linkeš [this message]
2024-01-08 18:47 ` [RFC PATCH v1 0/5] test case blocking and logging Jeremy Spewock
2024-02-06 14:57 ` [PATCH v2 0/7] " Juraj Linkeš
2024-02-06 14:57   ` [PATCH v2 1/7] dts: convert dts.py methods to class Juraj Linkeš
2024-02-06 14:57   ` [PATCH v2 2/7] dts: move test suite execution logic to DTSRunner Juraj Linkeš
2024-02-06 14:57   ` [PATCH v2 3/7] dts: filter test suites in executions Juraj Linkeš
2024-02-12 16:44     ` Jeremy Spewock
2024-02-14  9:55       ` Juraj Linkeš
2024-02-06 14:57   ` [PATCH v2 4/7] dts: reorganize test result Juraj Linkeš
2024-02-06 14:57   ` [PATCH v2 5/7] dts: block all test cases when earlier setup fails Juraj Linkeš
2024-02-06 14:57   ` [PATCH v2 6/7] dts: refactor logging configuration Juraj Linkeš
2024-02-12 16:45     ` Jeremy Spewock
2024-02-14  7:49       ` Juraj Linkeš
2024-02-14 16:51         ` Jeremy Spewock
2024-02-06 14:57   ` [PATCH v2 7/7] dts: improve test suite and case filtering Juraj Linkeš
2024-02-23  7:54 ` [PATCH v3 0/7] test case blocking and logging Juraj Linkeš
2024-02-23  7:54   ` [PATCH v3 1/7] dts: convert dts.py methods to class Juraj Linkeš
2024-02-23  7:54   ` [PATCH v3 2/7] dts: move test suite execution logic to DTSRunner Juraj Linkeš
2024-02-23  7:54   ` [PATCH v3 3/7] dts: filter test suites in executions Juraj Linkeš
2024-02-27 21:21     ` Jeremy Spewock
2024-02-28  9:16       ` Juraj Linkeš
2024-02-23  7:54   ` [PATCH v3 4/7] dts: reorganize test result Juraj Linkeš
2024-02-23  7:55   ` [PATCH v3 5/7] dts: block all test cases when earlier setup fails Juraj Linkeš
2024-02-23  7:55   ` [PATCH v3 6/7] dts: refactor logging configuration Juraj Linkeš
2024-02-23  7:55   ` [PATCH v3 7/7] dts: improve test suite and case filtering Juraj Linkeš
2024-02-27 21:24   ` [PATCH v3 0/7] test case blocking and logging Jeremy Spewock
2024-03-01 10:55 ` [PATCH v4 " Juraj Linkeš
2024-03-01 10:55   ` [PATCH v4 1/7] dts: convert dts.py methods to class Juraj Linkeš
2024-03-01 10:55   ` [PATCH v4 2/7] dts: move test suite execution logic to DTSRunner Juraj Linkeš
2024-03-01 10:55   ` [PATCH v4 3/7] dts: filter test suites in executions Juraj Linkeš
2024-03-01 10:55   ` [PATCH v4 4/7] dts: reorganize test result Juraj Linkeš
2024-03-01 10:55   ` [PATCH v4 5/7] dts: block all test cases when earlier setup fails Juraj Linkeš
2024-03-01 10:55   ` [PATCH v4 6/7] dts: refactor logging configuration Juraj Linkeš
2024-03-01 10:55   ` [PATCH v4 7/7] dts: improve test suite and case filtering Juraj Linkeš
2024-03-01 17:41     ` Jeremy Spewock
2024-03-01 17:43       ` Jeremy Spewock
2024-03-07 11:04         ` Thomas Monjalon
2024-03-01 16:11   ` [PATCH v4 0/7] test case blocking and logging Patrick Robb
2024-03-07 14:55   ` Thomas Monjalon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231220103331.60888-6-juraj.linkes@pantheon.tech \
    --to=juraj.linkes@pantheon.tech \
    --cc=Honnappa.Nagarahalli@arm.com \
    --cc=Luca.Vizzarro@arm.com \
    --cc=dev@dpdk.org \
    --cc=jspewock@iol.unh.edu \
    --cc=paul.szczepanek@arm.com \
    --cc=probb@iol.unh.edu \
    --cc=thomas@monjalon.net \
    --cc=yoan.picchi@foss.arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).