<p>Harald Welte <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/12192">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Jenkins Builder: Verified
  Harald Welte: Looks good to me, approved

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">trx_toolkit: introduce logging configuration arguments<br><br>Before this change, it was impossible to configure logging<br>parameters from command line, such as log level and format.<br><br>This change introduces the following optional arguments:<br><br>  --log-level - logging level for stderr (by default, DEBUG);<br>  --log-format - logging message format for stderr;<br><br>  --log-file-name - enable logging to a given file;<br>  --log-file-level - logging level for file (by default, DEBUG);<br>  --log-file-format - logging message format for file;<br><br>which are defined in a new class called ApplicationBase, so<br>all existing applications should inherit them now.<br><br>Change-Id: Ic3b0440cd73946ad444bd7e48feb7a92d45f6488<br>---<br>A src/target/trx_toolkit/app_common.py<br>M src/target/trx_toolkit/burst_gen.py<br>M src/target/trx_toolkit/burst_send.py<br>M src/target/trx_toolkit/ctrl_cmd.py<br>M src/target/trx_toolkit/fake_trx.py<br>M src/target/trx_toolkit/trx_sniff.py<br>6 files changed, 97 insertions(+), 15 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/target/trx_toolkit/app_common.py b/src/target/trx_toolkit/app_common.py</span><br><span>new file mode 100644</span><br><span>index 0000000..180e97c</span><br><span>--- /dev/null</span><br><span>+++ b/src/target/trx_toolkit/app_common.py</span><br><span>@@ -0,0 +1,67 @@</span><br><span style="color: hsl(120, 100%, 40%);">+#!/usr/bin/env python2</span><br><span style="color: hsl(120, 100%, 40%);">+# -*- coding: utf-8 -*-</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+# TRX Toolkit</span><br><span style="color: hsl(120, 100%, 40%);">+# Common helpers for applications</span><br><span style="color: hsl(120, 100%, 40%);">+#</span><br><span style="color: hsl(120, 100%, 40%);">+# (C) 2018 by Vadim Yanitskiy <axilirator@gmail.com></span><br><span style="color: hsl(120, 100%, 40%);">+#</span><br><span style="color: hsl(120, 100%, 40%);">+# All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+#</span><br><span style="color: hsl(120, 100%, 40%);">+# This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+# it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+# the Free Software Foundation; either version 2 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+# (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+#</span><br><span style="color: hsl(120, 100%, 40%);">+# This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+# but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+# GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+#</span><br><span style="color: hsl(120, 100%, 40%);">+# You should have received a copy of the GNU General Public License along</span><br><span style="color: hsl(120, 100%, 40%);">+# with this program; if not, write to the Free Software Foundation, Inc.,</span><br><span style="color: hsl(120, 100%, 40%);">+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+import logging as log</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+class ApplicationBase:</span><br><span style="color: hsl(120, 100%, 40%);">+       # Osmocom-style logging message format</span><br><span style="color: hsl(120, 100%, 40%);">+        # Example: [DEBUG] ctrl_if_bts.py:71 Recv POWEROFF cmd</span><br><span style="color: hsl(120, 100%, 40%);">+        LOG_FMT_DEFAULT = "[%(levelname)s] %(filename)s:%(lineno)d %(message)s"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   def app_init_logging(self, argv):</span><br><span style="color: hsl(120, 100%, 40%);">+             # Default logging handler (stderr)</span><br><span style="color: hsl(120, 100%, 40%);">+            sh = log.StreamHandler()</span><br><span style="color: hsl(120, 100%, 40%);">+              sh.setLevel(log.getLevelName(argv.log_level))</span><br><span style="color: hsl(120, 100%, 40%);">+         sh.setFormatter(log.Formatter(argv.log_fmt))</span><br><span style="color: hsl(120, 100%, 40%);">+          log.root.addHandler(sh)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             # Optional file handler</span><br><span style="color: hsl(120, 100%, 40%);">+               if argv.log_file_name is not None:</span><br><span style="color: hsl(120, 100%, 40%);">+                    fh = log.FileHandler(argv.log_file_name)</span><br><span style="color: hsl(120, 100%, 40%);">+                      fh.setLevel(log.getLevelName(argv.log_file_level))</span><br><span style="color: hsl(120, 100%, 40%);">+                    fh.setFormatter(log.Formatter(argv.log_file_fmt))</span><br><span style="color: hsl(120, 100%, 40%);">+                     log.root.addHandler(fh)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+             # Set DEBUG for the root logger</span><br><span style="color: hsl(120, 100%, 40%);">+               log.root.setLevel(log.DEBUG)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        def app_reg_logging_options(self, parser):</span><br><span style="color: hsl(120, 100%, 40%);">+            parser.add_argument("--log-level", metavar = "LVL",</span><br><span style="color: hsl(120, 100%, 40%);">+                       dest = "log_level", type = str, default = "DEBUG",</span><br><span style="color: hsl(120, 100%, 40%);">+                        choices = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],</span><br><span style="color: hsl(120, 100%, 40%);">+                        help = "Set logging level (default %(default)s)")</span><br><span style="color: hsl(120, 100%, 40%);">+           parser.add_argument("--log-format", metavar = "FMT",</span><br><span style="color: hsl(120, 100%, 40%);">+                      dest = "log_fmt", type = str, default = self.LOG_FMT_DEFAULT,</span><br><span style="color: hsl(120, 100%, 40%);">+                       help = "Set logging message format")</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              parser.add_argument("--log-file-name", metavar = "FILE",</span><br><span style="color: hsl(120, 100%, 40%);">+                  dest = "log_file_name", type = str,</span><br><span style="color: hsl(120, 100%, 40%);">+                 help = "Set logging file name")</span><br><span style="color: hsl(120, 100%, 40%);">+             parser.add_argument("--log-file-level", metavar = "LVL",</span><br><span style="color: hsl(120, 100%, 40%);">+                  dest = "log_file_level", type = str, default = "DEBUG",</span><br><span style="color: hsl(120, 100%, 40%);">+                   choices = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],</span><br><span style="color: hsl(120, 100%, 40%);">+                        help = "Set logging level for file (default %(default)s)")</span><br><span style="color: hsl(120, 100%, 40%);">+          parser.add_argument("--log-file-format", metavar = "FMT",</span><br><span style="color: hsl(120, 100%, 40%);">+                 dest = "log_file_fmt", type = str, default = self.LOG_FMT_DEFAULT,</span><br><span style="color: hsl(120, 100%, 40%);">+                  help = "Set logging message format for file")</span><br><span>diff --git a/src/target/trx_toolkit/burst_gen.py b/src/target/trx_toolkit/burst_gen.py</span><br><span>index 7625a27..1c18b3c 100755</span><br><span>--- a/src/target/trx_toolkit/burst_gen.py</span><br><span>+++ b/src/target/trx_toolkit/burst_gen.py</span><br><span>@@ -31,13 +31,14 @@</span><br><span> import argparse</span><br><span> import sys</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+from app_common import ApplicationBase</span><br><span> from rand_burst_gen import RandBurstGen</span><br><span> from data_dump import DATADumpFile</span><br><span> from data_if import DATAInterface</span><br><span> from gsm_shared import *</span><br><span> from data_msg import *</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-class Application:</span><br><span style="color: hsl(120, 100%, 40%);">+class Application(ApplicationBase):</span><br><span>   def __init__(self):</span><br><span>          print_copyright(CR_HOLDERS)</span><br><span>          self.argv = self.parse_argv()</span><br><span>@@ -46,8 +47,7 @@</span><br><span>            signal.signal(signal.SIGINT, self.sig_handler)</span><br><span> </span><br><span>           # Configure logging</span><br><span style="color: hsl(0, 100%, 40%);">-             log.basicConfig(level = log.DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">-                      format = "[%(levelname)s] %(filename)s:%(lineno)d %(message)s")</span><br><span style="color: hsl(120, 100%, 40%);">+             self.app_init_logging(self.argv)</span><br><span> </span><br><span>                 # Open requested capture file</span><br><span>                if self.argv.output_file is not None:</span><br><span>@@ -135,6 +135,9 @@</span><br><span>          parser = argparse.ArgumentParser(prog = "burst_gen",</span><br><span>                       description = "Auxiliary tool to generate and send random bursts")</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+              # Register common logging options</span><br><span style="color: hsl(120, 100%, 40%);">+             self.app_reg_logging_options(parser)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>               trx_group = parser.add_argument_group("TRX interface")</span><br><span>             trx_group.add_argument("-r", "--remote-addr",</span><br><span>                    dest = "remote_addr", type = str, default = "127.0.0.1",</span><br><span>diff --git a/src/target/trx_toolkit/burst_send.py b/src/target/trx_toolkit/burst_send.py</span><br><span>index 499e929..16db222 100755</span><br><span>--- a/src/target/trx_toolkit/burst_send.py</span><br><span>+++ b/src/target/trx_toolkit/burst_send.py</span><br><span>@@ -30,12 +30,13 @@</span><br><span> import argparse</span><br><span> import sys</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+from app_common import ApplicationBase</span><br><span> from data_dump import DATADumpFile</span><br><span> from data_if import DATAInterface</span><br><span> from gsm_shared import *</span><br><span> from data_msg import *</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-class Application:</span><br><span style="color: hsl(120, 100%, 40%);">+class Application(ApplicationBase):</span><br><span>     def __init__(self):</span><br><span>          print_copyright(CR_HOLDERS)</span><br><span>          self.argv = self.parse_argv()</span><br><span>@@ -44,8 +45,7 @@</span><br><span>            signal.signal(signal.SIGINT, self.sig_handler)</span><br><span> </span><br><span>           # Configure logging</span><br><span style="color: hsl(0, 100%, 40%);">-             log.basicConfig(level = log.DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">-                      format = "[%(levelname)s] %(filename)s:%(lineno)d %(message)s")</span><br><span style="color: hsl(120, 100%, 40%);">+             self.app_init_logging(self.argv)</span><br><span> </span><br><span>                 # Open requested capture file</span><br><span>                self.ddf = DATADumpFile(self.argv.capture_file)</span><br><span>@@ -106,6 +106,9 @@</span><br><span>                parser = argparse.ArgumentParser(prog = "burst_send",</span><br><span>                      description = "Auxiliary tool to send (reply) captured bursts")</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+         # Register common logging options</span><br><span style="color: hsl(120, 100%, 40%);">+             self.app_reg_logging_options(parser)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>               trx_group = parser.add_argument_group("TRX interface")</span><br><span>             trx_group.add_argument("-r", "--remote-addr",</span><br><span>                    dest = "remote_addr", type = str, default = "127.0.0.1",</span><br><span>diff --git a/src/target/trx_toolkit/ctrl_cmd.py b/src/target/trx_toolkit/ctrl_cmd.py</span><br><span>index 43b24a3..ffc3e46 100755</span><br><span>--- a/src/target/trx_toolkit/ctrl_cmd.py</span><br><span>+++ b/src/target/trx_toolkit/ctrl_cmd.py</span><br><span>@@ -32,9 +32,10 @@</span><br><span> import select</span><br><span> import sys</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+from app_common import ApplicationBase</span><br><span> from udp_link import UDPLink</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-class Application:</span><br><span style="color: hsl(120, 100%, 40%);">+class Application(ApplicationBase):</span><br><span>         def __init__(self):</span><br><span>          print_copyright(CR_HOLDERS)</span><br><span>          self.argv = self.parse_argv()</span><br><span>@@ -43,8 +44,7 @@</span><br><span>            signal.signal(signal.SIGINT, self.sig_handler)</span><br><span> </span><br><span>           # Configure logging</span><br><span style="color: hsl(0, 100%, 40%);">-             log.basicConfig(level = log.DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">-                      format = "[%(levelname)s] %(filename)s:%(lineno)d %(message)s")</span><br><span style="color: hsl(120, 100%, 40%);">+             self.app_init_logging(self.argv)</span><br><span> </span><br><span>                 # Init UDP connection</span><br><span>                self.ctrl_link = UDPLink(</span><br><span>@@ -59,6 +59,9 @@</span><br><span>                parser = argparse.ArgumentParser(prog = "ctrl_cmd",</span><br><span>                        description = "Auxiliary tool to send control commands")</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+                # Register common logging options</span><br><span style="color: hsl(120, 100%, 40%);">+             self.app_reg_logging_options(parser)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>               trx_group = parser.add_argument_group("TRX interface")</span><br><span>             trx_group.add_argument("-r", "--remote-addr",</span><br><span>                    dest = "remote_addr", type = str, default = "127.0.0.1",</span><br><span>diff --git a/src/target/trx_toolkit/fake_trx.py b/src/target/trx_toolkit/fake_trx.py</span><br><span>index 1c991ce..a45ce20 100755</span><br><span>--- a/src/target/trx_toolkit/fake_trx.py</span><br><span>+++ b/src/target/trx_toolkit/fake_trx.py</span><br><span>@@ -31,6 +31,7 @@</span><br><span> import select</span><br><span> import sys</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+from app_common import ApplicationBase</span><br><span> from ctrl_if_bts import CTRLInterfaceBTS</span><br><span> from ctrl_if_bb import CTRLInterfaceBB</span><br><span> from burst_fwd import BurstForwarder</span><br><span>@@ -39,7 +40,7 @@</span><br><span> from udp_link import UDPLink</span><br><span> from clck_gen import CLCKGen</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-class Application:</span><br><span style="color: hsl(120, 100%, 40%);">+class Application(ApplicationBase):</span><br><span>        def __init__(self):</span><br><span>          print_copyright(CR_HOLDERS)</span><br><span>          self.argv = self.parse_argv()</span><br><span>@@ -48,8 +49,7 @@</span><br><span>            signal.signal(signal.SIGINT, self.sig_handler)</span><br><span> </span><br><span>           # Configure logging</span><br><span style="color: hsl(0, 100%, 40%);">-             log.basicConfig(level = log.DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">-                      format = "[%(levelname)s] %(filename)s:%(lineno)d %(message)s")</span><br><span style="color: hsl(120, 100%, 40%);">+             self.app_init_logging(self.argv)</span><br><span> </span><br><span>         def run(self):</span><br><span>               # Init TRX CTRL interface for BTS</span><br><span>@@ -131,6 +131,9 @@</span><br><span>              parser = argparse.ArgumentParser(prog = "fake_trx",</span><br><span>                        description = "Virtual Um-interface (fake transceiver)")</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+                # Register common logging options</span><br><span style="color: hsl(120, 100%, 40%);">+             self.app_reg_logging_options(parser)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>               trx_group = parser.add_argument_group("TRX interface")</span><br><span>             trx_group.add_argument("-b", "--trx-bind-addr",</span><br><span>                  dest = "trx_bind_addr", type = str, default = "0.0.0.0",</span><br><span>diff --git a/src/target/trx_toolkit/trx_sniff.py b/src/target/trx_toolkit/trx_sniff.py</span><br><span>index 9fb567e..7a87351 100755</span><br><span>--- a/src/target/trx_toolkit/trx_sniff.py</span><br><span>+++ b/src/target/trx_toolkit/trx_sniff.py</span><br><span>@@ -32,10 +32,11 @@</span><br><span> </span><br><span> import scapy.all</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+from app_common import ApplicationBase</span><br><span> from data_dump import DATADumpFile</span><br><span> from data_msg import *</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-class Application:</span><br><span style="color: hsl(120, 100%, 40%);">+class Application(ApplicationBase):</span><br><span>   # Counters</span><br><span>   cnt_burst_dropped_num = 0</span><br><span>    cnt_burst_num = 0</span><br><span>@@ -51,8 +52,7 @@</span><br><span>                self.argv = self.parse_argv()</span><br><span> </span><br><span>            # Configure logging</span><br><span style="color: hsl(0, 100%, 40%);">-             log.basicConfig(level = log.DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">-                      format = "[%(levelname)s] %(filename)s:%(lineno)d %(message)s")</span><br><span style="color: hsl(120, 100%, 40%);">+             self.app_init_logging(self.argv)</span><br><span> </span><br><span>                 # Open requested capture file</span><br><span>                if self.argv.output_file is not None:</span><br><span>@@ -195,6 +195,9 @@</span><br><span>                  dest = "verbose", action = "store_true",</span><br><span>                         help = "Print burst bits to stdout")</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+            # Register common logging options</span><br><span style="color: hsl(120, 100%, 40%);">+             self.app_reg_logging_options(parser)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>               trx_group = parser.add_argument_group("TRX interface")</span><br><span>             trx_group.add_argument("-i", "--sniff-interface",</span><br><span>                        dest = "sniff_if", type = str, default = "lo", metavar = "IF",</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/12192">change 12192</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/12192"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmocom-bb </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: Ic3b0440cd73946ad444bd7e48feb7a92d45f6488 </div>
<div style="display:none"> Gerrit-Change-Number: 12192 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: Vadim Yanitskiy <axilirator@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder (1000002) </div>
<div style="display:none"> Gerrit-Reviewer: Pau Espin Pedrol <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Stefan Sperling <stsp@stsp.name> </div>
<div style="display:none"> Gerrit-Reviewer: Vadim Yanitskiy <axilirator@gmail.com> </div>