Skip to content

Commit

Permalink
Always use IDENTICAL timestamps so the power and slog reports can match
Browse files Browse the repository at this point in the history
  • Loading branch information
geeksville committed Jul 10, 2024
1 parent d0db5ca commit 628a4cb
Showing 1 changed file with 35 additions and 13 deletions.
48 changes: 35 additions & 13 deletions meshtastic/slog/slog.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,23 @@ def __init__(self, pMeter: PowerMeter, file_path: str, interval=0.2) -> None:
)
self.thread.start()

def store_current_reading(self, now: datetime | None = None) -> None:
"""Store current power measurement."""
if now is None:
now = datetime.now()
d = {

Check warning on line 89 in meshtastic/slog/slog.py

View check run for this annotation

Codecov / codecov/patch

meshtastic/slog/slog.py#L87-L89

Added lines #L87 - L89 were not covered by tests
"time": now,
"average_mW": self.pMeter.get_average_current_mA(),
"max_mW": self.pMeter.get_max_current_mA(),
"min_mW": self.pMeter.get_min_current_mA(),
}
self.pMeter.reset_measurements()
self.writer.add_row(d)

Check warning on line 96 in meshtastic/slog/slog.py

View check run for this annotation

Codecov / codecov/patch

meshtastic/slog/slog.py#L95-L96

Added lines #L95 - L96 were not covered by tests

def _logging_thread(self) -> None:
"""Background thread for logging the current watts reading."""
while self.is_logging:
d = {
"time": datetime.now(),
"average_mW": self.pMeter.get_average_current_mA(),
"max_mW": self.pMeter.get_max_current_mA(),
"min_mW": self.pMeter.get_min_current_mA(),
}
self.pMeter.reset_measurements()
self.writer.add_row(d)
self.store_current_reading()

Check warning on line 101 in meshtastic/slog/slog.py

View check run for this annotation

Codecov / codecov/patch

meshtastic/slog/slog.py#L101

Added line #L101 was not covered by tests
time.sleep(self.interval)

def close(self) -> None:
Expand All @@ -112,12 +118,19 @@ class StructuredLogger:
"""Sniffs device logs for structured log messages, extracts those into apache arrow format.
Also writes the raw log messages to raw.txt"""

def __init__(self, client: MeshInterface, dir_path: str, include_raw=True) -> None:
def __init__(
self,
client: MeshInterface,
dir_path: str,
power_logger: PowerLogger | None = None,
include_raw=True,
) -> None:
"""Initialize the StructuredLogger object.
client (MeshInterface): The MeshInterface object to monitor.
"""
self.client = client
self.power_logger = power_logger

Check warning on line 133 in meshtastic/slog/slog.py

View check run for this annotation

Codecov / codecov/patch

meshtastic/slog/slog.py#L133

Added line #L133 was not covered by tests

# Setup the arrow writer (and its schema)
self.writer = FeatherWriter(f"{dir_path}/slog")
Expand All @@ -129,6 +142,9 @@ def __init__(self, client: MeshInterface, dir_path: str, include_raw=True) -> No
if self.include_raw:
all_fields.append(("raw", pa.string()))

Check warning on line 143 in meshtastic/slog/slog.py

View check run for this annotation

Codecov / codecov/patch

meshtastic/slog/slog.py#L141-L143

Added lines #L141 - L143 were not covered by tests

# Use timestamp as the first column
all_fields.insert(0, ("time", pa.timestamp("us")))

Check warning on line 146 in meshtastic/slog/slog.py

View check run for this annotation

Codecov / codecov/patch

meshtastic/slog/slog.py#L146

Added line #L146 was not covered by tests

# pass in our name->type tuples a pa.fields
self.writer.set_schema(

Check warning on line 149 in meshtastic/slog/slog.py

View check run for this annotation

Codecov / codecov/patch

meshtastic/slog/slog.py#L149

Added line #L149 was not covered by tests
pa.schema(map(lambda x: pa.field(x[0], x[1]), all_fields))
Expand Down Expand Up @@ -198,11 +214,16 @@ def _onLogMessage(self, line: str) -> None:

# Store our structured log record
if di or self.include_raw:
di["time"] = datetime.now()
now = datetime.now()
di["time"] = now
if self.include_raw:
di["raw"] = line
self.writer.add_row(di)

Check warning on line 221 in meshtastic/slog/slog.py

View check run for this annotation

Codecov / codecov/patch

meshtastic/slog/slog.py#L216-L221

Added lines #L216 - L221 were not covered by tests

# If we have a sibling power logger, make sure we have a power measurement with the EXACT same timestamp
if self.power_logger:
self.power_logger.store_current_reading(now)

Check warning on line 225 in meshtastic/slog/slog.py

View check run for this annotation

Codecov / codecov/patch

meshtastic/slog/slog.py#L224-L225

Added lines #L224 - L225 were not covered by tests

if self.raw_file:
self.raw_file.write(line + "\n") # Write the raw log

Expand Down Expand Up @@ -239,15 +260,16 @@ def __init__(

logging.info(f"Writing slogs to {dir_name}")

self.slog_logger: Optional[StructuredLogger] = StructuredLogger(
client, self.dir_name
)
self.power_logger: Optional[PowerLogger] = (
None
if not power_meter
else PowerLogger(power_meter, f"{self.dir_name}/power")
)

self.slog_logger: Optional[StructuredLogger] = StructuredLogger(

Check warning on line 269 in meshtastic/slog/slog.py

View check run for this annotation

Codecov / codecov/patch

meshtastic/slog/slog.py#L269

Added line #L269 was not covered by tests
client, self.dir_name, power_logger=self.power_logger
)

# Store a lambda so we can find it again to unregister
self.atexit_handler = lambda: self.close() # pylint: disable=unnecessary-lambda

Expand Down

0 comments on commit 628a4cb

Please sign in to comment.