Вернул просмотр логов в сингл режим

This commit is contained in:
2026-08-31 12:17:43 +03:00
parent d2f5a22501
commit d1dd9e3d14
14 changed files with 580 additions and 47 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "plba"
version = "0.5.0"
version = "0.5.1"
description = "Platform runtime for business applications"
readme = "README.md"
requires-python = ">=3.11"
+1 -1
View File
@@ -105,6 +105,6 @@ class TraceLogReader(Protocol):
levels: tuple[TraceLevel, ...],
ancestor_depth: int | None = 0,
*,
view: Literal["tree", "single"] = "tree",
view: Literal["tree", "single"] = "single",
) -> TraceLogView | None:
"""Load trace context and filtered log records."""
+1 -1
View File
@@ -29,7 +29,7 @@ class TraceQueryRequest:
include_attrs_json: bool = False
response_format: TraceResponseFormat = "html"
ancestor_depth: int | None = None
view: TraceViewMode = "tree"
view: TraceViewMode = "single"
TraceLookupHandler = Callable[[str, TraceQueryRequest], Awaitable[TraceLogView]]
+1 -1
View File
@@ -21,7 +21,7 @@ class TraceRequestParser:
response_format = raw_format.strip().lower()
if response_format not in {"json", "text", "html"}:
raise ValueError(f"unsupported trace format: {raw_format}")
raw_view = request.query_params.get("view", "tree")
raw_view = request.query_params.get("view", "single")
view = raw_view.strip().lower()
if view not in {"tree", "single"}:
raise ValueError(f"unsupported trace view: {raw_view}")
@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Trace 3afa2bd3-db74-433b-b852-4be5bdf2c60b</title>
<style>
:root {
color-scheme: dark;
--bg: #000000;
--fg: #ececec;
--step: #ffffff;
--link: #66d9ef;
--error: #ff817d;
--warning: #e9ebec;
--info: #d6d7d9;
--other: #ececec;
}
body {
margin: 0;
background: var(--bg);
color: var(--fg);
font: 13px/1.1 "SFMono-Regular", monospace;
}
.page {
padding: 14px 16px 24px;
}
a {
color: var(--link);
text-decoration: underline;
text-underline-offset: 2px;
}
.line {
white-space: pre-wrap;
word-break: break-word;
}
.msg-error {
color: var(--error);
}
.msg-warning {
color: var(--warning);
}
.msg-info {
color: var(--info);
}
.msg-debug {
color: var(--other);
}
@media (max-width: 640px) {
.page {
padding: 12px 12px 20px;
}
}
</style>
</head>
<body>
<div class="page">
<div class="line">trace_id: <a href="/traces/3afa2bd3-db74-433b-b852-4be5bdf2c60b?format=html&amp;levels=DEBUG%2CINFO%2CWARNING%2CERROR&amp;attrs_json=true&amp;view=tree&amp;ancestor_depth=all">3afa2bd3-db74-433b-b852-4be5bdf2c60b</a></div><div class="line">parent_id: </div><div class="line">child_ids:</div><div class="line">&nbsp;</div><div class="line">==============================</div><div class="line">trace context: , <a href="/traces/3afa2bd3-db74-433b-b852-4be5bdf2c60b?format=html&amp;levels=DEBUG%2CINFO%2CWARNING%2CERROR&amp;attrs_json=true&amp;view=tree&amp;ancestor_depth=all">3afa2bd3-db74-433b-b852-4be5bdf2c60b</a></div><div class="line">&nbsp;</div><div class="line" style="color: var(--step);">email-processing</div><div class="line">&nbsp;</div><div class="line msg-info">Новых писем не найдено., {}</div>
</div>
</body>
</html>
@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Trace 3afa2bd3-db74-433b-b852-4be5bdf2c60b</title>
<style>
:root {
color-scheme: dark;
--bg: #000000;
--fg: #ececec;
--step: #ffffff;
--link: #66d9ef;
--error: #ff817d;
--warning: #e9ebec;
--info: #d6d7d9;
--other: #ececec;
}
body {
margin: 0;
background: var(--bg);
color: var(--fg);
font: 13px/1.1 "SFMono-Regular", monospace;
}
.page {
padding: 14px 16px 24px;
}
a {
color: var(--link);
text-decoration: underline;
text-underline-offset: 2px;
}
.line {
white-space: pre-wrap;
word-break: break-word;
}
.msg-error {
color: var(--error);
}
.msg-warning {
color: var(--warning);
}
.msg-info {
color: var(--info);
}
.msg-debug {
color: var(--other);
}
@media (max-width: 640px) {
.page {
padding: 12px 12px 20px;
}
}
</style>
</head>
<body>
<div class="page">
<div class="line">trace_id: <a href="/traces/3afa2bd3-db74-433b-b852-4be5bdf2c60b?format=html&amp;levels=DEBUG%2CINFO%2CWARNING%2CERROR&amp;attrs_json=true&amp;view=tree&amp;ancestor_depth=all">3afa2bd3-db74-433b-b852-4be5bdf2c60b</a></div><div class="line">parent_id: </div><div class="line">child_ids:</div><div class="line">&nbsp;</div><div class="line">==============================</div><div class="line">trace context: , <a href="/traces/3afa2bd3-db74-433b-b852-4be5bdf2c60b?format=html&amp;levels=DEBUG%2CINFO%2CWARNING%2CERROR&amp;attrs_json=true&amp;view=tree&amp;ancestor_depth=all">3afa2bd3-db74-433b-b852-4be5bdf2c60b</a></div><div class="line">&nbsp;</div><div class="line" style="color: var(--step);">email-processing</div><div class="line">&nbsp;</div><div class="line msg-info">Новых писем не найдено., {}</div>
</div>
</body>
</html>
@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Trace dc5769f8-4451-4acc-a923-0de56283285e</title>
<style>
:root {
color-scheme: dark;
--bg: #000000;
--fg: #ececec;
--step: #ffffff;
--link: #66d9ef;
--error: #ff817d;
--warning: #e9ebec;
--info: #d6d7d9;
--other: #ececec;
}
body {
margin: 0;
background: var(--bg);
color: var(--fg);
font: 13px/1.1 "SFMono-Regular", monospace;
}
.page {
padding: 14px 16px 24px;
}
a {
color: var(--link);
text-decoration: underline;
text-underline-offset: 2px;
}
.line {
white-space: pre-wrap;
word-break: break-word;
}
.msg-error {
color: var(--error);
}
.msg-warning {
color: var(--warning);
}
.msg-info {
color: var(--info);
}
.msg-debug {
color: var(--other);
}
@media (max-width: 640px) {
.page {
padding: 12px 12px 20px;
}
}
</style>
</head>
<body>
<div class="page">
<div class="line">trace_id: <a href="/traces/dc5769f8-4451-4acc-a923-0de56283285e?format=html&amp;levels=DEBUG%2CINFO%2CWARNING%2CERROR&amp;attrs_json=true&amp;view=tree&amp;ancestor_depth=all">dc5769f8-4451-4acc-a923-0de56283285e</a></div><div class="line">parent_id: </div><div class="line">child_ids:</div><div class="line">&nbsp;</div><div class="line">==============================</div><div class="line">trace context: , <a href="/traces/dc5769f8-4451-4acc-a923-0de56283285e?format=html&amp;levels=DEBUG%2CINFO%2CWARNING%2CERROR&amp;attrs_json=true&amp;view=tree&amp;ancestor_depth=all">dc5769f8-4451-4acc-a923-0de56283285e</a></div><div class="line">&nbsp;</div><div class="line" style="color: var(--step);">order-sync</div><div class="line">&nbsp;</div><div class="line msg-info">Подготовлен запрос синхронизации заказов ABCP. period_start=2026-08-11T20:10:04.926255+00:00, period_end=2026-08-12T20:10:04.926255+00:00., {&quot;period_start&quot;:&quot;2026-08-11T20:10:04.926255+00:00&quot;,&quot;period_end&quot;:&quot;2026-08-12T20:10:04.926255+00:00&quot;,&quot;abcp_request_url&quot;:&quot;static://cp/orders&quot;}</div><div class="line msg-info">Подготовлен запрос синхронизации заказов ABCP. period_start=2026-08-12T20:10:04.924987+00:00, period_end=2026-08-12T20:10:04.926255+00:00., {&quot;period_start&quot;:&quot;2026-08-12T20:10:04.924987+00:00&quot;,&quot;period_end&quot;:&quot;2026-08-12T20:10:04.926255+00:00&quot;,&quot;abcp_request_url&quot;:&quot;static://cp/orders&quot;}</div><div class="line msg-info">Синхронизация заказов завершена. records_loaded=1, period_start=2026-08-11T20:10:04.926255+00:00, period_end=2026-08-12T20:10:04.926255+00:00., {&quot;records_loaded&quot;:1,&quot;period_start&quot;:&quot;2026-08-11T20:10:04.926255+00:00&quot;,&quot;period_end&quot;:&quot;2026-08-12T20:10:04.926255+00:00&quot;}</div>
</div>
</body>
</html>
@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Trace c877db56-2148-47d0-9cb8-c8366ecb094a</title>
<style>
:root {
color-scheme: dark;
--bg: #000000;
--fg: #ececec;
--step: #ffffff;
--link: #66d9ef;
--error: #ff817d;
--warning: #e9ebec;
--info: #d6d7d9;
--other: #ececec;
}
body {
margin: 0;
background: var(--bg);
color: var(--fg);
font: 13px/1.1 "SFMono-Regular", monospace;
}
.page {
padding: 14px 16px 24px;
}
a {
color: var(--link);
text-decoration: underline;
text-underline-offset: 2px;
}
.line {
white-space: pre-wrap;
word-break: break-word;
}
.msg-error {
color: var(--error);
}
.msg-warning {
color: var(--warning);
}
.msg-info {
color: var(--info);
}
.msg-debug {
color: var(--other);
}
@media (max-width: 640px) {
.page {
padding: 12px 12px 20px;
}
}
</style>
</head>
<body>
<div class="page">
<div class="line">trace_id: <a href="/traces/c877db56-2148-47d0-9cb8-c8366ecb094a?format=html&amp;levels=DEBUG%2CINFO%2CWARNING%2CERROR&amp;attrs_json=true&amp;view=tree&amp;ancestor_depth=all">c877db56-2148-47d0-9cb8-c8366ecb094a</a></div><div class="line">parent_id: </div><div class="line">child_ids:</div><div class="line">&nbsp;</div><div class="line">==============================</div><div class="line">trace context: , <a href="/traces/c877db56-2148-47d0-9cb8-c8366ecb094a?format=html&amp;levels=DEBUG%2CINFO%2CWARNING%2CERROR&amp;attrs_json=true&amp;view=tree&amp;ancestor_depth=all">c877db56-2148-47d0-9cb8-c8366ecb094a</a></div><div class="line">&nbsp;</div><div class="line" style="color: var(--step);">order-sync</div><div class="line">&nbsp;</div><div class="line msg-info">Подготовлен запрос синхронизации заказов ABCP. period_start=2026-04-14T20:10:04.612913+00:00, period_end=2026-08-12T20:10:04.612913+00:00., {&quot;period_start&quot;:&quot;2026-04-14T20:10:04.612913+00:00&quot;,&quot;period_end&quot;:&quot;2026-08-12T20:10:04.612913+00:00&quot;,&quot;abcp_request_url&quot;:&quot;unknown://cp/orders&quot;}</div><div class="line msg-info">Подготовлен запрос синхронизации заказов ABCP. period_start=2026-03-24T15:36:42+00:00, period_end=2026-08-12T20:10:04.612913+00:00., {&quot;period_start&quot;:&quot;2026-03-24T15:36:42+00:00&quot;,&quot;period_end&quot;:&quot;2026-08-12T20:10:04.612913+00:00&quot;,&quot;abcp_request_url&quot;:&quot;unknown://cp/orders&quot;}</div><div class="line msg-info">Подготовлен запрос синхронизации заказов ABCP. period_start=2026-04-02T09:30:00+00:00, period_end=2026-08-12T20:10:04.612913+00:00., {&quot;period_start&quot;:&quot;2026-04-02T09:30:00+00:00&quot;,&quot;period_end&quot;:&quot;2026-08-12T20:10:04.612913+00:00&quot;,&quot;abcp_request_url&quot;:&quot;unknown://cp/orders&quot;}</div><div class="line msg-info">Синхронизация заказов завершена. records_loaded=3, period_start=2026-04-14T20:10:04.612913+00:00, period_end=2026-08-12T20:10:04.612913+00:00., {&quot;records_loaded&quot;:3,&quot;period_start&quot;:&quot;2026-04-14T20:10:04.612913+00:00&quot;,&quot;period_end&quot;:&quot;2026-08-12T20:10:04.612913+00:00&quot;}</div>
</div>
</body>
</html>
@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Trace 78ed0674-e1fa-495e-a8f7-2d1eb189a4b2</title>
<style>
:root {
color-scheme: dark;
--bg: #000000;
--fg: #ececec;
--step: #ffffff;
--link: #66d9ef;
--error: #ff817d;
--warning: #e9ebec;
--info: #d6d7d9;
--other: #ececec;
}
body {
margin: 0;
background: var(--bg);
color: var(--fg);
font: 13px/1.1 "SFMono-Regular", monospace;
}
.page {
padding: 14px 16px 24px;
}
a {
color: var(--link);
text-decoration: underline;
text-underline-offset: 2px;
}
.line {
white-space: pre-wrap;
word-break: break-word;
}
.msg-error {
color: var(--error);
}
.msg-warning {
color: var(--warning);
}
.msg-info {
color: var(--info);
}
.msg-debug {
color: var(--other);
}
@media (max-width: 640px) {
.page {
padding: 12px 12px 20px;
}
}
</style>
</head>
<body>
<div class="page">
<div class="line">trace_id: <a href="/traces/78ed0674-e1fa-495e-a8f7-2d1eb189a4b2?format=html&amp;levels=DEBUG%2CINFO%2CWARNING%2CERROR&amp;attrs_json=true&amp;view=tree&amp;ancestor_depth=all">78ed0674-e1fa-495e-a8f7-2d1eb189a4b2</a></div><div class="line">parent_id: </div><div class="line">child_ids:</div><div class="line">&nbsp;</div><div class="line">==============================</div><div class="line">trace context: , <a href="/traces/78ed0674-e1fa-495e-a8f7-2d1eb189a4b2?format=html&amp;levels=DEBUG%2CINFO%2CWARNING%2CERROR&amp;attrs_json=true&amp;view=tree&amp;ancestor_depth=all">78ed0674-e1fa-495e-a8f7-2d1eb189a4b2</a></div><div class="line">&nbsp;</div><div class="line" style="color: var(--step);">order-sync</div><div class="line">&nbsp;</div><div class="line msg-info">Подготовлен запрос синхронизации заказов ABCP. period_start=2026-08-11T20:10:04.195237+00:00, period_end=2026-08-12T20:10:04.195237+00:00., {&quot;period_start&quot;:&quot;2026-08-11T20:10:04.195237+00:00&quot;,&quot;period_end&quot;:&quot;2026-08-12T20:10:04.195237+00:00&quot;,&quot;abcp_request_url&quot;:&quot;static://cp/orders&quot;}</div><div class="line msg-info">Подготовлен запрос синхронизации заказов ABCP. period_start=2026-08-12T20:10:04.193492+00:00, period_end=2026-08-12T20:10:04.195237+00:00., {&quot;period_start&quot;:&quot;2026-08-12T20:10:04.193492+00:00&quot;,&quot;period_end&quot;:&quot;2026-08-12T20:10:04.195237+00:00&quot;,&quot;abcp_request_url&quot;:&quot;static://cp/orders&quot;}</div><div class="line msg-info">Синхронизация заказов завершена. records_loaded=1, period_start=2026-08-11T20:10:04.195237+00:00, period_end=2026-08-12T20:10:04.195237+00:00., {&quot;records_loaded&quot;:1,&quot;period_start&quot;:&quot;2026-08-11T20:10:04.195237+00:00&quot;,&quot;period_end&quot;:&quot;2026-08-12T20:10:04.195237+00:00&quot;}</div>
</div>
</body>
</html>
@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Trace 3ec474af-77db-4d4e-82cc-0c9df0ae10c3</title>
<style>
:root {
color-scheme: dark;
--bg: #000000;
--fg: #ececec;
--step: #ffffff;
--link: #66d9ef;
--error: #ff817d;
--warning: #e9ebec;
--info: #d6d7d9;
--other: #ececec;
}
body {
margin: 0;
background: var(--bg);
color: var(--fg);
font: 13px/1.1 "SFMono-Regular", monospace;
}
.page {
padding: 14px 16px 24px;
}
a {
color: var(--link);
text-decoration: underline;
text-underline-offset: 2px;
}
.line {
white-space: pre-wrap;
word-break: break-word;
}
.msg-error {
color: var(--error);
}
.msg-warning {
color: var(--warning);
}
.msg-info {
color: var(--info);
}
.msg-debug {
color: var(--other);
}
@media (max-width: 640px) {
.page {
padding: 12px 12px 20px;
}
}
</style>
</head>
<body>
<div class="page">
<div class="line">trace_id: <a href="/traces/3ec474af-77db-4d4e-82cc-0c9df0ae10c3?format=html&amp;levels=DEBUG%2CINFO%2CWARNING%2CERROR&amp;attrs_json=true&amp;view=tree&amp;ancestor_depth=all">3ec474af-77db-4d4e-82cc-0c9df0ae10c3</a></div><div class="line">parent_id: </div><div class="line">child_ids:</div><div class="line">&nbsp;</div><div class="line">==============================</div><div class="line">trace context: , <a href="/traces/3ec474af-77db-4d4e-82cc-0c9df0ae10c3?format=html&amp;levels=DEBUG%2CINFO%2CWARNING%2CERROR&amp;attrs_json=true&amp;view=tree&amp;ancestor_depth=all">3ec474af-77db-4d4e-82cc-0c9df0ae10c3</a></div><div class="line">&nbsp;</div><div class="line" style="color: var(--step);">order-sync</div><div class="line">&nbsp;</div><div class="line msg-info">Подготовлен запрос синхронизации заказов ABCP. period_start=2026-04-14T20:10:04.605396+00:00, period_end=2026-08-12T20:10:04.605396+00:00., {&quot;period_start&quot;:&quot;2026-04-14T20:10:04.605396+00:00&quot;,&quot;period_end&quot;:&quot;2026-08-12T20:10:04.605396+00:00&quot;,&quot;abcp_request_url&quot;:&quot;unknown://cp/orders&quot;}</div><div class="line msg-info">Синхронизация заказов завершена без изменений. records_loaded=0, period_start=2026-04-14T20:10:04.605396+00:00, period_end=2026-08-12T20:10:04.605396+00:00., {&quot;records_loaded&quot;:0,&quot;period_start&quot;:&quot;2026-04-14T20:10:04.605396+00:00&quot;,&quot;period_end&quot;:&quot;2026-08-12T20:10:04.605396+00:00&quot;}</div>
</div>
</body>
</html>
@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Trace c263b805-227c-4faf-855b-2d7bc51427e6</title>
<style>
:root {
color-scheme: dark;
--bg: #000000;
--fg: #ececec;
--step: #ffffff;
--link: #66d9ef;
--error: #ff817d;
--warning: #e9ebec;
--info: #d6d7d9;
--other: #ececec;
}
body {
margin: 0;
background: var(--bg);
color: var(--fg);
font: 13px/1.1 "SFMono-Regular", monospace;
}
.page {
padding: 14px 16px 24px;
}
a {
color: var(--link);
text-decoration: underline;
text-underline-offset: 2px;
}
.line {
white-space: pre-wrap;
word-break: break-word;
}
.msg-error {
color: var(--error);
}
.msg-warning {
color: var(--warning);
}
.msg-info {
color: var(--info);
}
.msg-debug {
color: var(--other);
}
@media (max-width: 640px) {
.page {
padding: 12px 12px 20px;
}
}
</style>
</head>
<body>
<div class="page">
<div class="line">trace_id: <a href="/traces/c263b805-227c-4faf-855b-2d7bc51427e6?format=html&amp;levels=DEBUG%2CINFO%2CWARNING%2CERROR&amp;attrs_json=true&amp;view=tree&amp;ancestor_depth=all">c263b805-227c-4faf-855b-2d7bc51427e6</a></div><div class="line">parent_id: </div><div class="line">child_ids:</div><div class="line">&nbsp;</div><div class="line">==============================</div><div class="line">trace context: , <a href="/traces/c263b805-227c-4faf-855b-2d7bc51427e6?format=html&amp;levels=DEBUG%2CINFO%2CWARNING%2CERROR&amp;attrs_json=true&amp;view=tree&amp;ancestor_depth=all">c263b805-227c-4faf-855b-2d7bc51427e6</a></div><div class="line">&nbsp;</div><div class="line" style="color: var(--step);">order-sync</div><div class="line">&nbsp;</div><div class="line msg-info">Подготовлен запрос синхронизации заказов ABCP. period_start=2026-04-14T20:10:04.620037+00:00, period_end=2026-08-12T20:10:04.620037+00:00., {&quot;period_start&quot;:&quot;2026-04-14T20:10:04.620037+00:00&quot;,&quot;period_end&quot;:&quot;2026-08-12T20:10:04.620037+00:00&quot;,&quot;abcp_request_url&quot;:&quot;unknown://cp/orders&quot;}</div><div class="line msg-info">Подготовлен запрос синхронизации заказов ABCP. period_start=2026-03-24T15:36:42+00:00, period_end=2026-08-12T20:10:04.620037+00:00., {&quot;period_start&quot;:&quot;2026-03-24T15:36:42+00:00&quot;,&quot;period_end&quot;:&quot;2026-08-12T20:10:04.620037+00:00&quot;,&quot;abcp_request_url&quot;:&quot;unknown://cp/orders&quot;}</div><div class="line msg-info">Подготовлен запрос синхронизации заказов ABCP. period_start=2026-04-02T09:30:00+00:00, period_end=2026-08-12T20:10:04.620037+00:00., {&quot;period_start&quot;:&quot;2026-04-02T09:30:00+00:00&quot;,&quot;period_end&quot;:&quot;2026-08-12T20:10:04.620037+00:00&quot;,&quot;abcp_request_url&quot;:&quot;unknown://cp/orders&quot;}</div><div class="line msg-info">Синхронизация заказов завершена. records_loaded=2, period_start=2026-04-14T20:10:04.620037+00:00, period_end=2026-08-12T20:10:04.620037+00:00., {&quot;records_loaded&quot;:2,&quot;period_start&quot;:&quot;2026-04-14T20:10:04.620037+00:00&quot;,&quot;period_end&quot;:&quot;2026-08-12T20:10:04.620037+00:00&quot;}</div>
</div>
</body>
</html>
@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Trace 2ca6de8b-8dbe-4ccd-b5a5-491739119228</title>
<style>
:root {
color-scheme: dark;
--bg: #000000;
--fg: #ececec;
--step: #ffffff;
--link: #66d9ef;
--error: #ff817d;
--warning: #e9ebec;
--info: #d6d7d9;
--other: #ececec;
}
body {
margin: 0;
background: var(--bg);
color: var(--fg);
font: 13px/1.1 "SFMono-Regular", monospace;
}
.page {
padding: 14px 16px 24px;
}
a {
color: var(--link);
text-decoration: underline;
text-underline-offset: 2px;
}
.line {
white-space: pre-wrap;
word-break: break-word;
}
.msg-error {
color: var(--error);
}
.msg-warning {
color: var(--warning);
}
.msg-info {
color: var(--info);
}
.msg-debug {
color: var(--other);
}
@media (max-width: 640px) {
.page {
padding: 12px 12px 20px;
}
}
</style>
</head>
<body>
<div class="page">
<div class="line">trace_id: <a href="/traces/2ca6de8b-8dbe-4ccd-b5a5-491739119228?format=html&amp;levels=DEBUG%2CINFO%2CWARNING%2CERROR&amp;attrs_json=true&amp;view=tree&amp;ancestor_depth=all">2ca6de8b-8dbe-4ccd-b5a5-491739119228</a></div><div class="line">parent_id: </div><div class="line">child_ids:</div><div class="line">&nbsp;</div><div class="line">==============================</div><div class="line">trace context: , <a href="/traces/2ca6de8b-8dbe-4ccd-b5a5-491739119228?format=html&amp;levels=DEBUG%2CINFO%2CWARNING%2CERROR&amp;attrs_json=true&amp;view=tree&amp;ancestor_depth=all">2ca6de8b-8dbe-4ccd-b5a5-491739119228</a></div><div class="line">&nbsp;</div><div class="line" style="color: var(--step);">order-sync</div><div class="line">&nbsp;</div><div class="line msg-info">Подготовлен запрос синхронизации заказов ABCP. period_start=2026-06-30T10:00:00+00:00, period_end=2026-06-30T11:00:00+00:00., {&quot;period_start&quot;:&quot;2026-06-30T10:00:00+00:00&quot;,&quot;period_end&quot;:&quot;2026-06-30T11:00:00+00:00&quot;}</div>
</div>
</body>
</html>
@@ -0,0 +1,61 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Trace e4cae497-d728-498f-8216-651a44e59992</title>
<style>
:root {
color-scheme: dark;
--bg: #000000;
--fg: #ececec;
--step: #ffffff;
--link: #66d9ef;
--error: #ff817d;
--warning: #e9ebec;
--info: #d6d7d9;
--other: #ececec;
}
body {
margin: 0;
background: var(--bg);
color: var(--fg);
font: 13px/1.1 "SFMono-Regular", monospace;
}
.page {
padding: 14px 16px 24px;
}
a {
color: var(--link);
text-decoration: underline;
text-underline-offset: 2px;
}
.line {
white-space: pre-wrap;
word-break: break-word;
}
.msg-error {
color: var(--error);
}
.msg-warning {
color: var(--warning);
}
.msg-info {
color: var(--info);
}
.msg-debug {
color: var(--other);
}
@media (max-width: 640px) {
.page {
padding: 12px 12px 20px;
}
}
</style>
</head>
<body>
<div class="page">
<div class="line">trace_id: <a href="/traces/e4cae497-d728-498f-8216-651a44e59992?format=html&amp;levels=DEBUG%2CINFO%2CWARNING%2CERROR&amp;attrs_json=true&amp;view=tree&amp;ancestor_depth=all">e4cae497-d728-498f-8216-651a44e59992</a></div><div class="line">parent_id: </div><div class="line">child_ids:</div><div class="line">&nbsp;</div><div class="line">==============================</div><div class="line">trace context: , <a href="/traces/e4cae497-d728-498f-8216-651a44e59992?format=html&amp;levels=DEBUG%2CINFO%2CWARNING%2CERROR&amp;attrs_json=true&amp;view=tree&amp;ancestor_depth=all">e4cae497-d728-498f-8216-651a44e59992</a></div><div class="line">&nbsp;</div><div class="line" style="color: var(--step);">worker-loop</div><div class="line">&nbsp;</div><div class="line msg-error">Необработанное исключение воркера. worker_name=job-processing, error=RuntimeError(&#x27;boom&#x27;)., {&quot;worker_name&quot;:&quot;job-processing&quot;,&quot;error&quot;:&quot;boom&quot;,&quot;exception_class&quot;:&quot;RuntimeError&quot;}</div>
</div>
</body>
</html>
+23 -39
View File
@@ -80,8 +80,8 @@ def test_trace_endpoint_returns_html_by_default() -> None:
levels=("ERROR", "WARNING", "INFO"),
include_attrs_json=False,
response_format="html",
ancestor_depth=None,
view="tree",
ancestor_depth=0,
view="single",
),
)
]
@@ -333,13 +333,13 @@ def test_trace_endpoint_returns_html_page_with_related_links() -> None:
assert "--error: #ff817d;" in response.text
assert "--other: #ececec;" in response.text
assert 'font: 13px/1.1 "SFMono-Regular", monospace;' in response.text
assert '<div class="line">trace_id: <a href="/traces/trace-1?format=html&amp;levels=ERROR%2CWARNING%2CINFO&amp;attrs_json=true&amp;view=tree&amp;ancestor_depth=all">trace-1</a></div>' in response.text
assert '<div class="line">parent_id: <a href="/traces/parent-1?format=html&amp;levels=ERROR%2CWARNING%2CINFO&amp;attrs_json=true&amp;view=tree&amp;ancestor_depth=all">parent-1</a></div>' in response.text
assert '<div class="line">trace_id: <a href="/traces/trace-1?format=html&amp;levels=ERROR%2CWARNING%2CINFO&amp;attrs_json=true&amp;view=single">trace-1</a></div>' in response.text
assert '<div class="line">parent_id: <a href="/traces/parent-1?format=html&amp;levels=ERROR%2CWARNING%2CINFO&amp;attrs_json=true&amp;view=single">parent-1</a></div>' in response.text
assert '<div class="line">child_ids:</div>' in response.text
assert '<div class="line"> - <a href="/traces/child-1?format=html&amp;levels=ERROR%2CWARNING%2CINFO&amp;attrs_json=true&amp;view=tree&amp;ancestor_depth=all">child-1</a></div>' in response.text
assert '<div class="line"> - <a href="/traces/child-2?format=html&amp;levels=ERROR%2CWARNING%2CINFO&amp;attrs_json=true&amp;view=tree&amp;ancestor_depth=all">child-2</a></div>' in response.text
assert '<div class="line"> - <a href="/traces/child-1?format=html&amp;levels=ERROR%2CWARNING%2CINFO&amp;attrs_json=true&amp;view=single">child-1</a></div>' in response.text
assert '<div class="line"> - <a href="/traces/child-2?format=html&amp;levels=ERROR%2CWARNING%2CINFO&amp;attrs_json=true&amp;view=single">child-2</a></div>' in response.text
assert '<div class="line">==============================</div>' in response.text
assert '<div class="line">trace context: order_confirmation, <a href="/traces/trace-1?format=html&amp;levels=ERROR%2CWARNING%2CINFO&amp;attrs_json=true&amp;view=tree&amp;ancestor_depth=all">trace-1</a></div>' in response.text
assert '<div class="line">trace context: order_confirmation, <a href="/traces/trace-1?format=html&amp;levels=ERROR%2CWARNING%2CINFO&amp;attrs_json=true&amp;view=single">trace-1</a></div>' in response.text
assert '<div class="line" style="color: var(--step);">load_stocks</div>' in response.text
assert '<div class="line" style="color: var(--step);">filter_stocks</div>' in response.text
assert "loaded prices" in response.text
@@ -450,43 +450,17 @@ def test_trace_endpoint_preserves_ancestor_depth_in_html_links() -> None:
assert "parent warning" in response.text
def test_trace_endpoint_returns_full_tree_by_default() -> None:
def test_trace_endpoint_returns_single_view_by_default() -> None:
async def trace_provider(trace_id: str, request: TraceQueryRequest) -> TraceLogView:
assert trace_id == "child-1"
assert request.view == "tree"
assert request.ancestor_depth is None
assert request.view == "single"
assert request.ancestor_depth == 0
return TraceLogView(
trace_id="root-1",
parent_id=None,
alias="root",
child_ids=("parent-1",),
records=(_trace_record(row_id=1, level="INFO", message="root message"),),
descendants=(
TraceLogView(
trace_id="parent-1",
parent_id="root-1",
alias="parent",
child_ids=("child-1", "sibling-1"),
records=(_trace_record(row_id=2, level="WARNING", message="parent message"),),
descendants=(
TraceLogView(
trace_id="child-1",
parent_id="parent-1",
alias="child",
child_ids=(),
child_ids=("leaf-1",),
records=(_trace_record(row_id=3, level="ERROR", message="child message"),),
),
TraceLogView(
trace_id="sibling-1",
parent_id="parent-1",
alias="sibling",
child_ids=(),
records=(_trace_record(row_id=4, level="INFO", message="sibling message"),),
),
),
),
),
requested_trace_id="child-1",
)
client = _build_client(trace_provider)
@@ -496,8 +470,18 @@ def test_trace_endpoint_returns_full_tree_by_default() -> None:
client.close()
assert response.status_code == 200
assert "requested_trace_id: child-1" in response.text
assert response.text.index("root message") < response.text.index("parent message") < response.text.index("child message") < response.text.index("sibling message")
assert response.text == (
"trace_id: child-1\n"
"parent_id: parent-1\n"
"child_ids:\n"
" - leaf-1\n"
"\n"
"==============================\n"
"trace context: child, child-1\n"
"\n"
"step: process\n"
"child message"
)
def test_trace_endpoint_supports_single_view_opt_in() -> None: