plesty.server.services.problem_report ===================================== .. py:module:: plesty.server.services.problem_report .. autoapi-nested-parse:: What a bench says about itself when something goes wrong. A report an operator can read before they send it: what this bench is, what it holds, what it was doing, and the tail of the logs that would otherwise have to be asked for one at a time. The point is to make the first question a maintainer asks — *what were you running, and on what?* — already answered. Nothing here contacts the tracker. The bench holds no credential that could write to it, and giving it one so it could file issues would be a token on every lab machine for the sake of a convenience. The report is text: the console copies it, saves it, or opens the tracker's own new-issue page with it filled in, and the operator presses submit as themselves. **The payload is filtered, not trusted.** A device's environment is where a deployment keeps its addresses and sometimes its credentials, and a log is whatever a module chose to print. So the environment is reported by key and never by value, and every line of captured text goes through :func:`redact`. Attributes ---------- .. autoapisummary:: plesty.server.services.problem_report.LOG_LINES plesty.server.services.problem_report.PACKAGES plesty.server.services.problem_report.HIDDEN Functions --------- .. autoapisummary:: plesty.server.services.problem_report.redact plesty.server.services.problem_report.report plesty.server.services.problem_report.new_issue_url Module Contents --------------- .. py:data:: LOG_LINES :value: 80 .. py:data:: PACKAGES :value: ('plesty-server', 'plesty-bench', 'plesty-lib', 'plesty-sdk') .. py:data:: HIDDEN :value: '' .. py:function:: redact(text: str) -> str Return *text* with anything that looks like a credential taken out. Applied to everything captured, including the operator's own description: a person pasting the command that failed pastes its arguments with it. :param text: The text to filter. :returns: The text with secrets replaced by :data:`HIDDEN`. Everything else is untouched — a report with the interesting line removed is a report that gets sent twice. .. py:function:: report(bench: Any, description: str = '', logs: int = LOG_LINES) -> str Build the report for this bench, as Markdown. :param bench: The bench to describe. :param description: What the operator says happened; written at the top, where a reader looks first. :param logs: Lines of each log to carry. :returns: The report. Every part of it is redacted, including the description. .. py:function:: new_issue_url(project_url: str, title: str, body: str, limit: int = 4000) -> str The tracker's own new-issue page, filled in as far as a URL can carry. The bench files nothing itself: this opens the page as the operator, in their browser, signed in as themselves. A long report does not fit in a query string — browsers and servers both cut them — so the body is only carried when it fits, and the console puts the whole of it on the clipboard either way. :param project_url: The project's web URL. :param title: The issue title. :param body: The report. :param limit: How much body a URL may carry. :returns: The URL to open.