forked from platformio/platformio-core
Control device monitor output with filters and text transformations
This commit is contained in:
@@ -9,6 +9,7 @@ PlatformIO Core 4
|
|||||||
4.2.2 (2020-??-??)
|
4.2.2 (2020-??-??)
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
* Control device monitor output with `filters and text transformations <https://docs.platformio.org/page/userguide/device/cmd_monitor.html#cmd-device-monitor-filters>`__
|
||||||
* Added support for Arm Mbed "module.json" ``dependencies`` field (`issue #3400 <https://github.com/platformio/platformio-core/issues/3400>`_)
|
* Added support for Arm Mbed "module.json" ``dependencies`` field (`issue #3400 <https://github.com/platformio/platformio-core/issues/3400>`_)
|
||||||
* Improved support for Arduino "library.properties" ``depends`` field
|
* Improved support for Arduino "library.properties" ``depends`` field
|
||||||
* Fixed an issue when quitting from PlatformIO IDE does not shutdown PIO Home server
|
* Fixed an issue when quitting from PlatformIO IDE does not shutdown PIO Home server
|
||||||
|
2
docs
2
docs
Submodule docs updated: 1506c1bcbf...d6a2968edc
15
platformio/commands/device/__init__.py
Normal file
15
platformio/commands/device/__init__.py
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
# Copyright (c) 2014-present PlatformIO <contact@platformio.org>
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
from platformio.commands.device.filters.base import DeviceMonitorFilter
|
@@ -20,9 +20,9 @@ import click
|
|||||||
from serial.tools import miniterm
|
from serial.tools import miniterm
|
||||||
|
|
||||||
from platformio import exception, fs, util
|
from platformio import exception, fs, util
|
||||||
from platformio.compat import dump_json_to_unicode, load_python_module
|
from platformio.commands.device import helpers as device_helpers
|
||||||
|
from platformio.compat import dump_json_to_unicode
|
||||||
from platformio.managers.platform import PlatformFactory
|
from platformio.managers.platform import PlatformFactory
|
||||||
from platformio.project.config import ProjectConfig
|
|
||||||
from platformio.project.exception import NotPlatformIOProjectError
|
from platformio.project.exception import NotPlatformIOProjectError
|
||||||
|
|
||||||
|
|
||||||
@@ -135,7 +135,7 @@ def device_list( # pylint: disable=too-many-branches
|
|||||||
help="Set the encoding for the serial port (e.g. hexlify, "
|
help="Set the encoding for the serial port (e.g. hexlify, "
|
||||||
"Latin1, UTF-8), default: UTF-8",
|
"Latin1, UTF-8), default: UTF-8",
|
||||||
)
|
)
|
||||||
@click.option("--filter", "-f", multiple=True, help="Add text transformation")
|
@click.option("--filter", "-f", multiple=True, help="Add filters/text transformations")
|
||||||
@click.option(
|
@click.option(
|
||||||
"--eol",
|
"--eol",
|
||||||
default="CRLF",
|
default="CRLF",
|
||||||
@@ -174,15 +174,11 @@ def device_list( # pylint: disable=too-many-branches
|
|||||||
help="Load configuration from `platformio.ini` and specified environment",
|
help="Load configuration from `platformio.ini` and specified environment",
|
||||||
)
|
)
|
||||||
def device_monitor(**kwargs): # pylint: disable=too-many-branches
|
def device_monitor(**kwargs): # pylint: disable=too-many-branches
|
||||||
click.echo(
|
|
||||||
"Looking for advanced Serial Monitor with UI? "
|
|
||||||
"Check http://bit.ly/pio-advanced-monitor"
|
|
||||||
)
|
|
||||||
project_options = {}
|
project_options = {}
|
||||||
try:
|
try:
|
||||||
with fs.cd(kwargs["project_dir"]):
|
with fs.cd(kwargs["project_dir"]):
|
||||||
project_options = get_project_options(kwargs["environment"])
|
project_options = device_helpers.get_project_options(kwargs["environment"])
|
||||||
kwargs = apply_project_monitor_options(kwargs, project_options)
|
kwargs = device_helpers.apply_project_monitor_options(kwargs, project_options)
|
||||||
except NotPlatformIOProjectError:
|
except NotPlatformIOProjectError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -190,17 +186,17 @@ def device_monitor(**kwargs): # pylint: disable=too-many-branches
|
|||||||
if "platform" in project_options:
|
if "platform" in project_options:
|
||||||
with fs.cd(kwargs["project_dir"]):
|
with fs.cd(kwargs["project_dir"]):
|
||||||
platform = PlatformFactory.newPlatform(project_options["platform"])
|
platform = PlatformFactory.newPlatform(project_options["platform"])
|
||||||
register_platform_filters(platform, kwargs["project_dir"], kwargs["environment"])
|
device_helpers.register_platform_filters(
|
||||||
|
platform, kwargs["project_dir"], kwargs["environment"]
|
||||||
|
)
|
||||||
|
|
||||||
if not kwargs["port"]:
|
if not kwargs["port"]:
|
||||||
ports = util.get_serial_ports(filter_hwid=True)
|
ports = util.get_serial_ports(filter_hwid=True)
|
||||||
if len(ports) == 1:
|
if len(ports) == 1:
|
||||||
kwargs["port"] = ports[0]["port"]
|
kwargs["port"] = ports[0]["port"]
|
||||||
elif "platform" in project_options and "board" in project_options:
|
elif "platform" in project_options and "board" in project_options:
|
||||||
board_hwids = get_board_hwids(
|
board_hwids = device_helpers.get_board_hwids(
|
||||||
kwargs["project_dir"],
|
kwargs["project_dir"], platform, project_options["board"],
|
||||||
platform,
|
|
||||||
project_options["board"],
|
|
||||||
)
|
)
|
||||||
for item in ports:
|
for item in ports:
|
||||||
for hwid in board_hwids:
|
for hwid in board_hwids:
|
||||||
@@ -217,12 +213,18 @@ def device_monitor(**kwargs): # pylint: disable=too-many-branches
|
|||||||
break
|
break
|
||||||
|
|
||||||
# override system argv with patched options
|
# override system argv with patched options
|
||||||
sys.argv = ["monitor"] + options_to_argv(
|
sys.argv = ["monitor"] + device_helpers.options_to_argv(
|
||||||
kwargs,
|
kwargs,
|
||||||
project_options,
|
project_options,
|
||||||
ignore=("port", "baud", "rts", "dtr", "environment", "project_dir"),
|
ignore=("port", "baud", "rts", "dtr", "environment", "project_dir"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if not kwargs["quiet"]:
|
||||||
|
click.echo(
|
||||||
|
"Available filters and text transformations: %s"
|
||||||
|
% ", ".join(sorted(miniterm.TRANSFORMATIONS.keys()))
|
||||||
|
)
|
||||||
|
click.echo("More details at http://bit.ly/pio-monitor-filters")
|
||||||
try:
|
try:
|
||||||
miniterm.main(
|
miniterm.main(
|
||||||
default_port=kwargs["port"],
|
default_port=kwargs["port"],
|
||||||
@@ -232,98 +234,3 @@ def device_monitor(**kwargs): # pylint: disable=too-many-branches
|
|||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise exception.MinitermException(e)
|
raise exception.MinitermException(e)
|
||||||
|
|
||||||
def apply_project_monitor_options(cli_options, project_options):
|
|
||||||
for k in ("port", "speed", "rts", "dtr"):
|
|
||||||
k2 = "monitor_%s" % k
|
|
||||||
if k == "speed":
|
|
||||||
k = "baud"
|
|
||||||
if cli_options[k] is None and k2 in project_options:
|
|
||||||
cli_options[k] = project_options[k2]
|
|
||||||
if k != "port":
|
|
||||||
cli_options[k] = int(cli_options[k])
|
|
||||||
return cli_options
|
|
||||||
|
|
||||||
|
|
||||||
def options_to_argv(cli_options, project_options, ignore=None):
|
|
||||||
result = project_options.get("monitor_flags", [])
|
|
||||||
for k, v in cli_options.items():
|
|
||||||
if v is None or (ignore and k in ignore):
|
|
||||||
continue
|
|
||||||
k = "--" + k.replace("_", "-")
|
|
||||||
if k in project_options.get("monitor_flags", []):
|
|
||||||
continue
|
|
||||||
if isinstance(v, bool):
|
|
||||||
if v:
|
|
||||||
result.append(k)
|
|
||||||
elif isinstance(v, tuple):
|
|
||||||
for i in v:
|
|
||||||
result.extend([k, i])
|
|
||||||
else:
|
|
||||||
result.extend([k, str(v)])
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def get_project_options(environment=None):
|
|
||||||
config = ProjectConfig.get_instance()
|
|
||||||
config.validate(envs=[environment] if environment else None)
|
|
||||||
if not environment:
|
|
||||||
default_envs = config.default_envs()
|
|
||||||
if default_envs:
|
|
||||||
environment = default_envs[0]
|
|
||||||
else:
|
|
||||||
environment = config.envs()[0]
|
|
||||||
return config.items(env=environment, as_dict=True)
|
|
||||||
|
|
||||||
|
|
||||||
def get_board_hwids(project_dir, platform, board):
|
|
||||||
with fs.cd(project_dir):
|
|
||||||
return (
|
|
||||||
platform
|
|
||||||
.board_config(board)
|
|
||||||
.get("build.hwids", [])
|
|
||||||
)
|
|
||||||
|
|
||||||
class DeviceMonitorFilter(miniterm.Transform):
|
|
||||||
# NAME = "esp_exception_decoder" - all filters must have one
|
|
||||||
|
|
||||||
# Called by PlatformIO to pass context
|
|
||||||
def __init__(self, project_dir, environment):
|
|
||||||
super(DeviceMonitorFilter, self).__init__()
|
|
||||||
|
|
||||||
self.project_dir = project_dir
|
|
||||||
self.environment = environment
|
|
||||||
|
|
||||||
self.config = ProjectConfig.get_instance()
|
|
||||||
if not self.environment:
|
|
||||||
default_envs = self.config.default_envs()
|
|
||||||
if default_envs:
|
|
||||||
self.environment = default_envs[0]
|
|
||||||
else:
|
|
||||||
self.environment = self.config.envs()[0]
|
|
||||||
|
|
||||||
# Called by the miniterm library when the filter is acutally used
|
|
||||||
def __call__(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
def register_platform_filters(platform, project_dir, environment):
|
|
||||||
monitor_dir = os.path.join(platform.get_dir(), "monitor")
|
|
||||||
if not os.path.isdir(monitor_dir):
|
|
||||||
return
|
|
||||||
|
|
||||||
for fn in os.listdir(monitor_dir):
|
|
||||||
if not fn.startswith("filter_") or not fn.endswith(".py"):
|
|
||||||
continue
|
|
||||||
path = os.path.join(monitor_dir, fn)
|
|
||||||
if not os.path.isfile(path):
|
|
||||||
continue
|
|
||||||
|
|
||||||
dot = fn.find(".")
|
|
||||||
module = load_python_module("platformio.commands.device.%s" % fn[:dot], path)
|
|
||||||
for key in dir(module):
|
|
||||||
member = getattr(module, key)
|
|
||||||
try:
|
|
||||||
if issubclass(member, DeviceMonitorFilter) and hasattr(member, "NAME"):
|
|
||||||
miniterm.TRANSFORMATIONS[member.NAME] = member(project_dir, environment)
|
|
||||||
except TypeError:
|
|
||||||
pass
|
|
13
platformio/commands/device/filters/__init__.py
Normal file
13
platformio/commands/device/filters/__init__.py
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# Copyright (c) 2014-present PlatformIO <contact@platformio.org>
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
42
platformio/commands/device/filters/base.py
Normal file
42
platformio/commands/device/filters/base.py
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# Copyright (c) 2014-present PlatformIO <contact@platformio.org>
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
from serial.tools import miniterm
|
||||||
|
|
||||||
|
from platformio.project.config import ProjectConfig
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceMonitorFilter(miniterm.Transform):
|
||||||
|
def __init__(self, project_dir, environment):
|
||||||
|
""" Called by PlatformIO to pass context """
|
||||||
|
super(DeviceMonitorFilter, self).__init__()
|
||||||
|
|
||||||
|
self.project_dir = project_dir
|
||||||
|
self.environment = environment
|
||||||
|
|
||||||
|
self.config = ProjectConfig.get_instance()
|
||||||
|
if not self.environment:
|
||||||
|
default_envs = self.config.default_envs()
|
||||||
|
if default_envs:
|
||||||
|
self.environment = default_envs[0]
|
||||||
|
else:
|
||||||
|
self.environment = self.config.envs()[0]
|
||||||
|
|
||||||
|
def __call__(self):
|
||||||
|
""" Called by the miniterm library when the filter is actually used """
|
||||||
|
return self
|
||||||
|
|
||||||
|
@property
|
||||||
|
def NAME(self):
|
||||||
|
raise NotImplementedError("Please declare NAME attribute for the filter class")
|
102
platformio/commands/device/helpers.py
Normal file
102
platformio/commands/device/helpers.py
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
# Copyright (c) 2014-present PlatformIO <contact@platformio.org>
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import inspect
|
||||||
|
import os
|
||||||
|
|
||||||
|
from serial.tools import miniterm
|
||||||
|
|
||||||
|
from platformio import fs
|
||||||
|
from platformio.commands.device import DeviceMonitorFilter
|
||||||
|
from platformio.compat import get_object_members, load_python_module
|
||||||
|
from platformio.project.config import ProjectConfig
|
||||||
|
|
||||||
|
|
||||||
|
def apply_project_monitor_options(cli_options, project_options):
|
||||||
|
for k in ("port", "speed", "rts", "dtr"):
|
||||||
|
k2 = "monitor_%s" % k
|
||||||
|
if k == "speed":
|
||||||
|
k = "baud"
|
||||||
|
if cli_options[k] is None and k2 in project_options:
|
||||||
|
cli_options[k] = project_options[k2]
|
||||||
|
if k != "port":
|
||||||
|
cli_options[k] = int(cli_options[k])
|
||||||
|
return cli_options
|
||||||
|
|
||||||
|
|
||||||
|
def options_to_argv(cli_options, project_options, ignore=None):
|
||||||
|
confmon_flags = project_options.get("monitor_flags", [])
|
||||||
|
result = confmon_flags[::]
|
||||||
|
|
||||||
|
for f in project_options.get("monitor_filters", []):
|
||||||
|
result.extend(["--filter", f])
|
||||||
|
|
||||||
|
for k, v in cli_options.items():
|
||||||
|
if v is None or (ignore and k in ignore):
|
||||||
|
continue
|
||||||
|
k = "--" + k.replace("_", "-")
|
||||||
|
if k in confmon_flags:
|
||||||
|
continue
|
||||||
|
if isinstance(v, bool):
|
||||||
|
if v:
|
||||||
|
result.append(k)
|
||||||
|
elif isinstance(v, tuple):
|
||||||
|
for i in v:
|
||||||
|
result.extend([k, i])
|
||||||
|
else:
|
||||||
|
result.extend([k, str(v)])
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def get_project_options(environment=None):
|
||||||
|
config = ProjectConfig.get_instance()
|
||||||
|
config.validate(envs=[environment] if environment else None)
|
||||||
|
if not environment:
|
||||||
|
default_envs = config.default_envs()
|
||||||
|
if default_envs:
|
||||||
|
environment = default_envs[0]
|
||||||
|
else:
|
||||||
|
environment = config.envs()[0]
|
||||||
|
return config.items(env=environment, as_dict=True)
|
||||||
|
|
||||||
|
|
||||||
|
def get_board_hwids(project_dir, platform, board):
|
||||||
|
with fs.cd(project_dir):
|
||||||
|
return platform.board_config(board).get("build.hwids", [])
|
||||||
|
|
||||||
|
|
||||||
|
def register_platform_filters(platform, project_dir, environment):
|
||||||
|
monitor_dir = os.path.join(platform.get_dir(), "monitor")
|
||||||
|
if not os.path.isdir(monitor_dir):
|
||||||
|
return
|
||||||
|
|
||||||
|
for fn in os.listdir(monitor_dir):
|
||||||
|
if not fn.startswith("filter_") or not fn.endswith(".py"):
|
||||||
|
continue
|
||||||
|
path = os.path.join(monitor_dir, fn)
|
||||||
|
if not os.path.isfile(path):
|
||||||
|
continue
|
||||||
|
|
||||||
|
module = load_python_module(
|
||||||
|
"platformio.commands.device.filters.%s" % fn[: fn.find(".")], path
|
||||||
|
)
|
||||||
|
for cls in get_object_members(module).values():
|
||||||
|
if (
|
||||||
|
not inspect.isclass(cls)
|
||||||
|
or not issubclass(cls, DeviceMonitorFilter)
|
||||||
|
or cls == DeviceMonitorFilter
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
obj = cls(project_dir, environment)
|
||||||
|
miniterm.TRANSFORMATIONS[obj.NAME] = obj
|
@@ -21,7 +21,8 @@ from time import sleep
|
|||||||
import click
|
import click
|
||||||
|
|
||||||
from platformio import exception, fs
|
from platformio import exception, fs
|
||||||
from platformio.commands import device
|
from platformio.commands.device import helpers as device_helpers
|
||||||
|
from platformio.commands.device.command import device_monitor as cmd_device_monitor
|
||||||
from platformio.managers.core import pioplus_call
|
from platformio.managers.core import pioplus_call
|
||||||
from platformio.project.exception import NotPlatformIOProjectError
|
from platformio.project.exception import NotPlatformIOProjectError
|
||||||
|
|
||||||
@@ -197,8 +198,8 @@ def device_monitor(ctx, **kwargs):
|
|||||||
project_options = {}
|
project_options = {}
|
||||||
try:
|
try:
|
||||||
with fs.cd(kwargs["project_dir"]):
|
with fs.cd(kwargs["project_dir"]):
|
||||||
project_options = device.get_project_options(kwargs["environment"])
|
project_options = device_helpers.get_project_options(kwargs["environment"])
|
||||||
kwargs = device.apply_project_monitor_options(kwargs, project_options)
|
kwargs = device_helpers.apply_project_monitor_options(kwargs, project_options)
|
||||||
except NotPlatformIOProjectError:
|
except NotPlatformIOProjectError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -206,7 +207,7 @@ def device_monitor(ctx, **kwargs):
|
|||||||
|
|
||||||
def _tx_target(sock_dir):
|
def _tx_target(sock_dir):
|
||||||
pioplus_argv = ["remote", "device", "monitor"]
|
pioplus_argv = ["remote", "device", "monitor"]
|
||||||
pioplus_argv.extend(device.options_to_argv(kwargs, project_options))
|
pioplus_argv.extend(device_helpers.options_to_argv(kwargs, project_options))
|
||||||
pioplus_argv.extend(["--sock", sock_dir])
|
pioplus_argv.extend(["--sock", sock_dir])
|
||||||
try:
|
try:
|
||||||
pioplus_call(pioplus_argv)
|
pioplus_call(pioplus_argv)
|
||||||
@@ -224,7 +225,7 @@ def device_monitor(ctx, **kwargs):
|
|||||||
return
|
return
|
||||||
with open(sock_file) as fp:
|
with open(sock_file) as fp:
|
||||||
kwargs["port"] = fp.read()
|
kwargs["port"] = fp.read()
|
||||||
ctx.invoke(device.device_monitor, **kwargs)
|
ctx.invoke(cmd_device_monitor, **kwargs)
|
||||||
t.join(2)
|
t.join(2)
|
||||||
finally:
|
finally:
|
||||||
fs.rmtree(sock_dir)
|
fs.rmtree(sock_dir)
|
||||||
|
@@ -21,7 +21,7 @@ import click
|
|||||||
from tabulate import tabulate
|
from tabulate import tabulate
|
||||||
|
|
||||||
from platformio import app, exception, fs, util
|
from platformio import app, exception, fs, util
|
||||||
from platformio.commands.device import device_monitor as cmd_device_monitor
|
from platformio.commands.device.command import device_monitor as cmd_device_monitor
|
||||||
from platformio.commands.run.helpers import clean_build_dir, handle_legacy_libdeps
|
from platformio.commands.run.helpers import clean_build_dir, handle_legacy_libdeps
|
||||||
from platformio.commands.run.processor import EnvironmentProcessor
|
from platformio.commands.run.processor import EnvironmentProcessor
|
||||||
from platformio.commands.test.processor import CTX_META_TEST_IS_RUNNING
|
from platformio.commands.test.processor import CTX_META_TEST_IS_RUNNING
|
||||||
|
@@ -445,6 +445,14 @@ ProjectOptions = OrderedDict(
|
|||||||
oldnames=["monitor_baud"],
|
oldnames=["monitor_baud"],
|
||||||
default=9600,
|
default=9600,
|
||||||
),
|
),
|
||||||
|
ConfigEnvOption(
|
||||||
|
group="monitor",
|
||||||
|
name="monitor_filters",
|
||||||
|
description=(
|
||||||
|
"Apply the filters and text transformations to monitor output"
|
||||||
|
),
|
||||||
|
multiple=True,
|
||||||
|
),
|
||||||
ConfigEnvOption(
|
ConfigEnvOption(
|
||||||
group="monitor",
|
group="monitor",
|
||||||
name="monitor_rts",
|
name="monitor_rts",
|
||||||
|
Reference in New Issue
Block a user