Skip to content

Add docs and deploy#59

Open
emmuhamm wants to merge 44 commits intodevelopfrom
emmuhamm/deploy-docs
Open

Add docs and deploy#59
emmuhamm wants to merge 44 commits intodevelopfrom
emmuhamm/deploy-docs

Conversation

@emmuhamm
Copy link
Copy Markdown
Collaborator

@emmuhamm emmuhamm commented Mar 11, 2026

Description

vibes Screenshot 2026-02-12 at 13 46 38

Fix #52
Fix #43

Add docs and deploy them. Its a lot.

There are two kinds of docs that exist, one for the user and one for the developer. The user docs are found in docs/ and the dev docs are in docs_dev/. The split is so that the user docs are used to make the dune daq readthedocs website, while the dev docs are primarily found in the mkdocs (similar to how it is in drunc).

Speaking of mkdocs, they should be found here: https://dune-daq.github.io/daqpytools/

It contains both the user and developer docs just so we have everything in one consistent place.

The docs themselves follow the diataxis framework, such that each page should be only one of the four: tutorial, guide, reference, explanation. That should make the reading and understanding of the docs much clearer. \

The api references are automatically generated, this is done using the dev_docs/generate_logging_autodocs.py script.

The other script in that file just cleans up the file structure in the two docs so they are clearly displayed in the mkdocs.

For this one feature to work, we have an empty folder called docs_anchor, which is eventually used to build the autodocs so that we have the user and dev docs in the same heirarchy.

Type of change

  • Documentation (non-breaking change that adds or improves the documentation)

TODO

  • Fix ordering of pages
  • Go through the docs again with a fine tooth comb to see if i've missed anything
  • Add a thing about severity levels in the context of dune? this is a WIP tho
  • Make sure its explicitly clear that you need to have the log_level set in get_daq_logger if you are initialising this

Testing checklist

View https://dune-daq.github.io/daqpytools/ and read through everything :')

  • Unit tests pass (e.g. dbt-build --unittest)
  • Minimal system quicktest passes (pytest -s minimal_system_quick_test.py)
  • Full set of integration tests pass (daqsystemtest_integtest_bundle.sh)
  • Python tests pass if applicable (e.g. python -m pytest)
  • Pre-commit hooks run successfully if applicable (e.g. pre-commit run --all-files)

Comments here on the testing

Further checks

  • Code is commented where needed, particularly in hard-to-understand areas
  • Code style is correct (dbt-build --lint, and/or see https://dune-daq-sw.readthedocs.io/en/latest/packages/styleguide/)
  • If applicable, new tests have been added or an issue has been opened to tackle that in the future.
    (Indicate issue here: # (issue))

@emmuhamm emmuhamm self-assigned this Mar 11, 2026
@emmuhamm emmuhamm linked an issue Mar 11, 2026 that may be closed by this pull request
@emmuhamm emmuhamm changed the title Deploy docs Deploy docs out to pages Mar 12, 2026
@emmuhamm emmuhamm force-pushed the emmuhamm/deploy-docs branch from 0bba273 to c60efe9 Compare March 12, 2026 11:17
@emmuhamm emmuhamm mentioned this pull request Mar 18, 2026
10 tasks
@emmuhamm emmuhamm force-pushed the emmuhamm/deploy-docs branch from e6a71ee to 0dbf745 Compare March 19, 2026 11:38
@emmuhamm emmuhamm changed the title Deploy docs out to pages Add docs and deploy Mar 19, 2026
@emmuhamm emmuhamm force-pushed the emmuhamm/deploy-docs branch from 959d438 to 8586192 Compare March 20, 2026 15:06
@emmuhamm emmuhamm added the documentation Improvements or additions to documentation label Mar 20, 2026
@emmuhamm emmuhamm marked this pull request as ready for review March 20, 2026 16:11
@emmuhamm
Copy link
Copy Markdown
Collaborator Author

Hi @PawelPlesniak @henry-wallace-phys, this monster of a PR is ready for review. Might be easier to review if you just read the docs to be honest, which is found here: https://dune-daq.github.io/daqpytools/

@henry-wallace-phys since youre not too familiar with the logging framework, can you give comments on how clear and easy to follow the docs are? hopefully the tutorial and the how tos and the best practices should help you get up and running with your runconfui refactor :)

@PawelPlesniak since youre an expert, can you flick through everything? (sorry..) Let me know if im missing something svp

@PawelPlesniak
Copy link
Copy Markdown
Collaborator

Thank you for this Emir. It will take a bit to read, so I will leave running commentary separated by time at which I cannot follow the length of the comment.

On the splash page

image Rewrite "(as of 5.6.0)" to "(as of fddaq-v5.6.0, daqpytools vX.Y.Z)"

In the tutorial Step 1

For now, please see the docstring of get_daq_logger to see what stuff you can have and what to initialise with.

Could do with a hyperlink

Tutorial Step 2

Step 2: Emit your first messages

Is worth defining what "emit" means.

Tutorial next steps

To learn how to use specific handlers and filters, see the How-to guides.

Link broken. Would highly recommend using lychee, as per the drunc example. This autochecks whether tha pages are safe.

For a full API reference, see the API Ref.

APIref -> API reference guide (both this link and the bookmark)

Concepts - how logging works in DUNE DAQ

https://dune-daq.github.io/daqpytools/user/explanation/

image

Here it's worth stating that the log level is just an enum, with CRITICAL being 50, with incrememnts of 10 down to 0 for NOTSET.

More levels can be defined as required, see Python's logging manual.

Link this

Filters section

Worth also saying that each handler and logger have their own levels

Inheritance section

Slightly misleading - the log records are passed to the parents all the way up until they hit root. The diagram you link below your diagram shows this.

Streams

Include a link to the next section here (How to use handlers and filters)

How to use handlers and filterrs

The stderr stream emits only for records at ERROR or above.

Is this generally true or have we configured it to work this way?

In the code example

import time

from daqpytools.logging import HandlerType, get_daq_logger

main_logger: logging.Logger = get_daq_logger(
    logger_name="daqpytools_logging_demonstrator",
    stream_handlers=True,
    throttle=True
)

emit_err = lambda i: main_logger.info(
    f"Throttle test {i}",
    extra={"handlers": [HandlerType.Rich, HandlerType.Throttle]},
)

for i in range(50):
    emit_err(i)
main_logger.warning("Sleeping for 30 seconds")
time.sleep(30)
for i in range(1000):
    emit_err(i)

Slight pedantic request - your variable name is emit_err, can you make this emit_log_record instead? These are not error messages.

How to route messages to specific handlers

It handles ERS environment variable parsing and creates routing metadata bundles that you attach to records via extra.

Can you make this "It can handle ERS environment variables..." instead? This makes it seem that it will always parse the ERS env vars, even if the protobufstream handler is not requested.

How to add handlers at runtime

You can configure handlers in two phases:

Could you rephrase this as "Handlers can be configured in two ways", give an example with get_daq_logger with all the relevant handlers already selected, and a separate instance of how to add at runtime? As I was typing that I relaised this is why you called this section "at runtime", but for completion, I would suggest restructuring this page to be called "How to add handlers". with separate subsections for "at construction" and a separate one for "at runtime"

Suppress by default with fallback_handler={HandlerType.Unknown}

This secttion makes sense as I read several of your talks, but for a user who didn't it would be better to state this section as "default behaviour with extras", and define what the fallback_handlers are and what they do. This kind of does it in reverse, making it hard to follow. How to use the extras would be helpful here too, and how you can use the wrapper around the extras. Pointing to the dev docs will be helpful here.

How to configure ERS handlers

For background on ERS streams and routing, see Concepts. For the LogHandlerConf routing API, see Routing messages to specific handlers.

Here also link the definition of the ERS kafka handler

Configuring ERS handlers on an existing logger

Here also explain how to initialize it straight away (i.e. on logger construction)

Logging best practices

Always set up a named pseudo-root logger

You should explain what logging does by default for the true root logger (maybe in concepts?) before saying what the pseudo-root logger does.

As the root logger is the highest logger which every logger inherits from, modifying this logger will have a global effect on all your loggers, which is almost always undesirable.

This should be modified to say (in bold and maybe caps depending on your personal choice) that it will affect thee logger instances from other repositories too, and that it can lead to undesirable code (e.g. this)

A good place to define parent-level loggers with handlers (c.f drunc.process_manager)

Missing a dot after the f.

Use get_daq_logger to initialise it once.

Preface this with "once the pseudo-root logger is defined". You could also point to the function we have in drunc which prepends the "drunc" prefix to actually inherit from the pseudo-root loggers, to make sure that the inheritance is followed.

Concepts: How the logging system works internally

HandlerSpec describes how to build a handler: - alias: The HandlerType key - handler_class: The runtime handler class (used to detect existing instances) - factory: A callable that builds the handler from configuration - fallback_types: Which HandlerType values this handler represents for routing purposes - target_stream: Optional (for stream-specific handlers like stdout vs stderr)

Is this formatting correct? Similarly for tthe following bullet point list.

I will finish the dev docs tomorrow, they need dedicated effort

General comments

This is a very nice set of complete documentation, with clear descriptions and demonstrations. Nice work!

Some requests:

  • The order of the docs in the column on the left does not correspond to the order in which your splash page lists things. I like the splash page order, can we make the logs reflect this?
image
  • There will be more requests from the dev side of things tomorrow, for now it is late

@PawelPlesniak
Copy link
Copy Markdown
Collaborator

Continued

Concepts: How the logging system works internally

Nice UML diagrams

In HandleIDFilter, I am a bit unclear on how the *AllowedHandlerStrategy is structured - is this separate for ERS because ERS has level-specific handlers?

The "How it works:" section in HandleIDFilter here is good, but I think it is incomplete. It would be clearer if at the end you give some examples and talk through the logic on when handlers are filtered based on the filters, similarly to what you did in your slides. This should be done for all the basic permutations, i.e. default handlers with fallback_handlers, when specifying extras, when using the LogHandlerConf. It may seem excessive, but the structure is inherently complex, and this will allow the developer to use your framework without consulting you all the time. Reading on I saw this is understandable after section Fallback Handlers, but a separate page would make this clearer.

In Routing strategies, the "Implementation" numbered list is not formatted correctly.
image

In Fallback Handlers, you've defined what happens when you add a handler and explicitly state what the fallback_handler types are. Few questions

  • Clarification - if a handler is added using get_daq_logger, and then the logger instance is used to emit, the fallback handler is used and it has already been set to use the allocated handler, right?
  • Curiosity - if a handler is added with a fallback handler allocated to a handler that hasn't been instantiated with the logger or any of its parents, what happens?
  • How do fallback handlers fit into the picture of inheritance?

Architecture reference: initialization and record flow

Incorrect formatting?
image

Record flow
Number 3 and 4 should be combined - they are the same logic. 11 and 12 seem to be similar too. This flow is good, but it could be improved with a logical output for each step, or reference to the diagram you draw below.
image
This is very useful information, and I think the user reader should be pointed to it somewhere in the user docs,. maybe at the end of concepts?

The diagram encapsulates what happens with your framework very well.

How to debug routing issues

Very nice. I reckon this will be visited quite frequently

Common handler and filter patterns

Not sure the Next steps section should be here

Summary

Very nice set of documentation. It shows clear examples of how the infrastructure works. The suggested changes are mainly to make readability as easy as possible. A couple more examples have been suggested to give more explicit examples on how to use the framework, especially with the filtering (which is the part with the most custom code). Nicely done! Once the suggested changes are implemented I will re-review and we can merge

@PawelPlesniak
Copy link
Copy Markdown
Collaborator

I will also quickly flick through the code and the docstrings, but after lunch

@PawelPlesniak
Copy link
Copy Markdown
Collaborator

It may also be worth nuking my old wiki

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Doc]: Raw documentation for user and developer [Doc]: First pass at providing documentation

3 participants