Skip to content
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

Closed
wants to merge 37 commits into from
Closed

Conversation

wouterdb
Copy link
Contributor

@wouterdb wouterdb commented Dec 12, 2024

Description

Add configurable logging.

closes #8306
closes #8307

closes #8356

includes

  1. per-component log files via the config file
[logging]
server = server_log.yml
scheduler = scheduler.log.tmpl
  1. tool to dump log file inmanta print_default_logging_config [compiler|scheduler|server]
  2. moved resource action log to scheduler

Questions and results

  1. do we want comments in the files outputted by the tool?
    - comments are in the files in misc, not in the tool output
  2. 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
  3. 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) -> Logging: add a way to validate config files for specific tools (like scheduler) #8482
  3. Some methods in the stable api of the logging are deprecated, do we drop them? -> logging: Some methods in the stable api of the logging are deprecated #8485
  4. Hook on LSM Design way for extensions to contribute log config #8492
  5. TTY forcing? -> logging Force TTY to be abled when generating default config #8484
  6. load config from env var -> Add support to provide logging config via environment variables #8308
  7. document logging config -> Dcoument configurable logging  #8493

Self Check:

Strike through any lines that are not applicable (~~line~~) then check the box

  • Attached issue to pull request
  • Changelog entry
  • Type annotations are present
  • Code is clear and sufficiently documented
  • No (preventable) type errors (check using make mypy or make mypy-diff)
  • Sufficient test cases (reproduces the bug/tests the requested feature)
  • Correct, in line with design
  • End user documentation is included or an issue is created for end-user documentation (add ref to issue here: ) -> Dcoument configurable logging  #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 for more info)

@@ -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")
Copy link
Contributor Author

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:
Copy link
Contributor Author

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

Copy link
Contributor

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.

Comment on lines +947 to +954
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
Copy link
Contributor Author

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

Comment on lines -1246 to -1247
"--log-file",
agent_log,
Copy link
Contributor Author

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)

)


@command("default_logging_config", help_msg="Print the default log config", parser_config=default_log_config_parser)
Copy link
Contributor

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

@arnaudsjs
Copy link
Contributor

arnaudsjs commented Dec 13, 2024

  1. do we want comments in the files outputted by the tool? (this probably means either hardcode them as string with comments or some ruamel) . We could also provide documented versions in the docs

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?

  1. 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 )

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.

  1. should -v work when using the config file?

I think we will have to if we want to offer a decent user experience.

  1. Some methods in the stable api of the logging are deprecated, do we drop them?

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.

@bartv
Copy link
Contributor

bartv commented Dec 13, 2024

  1. Some methods in the stable api of the logging are deprecated, do we drop them?

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.

@@ -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"""
Copy link
Contributor

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.

if component == "scheduler":
# Override defaults
if LOG_CONTEXT_VAR_ENVIRONMENT not in context:
raise Exception("The scheduler expect an environment as context")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
raise Exception("The scheduler expect an environment as context")
raise Exception("The scheduler expects an environment as context")

@sanderr
Copy link
Contributor

sanderr commented Dec 13, 2024

I'm not sure about exposing the name scheduler to the end user, as mentioned before in the office. I think deploy or agent might be more intuitive. But I'm also not too heavily opposed to it, and I recognize that I'm bad at estimating what's intuitive when it comes to these types of things.

@sanderr
Copy link
Contributor

sanderr commented Dec 13, 2024

Questions

  1. I also think comments would be good.

@sanderr
Copy link
Contributor

sanderr commented Dec 13, 2024

Questions

  1. No opinion, I can get behind what Arnaud responded.

@sanderr
Copy link
Contributor

sanderr commented Dec 13, 2024

Questions

  1. As discussed in the office. I'm torn: either don't allow it, or have it set the root logger's level. Preference for the latter, but tough to make the call.

@sanderr
Copy link
Contributor

sanderr commented Dec 13, 2024

Questions

  1. Sounds good

Copy link
Contributor

@sanderr sanderr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving PR description

@wouterdb
Copy link
Contributor Author

I'm not sure about exposing the name scheduler to the end user, as mentioned before in the office. I think deploy or agent might be more intuitive. But I'm also not too heavily opposed to it, and I recognize that I'm bad at estimating what's intuitive when it comes to these types of things.

@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)

@sanderr
Copy link
Contributor

sanderr commented Dec 16, 2024

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
Copy link
Contributor

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:
Copy link
Contributor

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] = []
Copy link
Contributor

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.

Suggested change
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()
Copy link
Contributor

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

Copy link
Contributor

@jptrindade jptrindade left a 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


# 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")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
tracing.configure_logfire("inmanta.executor")
tracing.configure_logfire(LOGGER_NAME_EXECUTOR)

Copy link
Contributor Author

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:
Copy link
Contributor

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thx!

@wouterdb wouterdb added the merge-tool-ready This ticket is ready to be merged in label Dec 19, 2024
@inmantaci
Copy link
Contributor

Processing this pull request

@inmantaci
Copy link
Contributor

Merged into branches master in 00301d7

inmantaci pushed a commit that referenced this pull request Dec 19, 2024
# 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)
@inmantaci inmantaci closed this Dec 19, 2024
@inmantaci inmantaci deleted the issue/configurable_logging branch December 19, 2024 10:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merge-tool-ready This ticket is ready to be merged in
Projects
None yet
7 participants