Skip to content

Commit 31a11f2

Browse files
committed
feat(cli): add new command line switch --log-config to specify a python json log configuration
1 parent 5031a36 commit 31a11f2

File tree

5 files changed

+81
-12
lines changed

5 files changed

+81
-12
lines changed

packages/core/src/robotcode/core/utils/logging.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -203,10 +203,9 @@ def log(
203203
if context_name is not None:
204204
depth = self._measure_contexts.get(context_name, 0)
205205

206-
if depth > 0:
207-
extra = {**extra} if extra is not None else {}
208-
if "indent" not in extra:
209-
extra["indent"] = " " * depth
206+
extra = {**extra} if extra is not None else {}
207+
if "indent" not in extra:
208+
extra["indent"] = (" " * depth) if depth > 0 else ""
210209

211210
self.logger.log(
212211
level,

packages/debugger/src/robotcode/debugger/server.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,15 +196,15 @@ async def _terminate(
196196
Debugger.instance().terminate()
197197

198198
if not restart and not self._sigint_signaled:
199-
self._logger.info("Send SIGINT to process")
199+
self._logger.debug("Send SIGINT to process")
200200
signal.raise_signal(signal.SIGINT)
201201
self._sigint_signaled = True
202202

203203
Debugger.instance().continue_all_if_paused()
204204
else:
205205
await self.send_event_async(Event("terminateRequested"))
206206

207-
self._logger.info("Send SIGTERM to process")
207+
self._logger.debug("Send SIGTERM to process")
208208
signal.raise_signal(signal.SIGTERM)
209209

210210
@rpc_method(name="disconnect", param_type=DisconnectArguments)

src/robotcode/cli/__init__.py

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import json
12
import logging
3+
import logging.config
24
from pathlib import Path
35
from typing import Any, List, Literal, Optional
46

@@ -35,8 +37,11 @@ def my_make_metavar(self: click.Parameter, *args: Any, **kwargs: Any) -> str:
3537

3638

3739
class RobotCodeFormatter(logging.Formatter):
38-
def __init__(self, *args: Any, **kwargs: Any) -> None:
39-
super().__init__(*args, **kwargs)
40+
def __init__(self, *args: Any, defaults: Any = None, **kwargs: Any) -> None:
41+
defaults = defaults or {}
42+
if defaults.get("indent") is None:
43+
defaults["indent"] = ""
44+
super().__init__(*args, defaults=defaults, **kwargs)
4045

4146

4247
@click.group(
@@ -162,6 +167,21 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:
162167
help="Enables logging of method/function calls.",
163168
show_envvar=True,
164169
)
170+
@click.option(
171+
"--log-config",
172+
type=click.Path(
173+
file_okay=True,
174+
dir_okay=False,
175+
readable=True,
176+
exists=True,
177+
path_type=str,
178+
),
179+
help="Path to a logging configuration file. This must be a valid Python logging configuration file in JSON format."
180+
" If this option is set, the other logging options are ignored.",
181+
default=None,
182+
show_default=True,
183+
show_envvar=True,
184+
)
165185
@click.option(
166186
"--default-path",
167187
"-dp",
@@ -220,6 +240,7 @@ def robotcode(
220240
log_style: Literal["%", "{", "$"],
221241
log_filename: Optional[str],
222242
log_calls: bool,
243+
log_config: Optional[Path],
223244
default_path: Optional[List[str]],
224245
launcher_script: Optional[str] = None,
225246
debugpy: bool = False,
@@ -257,7 +278,21 @@ def robotcode(
257278
app.config.log_level = log_level
258279
app.config.log_calls = log_calls
259280

260-
if log:
281+
if log_config:
282+
if log_calls:
283+
LoggingDescriptor.set_call_tracing(True)
284+
285+
app.verbose(f"Loading logging configuration from '{log_config}'")
286+
try:
287+
with open(log_config, "r", encoding="utf-8") as f:
288+
config = json.load(f)
289+
290+
logging.config.dictConfig(config)
291+
292+
except Exception as e:
293+
app.error(f"Failed to load logging configuration from '{log_config}': {e}")
294+
295+
elif log:
261296
if log_calls:
262297
LoggingDescriptor.set_call_tracing(True)
263298

@@ -269,9 +304,7 @@ def robotcode(
269304
)
270305

271306
try:
272-
logging.root.handlers[0].formatter = RobotCodeFormatter(
273-
fmt=log_format, style=log_style, defaults={"indent": ""}
274-
)
307+
logging.root.handlers[0].formatter = RobotCodeFormatter(fmt=log_format, style=log_style)
275308
except TypeError:
276309
pass
277310

tests/robotcode/language_server/robotframework/parts/data/.vscode/settings.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
"--log",
2020
"--log-level", "DEBUG",
2121
// "--log-format", "%(indent)s%(levelname)s:%(name)s:%(filename)s:%(lineno)d: %(message)s"
22+
23+
// "--log-config", "logging.json"
2224
],
2325
// "robotcode.robocop.configFile": "pyproject.toml",
2426
"robotcode.robocop.enabled": true,
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"version": 1,
3+
"disable_existing_loggers": true,
4+
"formatters": {
5+
"standard": {
6+
"class": "robotcode.cli.RobotCodeFormatter",
7+
"format": "%(indent)s %(asctime)s %(name)s %(levelname)s: %(message)s"
8+
}
9+
},
10+
"handlers": {
11+
"console": {
12+
"level": "DEBUG",
13+
"class": "logging.StreamHandler",
14+
"formatter": "standard"
15+
},
16+
"file_handler": {
17+
"level": "DEBUG",
18+
"class": "logging.handlers.RotatingFileHandler",
19+
"formatter": "standard",
20+
"filename": "info.log",
21+
"mode": "w",
22+
"maxBytes": 26214400,
23+
"backupCount": 10,
24+
"encoding": "utf8"
25+
}
26+
},
27+
28+
"root": {
29+
"level": "DEBUG",
30+
"handlers": [
31+
"console",
32+
"file_handler"
33+
]
34+
}
35+
}

0 commit comments

Comments
 (0)