Skip to content

Commit 14aa746

Browse files
committed
Run ruff
1 parent fed60b1 commit 14aa746

3 files changed

Lines changed: 63 additions & 44 deletions

File tree

src/daqpytools/apps/logging_demonstrator.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
import logging
22
import os
33
import time
4+
45
import click
56
from rich.traceback import install as rich_traceback_install
67

78
from daqpytools.logging.exceptions import LoggerSetupError
89
from daqpytools.logging.handlers import (
910
HandlerType,
1011
LogHandlerConf,
11-
ThrottleFilter,
12-
StreamType,
1312
)
1413
from daqpytools.logging.levels import logging_log_level_keys
1514
from daqpytools.logging.logger import get_daq_logger
@@ -71,10 +70,11 @@ def validate_test_configuration(
7170
)
7271
)
7372
@click.option(
73+
"-t",
7474
"--throttle",
7575
is_flag=True,
7676
help=(
77-
"Demonstrate throttling functionality"
77+
"Demonstrate throttling functionality. Requires Rich handlers"
7878
)
7979
)
8080
@click.option(
@@ -131,6 +131,7 @@ def main(
131131
to be set to true.
132132
handlertypes (bool): If true, demonstrates the advanced feature of HandlerTypes
133133
and streams.
134+
throttle (bool): If true, demonstrates the throttling feature. Requires Rich.
134135
135136
Returns:
136137
None
@@ -209,14 +210,27 @@ def main(
209210

210211

211212
# Throttle demo
212-
def emit_err(i):
213-
main_logger.info(f"Throttle test {i}", extra={"handlers": [HandlerType.Rich, HandlerType.Throttle]})
213+
def emit_err(i: int) -> None:
214+
"""Short function that prints out a log message.
215+
This is used to ensure that the log message is kept on the same line,
216+
but also to feed in how many repetitions it has gone through
217+
Args:
218+
i (int): Integer to be transmitted in the log message.
219+
220+
Returns:
221+
None.
222+
"""
223+
throttle_msg = f"Throttle test {i}"
224+
main_logger.info(throttle_msg, extra={"handlers":
225+
[HandlerType.Rich, HandlerType.Throttle]
226+
})
227+
214228
if throttle:
215229
for i in range(50):
216230
emit_err(i)
217231
main_logger.warning("Sleeping for 30 seconds")
218-
time.sleep(31) #demonstrate 30s time window
219-
for i in range(100):
232+
time.sleep(31)
233+
for i in range(1000):
220234
emit_err(i)
221235

222236

src/daqpytools/logging/handlers.py

Lines changed: 41 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
from __future__ import annotations
22

3+
import copy
34
import io
45
import logging
5-
import copy
66
import os
77
import re
88
import sys
9+
import time
10+
from collections import defaultdict
911
from dataclasses import dataclass, field
1012
from datetime import datetime
1113
from enum import Enum
12-
from typing import ClassVar, cast, Dict, Optional
13-
14-
import time
15-
from collections import defaultdict
1614
from threading import Lock
15+
from typing import ClassVar, cast
1716

1817
from erskafka.ERSKafkaLogHandler import ERSKafkaLogHandler
1918
from rich.console import Console, ConsoleRenderable
@@ -35,6 +34,7 @@
3534
from daqpytools.logging.levels import level_to_ers_var, logging_log_level_to_str
3635
from daqpytools.logging.utils import get_width
3736

37+
3838
class FormattedRichHandler(RichHandler):
3939
"""RichHandler that formats log messages with time, aligned columns, and styles."""
4040

@@ -165,9 +165,8 @@ class HandlerType(Enum):
165165
def from_string(cls, s: str) -> HandlerType | None:
166166
"""Converts from a case-independent string to HandlerType."""
167167
try:
168-
h = HandlerType(s.lower())
169-
return h
170-
except:
168+
return HandlerType(s.lower())
169+
except ValueError:
171170
msg=f"[red]{s}[/red] is not a known handler type"
172171
log.warning(msg)
173172
return None
@@ -238,7 +237,11 @@ def _convert_str_to_handlertype(handler_str: str) -> tuple[HandlerType,
238237
protobuf configuration
239238
"""
240239
if "erstrace" in handler_str:
241-
log.debug("ERSTrace is a C++ implementation, does not have an equivalent in Python")
240+
msg = (
241+
"ERSTrace is a C++ implementation, "
242+
"does not have an equivalent in Python"
243+
)
244+
log.debug(msg)
242245
return None, None
243246

244247
if HandlerType.Protobufstream.value not in handler_str:
@@ -281,10 +284,11 @@ def get_base() -> set[HandlerType]:
281284
class IssueRecord:
282285
"""Tracks throttling state for a unique issue (identified by file: line)."""
283286

284-
def __init__(self):
287+
def __init__(self) -> None:
288+
"""C'tor."""
285289
self.reset()
286290

287-
def reset(self):
291+
def reset(self) -> None:
288292
"""Reset all counters and timestamps."""
289293
self.last_occurrence: float = 0.0
290294
self.last_report: float = 0.0
@@ -295,11 +299,16 @@ def reset(self):
295299

296300

297301
class BaseHandlerFilter(logging.Filter):
298-
def __init__(self):
302+
"""Base filter that hold the logic on choosing if a handler should emit
303+
based on what HandlersTypes are supplied to it.
304+
"""
305+
def __init__(self) -> None:
306+
"""C'tor."""
299307
super().__init__()
300308

301-
def get_allowed(self, record) -> list | None:
302-
# TODO/future: kafka protobufs should validate url/port match before transmitting
309+
def get_allowed(self, record: logging.LogRecord) -> list | None:
310+
"""Parses the record to obtain the set of Handlers that allows transmission."""
311+
# TODO/future: kafkaprotobufs should validate url/port match before transmitting
303312

304313
# Handle the ERS case, requires more processing
305314
if getattr(record, "stream", None) == StreamType.ERS:
@@ -327,7 +336,7 @@ class HandleIDFilter(BaseHandlerFilter):
327336
if the current handler (defined by the handler_id) is within the set of
328337
allowed handlers.
329338
"""
330-
def __init__(self, handler_id: Union[HandlerType, List[HandlerType]]) -> None:
339+
def __init__(self, handler_id: HandlerType | list[HandlerType]) -> None:
331340
"""Initialises HandleIDFilter with the handler_id, to identify what
332341
kind of handler this filter is.
333342
"""
@@ -346,11 +355,11 @@ def filter(self, record: logging.LogRecord) -> bool:
346355
return bool(self.handler_ids & set(allowed))
347356

348357
class ThrottleFilter(BaseHandlerFilter):
349-
"""
350-
Advanced logging filter with escalating throttle thresholds.
358+
"""Advanced logging filter with escalating throttle thresholds.
351359
352360
Args:
353-
initial_threshold: Number of initial occurrences to let through immediately (default: 30)
361+
initial_threshold: Number of initial occurrences
362+
to let through immediately (default: 30)
354363
time_limit: Time window in seconds for resetting state (default: 30)
355364
name: Optional filter name
356365
@@ -368,16 +377,16 @@ class ThrottleFilter(BaseHandlerFilter):
368377
... logger.error("Repeated error message")
369378
"""
370379

371-
def __init__(self, initial_threshold: int = 30, time_limit: int = 30):
380+
def __init__(self, initial_threshold: int = 30, time_limit: int = 30) -> None:
381+
"""C'tor."""
372382
super().__init__()
373383
self.initial_threshold = initial_threshold
374384
self.time_limit = time_limit
375-
self.issue_map: Dict[str, IssueRecord] = defaultdict(IssueRecord)
385+
self.issue_map: dict[str, IssueRecord] = defaultdict(IssueRecord)
376386
self.mutex = Lock() # Ensures thread safety
377387

378388
def filter(self, record: logging.LogRecord) -> bool:
379-
"""
380-
Determine if a log record should be emitted.
389+
"""Determine if a log record should be emitted.
381390
382391
Args:
383392
record: The log record to filter
@@ -401,8 +410,7 @@ def filter(self, record: logging.LogRecord) -> bool:
401410
return self._throttle(issue_record, record)
402411

403412
def _throttle(self, rec: IssueRecord, record: logging.LogRecord) -> bool:
404-
"""
405-
Apply throttling logic to determine if record should be emitted.
413+
"""Apply throttling logic to determine if record should be emitted.
406414
407415
Args:
408416
rec: The issue record tracking state for this unique issue
@@ -432,30 +440,28 @@ def _throttle(self, rec: IssueRecord, record: logging.LogRecord) -> bool:
432440
return not reported
433441

434442
# Step 3: Check if we hit the escalating threshold
435-
elif rec.suppressed_counter >= rec.threshold:
443+
if rec.suppressed_counter >= rec.threshold:
436444
rec.threshold = rec.threshold * 10 # Escalate: 10 -> 100 -> 1000 ...
437445
rec.last_occurrence = current_time
438446
rec. last_occurrence_formatted = self._format_timestamp(current_time)
439447
self._report_suppression(rec, record)
440448
return False # Don't emit the original record
441449

442450
# Step 4: Check if enough time passed since last report
443-
elif current_time - rec.last_report > self.time_limit:
451+
if current_time - rec.last_report > self.time_limit:
444452
rec.last_occurrence = current_time
445453
rec. last_occurrence_formatted = self._format_timestamp(current_time)
446454
self._report_suppression(rec, record)
447455
return False # Don't emit the original record
448456

449457
# Step 5: Suppress silently
450-
else:
451-
rec.suppressed_counter += 1
452-
rec.last_occurrence = current_time
453-
rec. last_occurrence_formatted = self._format_timestamp(current_time)
454-
return False
458+
rec.suppressed_counter += 1
459+
rec.last_occurrence = current_time
460+
rec. last_occurrence_formatted = self._format_timestamp(current_time)
461+
return False
455462

456-
def _report_suppression(self, rec: IssueRecord, record: logging.LogRecord):
457-
"""
458-
Create and emit a suppression notice.
463+
def _report_suppression(self, rec: IssueRecord, record: logging.LogRecord) -> None:
464+
"""Create and emit a suppression notice.
459465
460466
Args:
461467
rec: The issue record with suppression count
@@ -486,8 +492,7 @@ def _report_suppression(self, rec: IssueRecord, record: logging.LogRecord):
486492

487493
@staticmethod
488494
def _format_timestamp(timestamp: float) -> str:
489-
"""
490-
Format timestamp in ISO format with microseconds.
495+
"""Format timestamp in ISO format with microseconds.
491496
492497
Args:
493498
timestamp: Unix timestamp

src/daqpytools/logging/logger.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77

88
from daqpytools.logging.exceptions import LoggerSetupError
99
from daqpytools.logging.handlers import (
10+
ThrottleFilter,
1011
add_ers_kafka_handler,
1112
add_file_handler,
1213
add_rich_handler,
1314
add_stderr_handler,
1415
add_stdout_handler,
15-
ThrottleFilter,
1616
)
1717
from daqpytools.logging.levels import logging_log_level_to_int
1818
from daqpytools.logging.utils import get_width

0 commit comments

Comments
 (0)