-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue/configurable logging #8471
Conversation
@@ -85,7 +85,7 @@ def server_parser_config(parser: argparse.ArgumentParser, parent_parsers: abc.Se | |||
) | |||
|
|||
|
|||
@command("server", help_msg="Start the inmanta server", parser_config=server_parser_config) | |||
@command("server", help_msg="Start the inmanta server", parser_config=server_parser_config, component="server") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding the component here to load correct config
def default_logging_config(options: argparse.Namespace) -> None: | ||
config_builder = LoggingConfigBuilder() | ||
|
||
# Al possible context vars: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handling of templates-in-templates below, somewhat nasty, but it works
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to have a docstring that explain how the templating works conceptually. Now you have to derive all that information from the code itself.
log_context = {} | ||
env = None | ||
if hasattr(options, "environment"): | ||
env = options.environment | ||
if not env: | ||
env = agent_config.environment.get() | ||
if env: | ||
log_context[LOG_CONTEXT_VAR_ENVIRONMENT] = env |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have so little config I just hardcoded it here
"--log-file", | ||
agent_log, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is now part of the log config! (I'm a bit in doubt, but it simplifies things)
src/inmanta/app.py
Outdated
) | ||
|
||
|
||
@command("default_logging_config", help_msg="Print the default log config", parser_config=default_log_config_parser) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think generate_default_loging_config
or some other prefix like print_
, export_
or print_
would convey better what this does.
I would also extend the help message with: Print the default log config for the provided component
I think this is very much a must have, given that we have some very specific custom loggers. I am in favor of hard coding it. I guess this config is not going to change often, is it?
I think we already enforce some rules for formatters and handlers, defined by an extension, to prevent naming conflicts. I am not sure whether this is any useful for the loggers as well, because this is visible to the end-user. Our current convention is using the module names. I guess that's sufficiently unique.
I think we will have to if we want to offer a decent user experience.
I think those methods are mainly used by the solutions team in many of their tooling. So the question is mainly whether they are ready for this. To be honest I am not even sure whether they are aware about the deprecation of these methods. |
I think there has been discussion some time ago. iirc this is mostly used in the logger that is attached to requests in restbase. We can ask Guillaume, he probably knows from the top of his head. |
src/inmanta/logging.py
Outdated
@@ -84,6 +86,20 @@ def python_log_level_to_name(python_log_level: int) -> str: | |||
logging.addLevelName(3, "TRACE") | |||
|
|||
|
|||
class LogConfigDumper(Dumper): | |||
"""Ensure class variables are not shared, as representer config lives on the class""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand this docstring.
src/inmanta/logging.py
Outdated
if component == "scheduler": | ||
# Override defaults | ||
if LOG_CONTEXT_VAR_ENVIRONMENT not in context: | ||
raise Exception("The scheduler expect an environment as context") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
raise Exception("The scheduler expect an environment as context") | |
raise Exception("The scheduler expects an environment as context") |
I'm not sure about exposing the name |
Questions
|
Questions
|
Questions
|
Questions
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approving PR description
@sanderr I see you point, but I'm a bit torn. The main audience here is sysadmins. They will be interested in process listing, config files, log files,... So they don't have the direct developer view. For them, the distinction agent/scheduler/executor is very relevant. I think we made step a forward from agent/agent(process)/agent(instance) in that they are now more distinct concepts. But it would be nice if they wouldn't have to know. But I'm afraid they do have to know. (We can only afford them not to know if these things never fail, but I think venv's will keep acting up) |
Ok, I think that's a valid point. I don't know the user perspective sufficiently well to provide further input. I mainly wanted to expose this fact, but I'm totally fine leaving it as is if you think it would be best in the grand scheme of things. |
@@ -1340,10 +1339,6 @@ async def test_send_deploy_done(server, client, environment, agent, caplog, meth | |||
) | |||
assert result.code == 200, result.result | |||
|
|||
# Assert effect of send_deploy_done call |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not immediately clear at the moment why this is no longer logged
return config.logging_config.get() | ||
|
||
@stable_api | ||
def apply_options(self, options: Options) -> None: | ||
def apply_options(self, options: Options, component: str | None = None, context: Mapping[str, str] = {}) -> None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing param docstring from stable_api method
@@ -550,6 +523,7 @@ def __init__(self, stream: TextIO = sys.stdout) -> None: | |||
self._handlers: abc.Sequence[logging.Handler] = self._apply_logging_config(log_config) | |||
self._options_applied: bool = False | |||
self._logging_configs_extensions: list[LoggingConfigExtension] = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is no longer used afaics. I don't remember what we discussed about the logging config for lsm, maybe it is still relevant to keep this around then.
self._logging_configs_extensions: list[LoggingConfigExtension] = [] |
@@ -761,7 +766,6 @@ def __init__( | |||
super().__init__(fmt, log_colors=log_colors, reset=reset, no_color=no_color) | |||
self.fmt = fmt | |||
self._keep_logger_names = keep_logger_names | |||
self._logger_mode_manager = LoggerModeManager.get_instance() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_wrap_record
docstring should be updated: _logger_mode
no longer exists
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we already have tests to assert that -v
Co-authored-by: Hugo-Inmanta <[email protected]>
Co-authored-by: João Trindade <[email protected]>
Co-authored-by: João Trindade <[email protected]>
…ta-core into issue/configurable_logging
|
||
# Load config | ||
inmanta.config.Config.load_config_from_dict(config) | ||
|
||
# Make sure logfire is configured correctly | ||
tracing.configure_logfire("agent.executor") | ||
tracing.configure_logfire("inmanta.executor") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tracing.configure_logfire("inmanta.executor") | |
tracing.configure_logfire(LOGGER_NAME_EXECUTOR) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not about the logger name here (even if I'm not sure what it is)
@@ -805,8 +811,6 @@ def format(self, record: logging.LogRecord) -> str: | |||
def _wrap_record(self, record: logging.LogRecord) -> logging.LogRecord: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could even lift the logic from _get_logger_name_for
:
if not self._keep_logger_names:
....
In here and then call into _get_logger_name_for
only when required
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thx!
Co-authored-by: Hugo-Inmanta <[email protected]>
Co-authored-by: Hugo-Inmanta <[email protected]>
Processing this pull request |
Merged into branches master in 00301d7 |
# Description Add configurable logging. closes #8306 closes #8307 closes #8356 ## includes 1. per-component log files via the config file ```ini [logging] server = server_log.yml scheduler = scheduler.log.tmpl ``` 2. tool to dump log file ` inmanta print_default_logging_config [compiler|scheduler|server]` 3. moved resource action log to scheduler ## Questions and results 1. [x] do we want comments in the files outputted by the tool? - comments are in the files in misc, not in the tool output 3. [x] do we want to enforce a naming convention on the logger. (it is in the code, but I wouldn't, as we don't have a lot of feeling with this ) - no: we don't know logging well enogu 5. [x] should `-v` work when using the config file? - force in a cli logger at this level ## Next steps 1. [ ] remove all resource action alike functions from the server 2. [ ] add a way to validate config files for specific tools (like scheduler) -> #8482 6. [ ] Some methods in the stable api of the logging are deprecated, do we drop them? -> #8485 7. [ ] Hook on LSM #8492 8. [ ] TTY forcing? -> #8484 9. [ ] load config from env var -> #8308 10. [ ] document logging config -> #8493 # Self Check: Strike through any lines that are not applicable (`~~line~~`) then check the box - [x] Attached issue to pull request - [x] Changelog entry - [x] Type annotations are present - [x] Code is clear and sufficiently documented - [x] No (preventable) type errors (check using make mypy or make mypy-diff) - [x] Sufficient test cases (reproduces the bug/tests the requested feature) - [x] Correct, in line with design - [ ] End user documentation is included or an issue is created for end-user documentation (add ref to issue here: ) -> #8493 - [ ] If this PR fixes a race condition in the test suite, also push the fix to the relevant stable branche(s) (see [test-fixes](https://internal.inmanta.com/development/core/tasks/build-master.html#test-fixes) for more info)
Description
Add configurable logging.
closes #8306
closes #8307
closes #8356
includes
inmanta print_default_logging_config [compiler|scheduler|server]
Questions and results
- comments are in the files in misc, not in the tool output
- no: we don't know logging well enogu
-v
work when using the config file?- force in a cli logger at this level
Next steps
Self Check:
Strike through any lines that are not applicable (
~~line~~
) then check the box