Skip to content

Commit c24ef2e

Browse files
committed
fix: EOS loguru logging of EOSdash stdout logs
When patching loguru logging records do not replace structured loguru fields. Signed-off-by: Bobby Noelte <b0661n0e17e@gmail.com>
1 parent 3bf3b82 commit c24ef2e

5 files changed

Lines changed: 75 additions & 29 deletions

File tree

docs/_generated/configexample.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@
136136
}
137137
},
138138
"general": {
139-
"version": "0.2.0.dev81043823",
139+
"version": "0.2.0.dev23478293",
140140
"data_folder_path": null,
141141
"data_output_subpath": "output",
142142
"latitude": 52.52,

docs/_generated/configgeneral.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
| latitude | `EOS_GENERAL__LATITUDE` | `Optional[float]` | `rw` | `52.52` | Latitude in decimal degrees between -90 and 90. North is positive (ISO 19115) (°) |
1717
| longitude | `EOS_GENERAL__LONGITUDE` | `Optional[float]` | `rw` | `13.405` | Longitude in decimal degrees within -180 to 180 (°) |
1818
| timezone | | `Optional[str]` | `ro` | `N/A` | Computed timezone based on latitude and longitude. |
19-
| version | `EOS_GENERAL__VERSION` | `str` | `rw` | `0.2.0.dev81043823` | Configuration file version. Used to check compatibility. |
19+
| version | `EOS_GENERAL__VERSION` | `str` | `rw` | `0.2.0.dev23478293` | Configuration file version. Used to check compatibility. |
2020
:::
2121
<!-- pyml enable line-length -->
2222

@@ -28,7 +28,7 @@
2828
```json
2929
{
3030
"general": {
31-
"version": "0.2.0.dev81043823",
31+
"version": "0.2.0.dev23478293",
3232
"data_folder_path": null,
3333
"data_output_subpath": "output",
3434
"latitude": 52.52,
@@ -46,7 +46,7 @@
4646
```json
4747
{
4848
"general": {
49-
"version": "0.2.0.dev81043823",
49+
"version": "0.2.0.dev23478293",
5050
"data_folder_path": null,
5151
"data_output_subpath": "output",
5252
"latitude": 52.52,

docs/_generated/openapi.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Akkudoktor-EOS
22

3-
**Version**: `v0.2.0.dev81043823`
3+
**Version**: `v0.2.0.dev23478293`
44

55
<!-- pyml disable line-length -->
66
**Description**: This project provides a comprehensive solution for simulating and optimizing an energy system based on renewable energy sources. With a focus on photovoltaic (PV) systems, battery storage (batteries), load management (consumer requirements), heat pumps, electric vehicles, and consideration of electricity price data, this system enables forecasting and optimization of energy flow and costs over a specified period.

openapi.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"info": {
44
"title": "Akkudoktor-EOS",
55
"description": "This project provides a comprehensive solution for simulating and optimizing an energy system based on renewable energy sources. With a focus on photovoltaic (PV) systems, battery storage (batteries), load management (consumer requirements), heat pumps, electric vehicles, and consideration of electricity price data, this system enables forecasting and optimization of energy flow and costs over a specified period.",
6-
"version": "v0.2.0.dev81043823"
6+
"version": "v0.2.0.dev23478293"
77
},
88
"paths": {
99
"/v1/admin/cache/clear": {
@@ -2525,7 +2525,7 @@
25252525
"general": {
25262526
"$ref": "#/components/schemas/GeneralSettings-Output",
25272527
"default": {
2528-
"version": "0.2.0.dev81043823",
2528+
"version": "0.2.0.dev23478293",
25292529
"data_output_subpath": "output",
25302530
"latitude": 52.52,
25312531
"longitude": 13.405,
@@ -4272,7 +4272,7 @@
42724272
"type": "string",
42734273
"title": "Version",
42744274
"description": "Configuration file version. Used to check compatibility.",
4275-
"default": "0.2.0.dev81043823"
4275+
"default": "0.2.0.dev23478293"
42764276
},
42774277
"data_folder_path": {
42784278
"anyOf": [
@@ -4346,7 +4346,7 @@
43464346
"type": "string",
43474347
"title": "Version",
43484348
"description": "Configuration file version. Used to check compatibility.",
4349-
"default": "0.2.0.dev81043823"
4349+
"default": "0.2.0.dev23478293"
43504350
},
43514351
"data_folder_path": {
43524352
"anyOf": [

src/akkudoktoreos/server/rest/starteosdash.py

Lines changed: 66 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import re
44
import sys
55
from pathlib import Path
6+
from typing import Any, MutableMapping
67

78
from loguru import logger
89

@@ -36,6 +37,58 @@
3637
)
3738

3839

40+
def patch_loguru_record(
41+
record: MutableMapping[str, Any],
42+
*,
43+
file_name: str,
44+
file_path: str,
45+
line_no: int,
46+
function: str,
47+
logger_name: str = "EOSdash",
48+
) -> None:
49+
"""Patch a Loguru log record with subprocess-origin metadata.
50+
51+
This helper mutates an existing Loguru record in-place to update selected
52+
metadata fields (file, line, function, and logger name) while preserving
53+
Loguru's internal record structure. It must be used with ``logger.patch()``
54+
and **must not** replace structured fields (such as ``record["file"]``)
55+
with plain dictionaries.
56+
57+
The function is intended for forwarding log messages originating from
58+
subprocess stdout/stderr streams into Loguru while retaining meaningful
59+
source information (e.g., file path and line number).
60+
61+
Args:
62+
record:
63+
The Loguru record dictionary provided to ``logger.patch()``.
64+
file_name:
65+
The source file name to assign (e.g. ``"main.py"``).
66+
file_path:
67+
The full source file path to assign
68+
(e.g. ``"/app/server/main.py"``).
69+
line_no:
70+
The source line number associated with the log entry.
71+
function:
72+
The function name associated with the log entry.
73+
logger_name:
74+
The logical logger name to assign to the record. Defaults to
75+
``"EOSdash"``.
76+
77+
Notes:
78+
- This function mutates the record in-place and returns ``None``.
79+
- Only attributes of existing structured objects are modified;
80+
no structured Loguru fields are replaced.
81+
- Replacing ``record["file"]`` or similar structured fields with a
82+
dictionary will cause Loguru sinks to fail.
83+
84+
"""
85+
record["file"].name = file_name
86+
record["file"].path = file_path
87+
record["line"] = line_no
88+
record["function"] = function
89+
record["name"] = logger_name
90+
91+
3992
async def forward_stream(stream: asyncio.StreamReader, prefix: str = "") -> None:
4093
"""Continuously read log lines from a subprocess and re-log them via Loguru.
4194
@@ -94,16 +147,12 @@ async def forward_stream(stream: asyncio.StreamReader, prefix: str = "") -> None
94147

95148
# ---- Patch logger with realistic metadata ----
96149
patched = logger.patch(
97-
lambda r: r.update(
98-
{
99-
"file": {
100-
"name": file_name,
101-
"path": file_path,
102-
},
103-
"line": line_no,
104-
"function": func_name,
105-
"name": "EOSdash",
106-
}
150+
lambda r: patch_loguru_record(
151+
r,
152+
file_name=file_name,
153+
file_path=file_path,
154+
line_no=line_no,
155+
function=func_name,
107156
)
108157
)
109158

@@ -115,16 +164,13 @@ async def forward_stream(stream: asyncio.StreamReader, prefix: str = "") -> None
115164
file_path = f"/subprocess/{file_name}"
116165

117166
logger.patch(
118-
lambda r: r.update(
119-
{
120-
"file": {
121-
"name": file_name,
122-
"path": file_path,
123-
},
124-
"line": 1,
125-
"function": "<subprocess>",
126-
"name": "EOSdash",
127-
}
167+
lambda r: patch_loguru_record(
168+
r,
169+
file_name=file_name,
170+
file_path=file_path,
171+
line_no=1,
172+
function="<subprocess>",
173+
logger_name="EOSdash",
128174
)
129175
).info(f"{prefix}{raw}")
130176

0 commit comments

Comments
 (0)