1
+ import logging
2
+ import pytest
3
+
4
+ from nodestream .logging_metrics import MetricsLoggingHandler
5
+ from nodestream .metrics import (
6
+ LOG_DEBUG_COUNT ,
7
+ LOG_ERROR_COUNT ,
8
+ LOG_INFO_COUNT ,
9
+ LOG_WARNING_COUNT ,
10
+ Metrics ,
11
+ ConsoleMetricHandler ,
12
+ )
13
+
14
+
15
+ class CapturingConsoleHandler (ConsoleMetricHandler ):
16
+ """Console handler that exposes its internal metrics for assertions."""
17
+
18
+ def discharge (self ):
19
+ # Override to not reset metrics so we can assert after logging
20
+ return {metric .name : value for metric , value in self .metrics .items ()}
21
+
22
+
23
+ @pytest .fixture
24
+ def metrics ():
25
+ # Use a capturing console handler to observe metric values
26
+ handler = CapturingConsoleHandler (command = None ) # command is not used
27
+ with Metrics .capture (handler ) as metrics :
28
+ yield metrics
29
+
30
+
31
+ def test_metrics_logging_handler_increments_error (metrics ):
32
+ logger = logging .getLogger ("test_logger_error" )
33
+ logger .setLevel (logging .DEBUG )
34
+
35
+ handler = MetricsLoggingHandler (metrics )
36
+ logger .addHandler (handler )
37
+
38
+ logger .error ("error message" )
39
+
40
+ # Verify metric incremented
41
+ values = metrics .handler .discharge ()
42
+ assert values .get (LOG_ERROR_COUNT .name , 0 ) == 1
43
+
44
+
45
+ def test_metrics_logging_handler_increments_warning (metrics ):
46
+ logger = logging .getLogger ("test_logger_warning" )
47
+ logger .setLevel (logging .DEBUG )
48
+
49
+ handler = MetricsLoggingHandler (metrics )
50
+ logger .addHandler (handler )
51
+
52
+ logger .warning ("warning message" )
53
+
54
+ values = metrics .handler .discharge ()
55
+ assert values .get (LOG_WARNING_COUNT .name , 0 ) == 1
56
+
57
+
58
+ def test_metrics_logging_handler_increments_info (metrics ):
59
+ logger = logging .getLogger ("test_logger_info" )
60
+ logger .setLevel (logging .DEBUG )
61
+
62
+ handler = MetricsLoggingHandler (metrics )
63
+ logger .addHandler (handler )
64
+
65
+ logger .info ("info message" )
66
+
67
+ values = metrics .handler .discharge ()
68
+ assert values .get (LOG_INFO_COUNT .name , 0 ) == 1
69
+
70
+
71
+ def test_metrics_logging_handler_increments_debug (metrics ):
72
+ logger = logging .getLogger ("test_logger_debug" )
73
+ logger .setLevel (logging .DEBUG )
74
+
75
+ handler = MetricsLoggingHandler (metrics )
76
+ logger .addHandler (handler )
77
+
78
+ logger .debug ("debug message" )
79
+
80
+ values = metrics .handler .discharge ()
81
+ assert values .get (LOG_DEBUG_COUNT .name , 0 ) == 1
82
+
83
+
84
+ def test_root_logger_handler_increments_for_distinct_logger (metrics ):
85
+ """Attaching handler to root should capture records from a distinct logger."""
86
+ root_logger = logging .getLogger ()
87
+ original_level = root_logger .level
88
+ handler = MetricsLoggingHandler (metrics )
89
+ try :
90
+ root_logger .setLevel (logging .DEBUG )
91
+ root_logger .addHandler (handler )
92
+
93
+ distinct_logger = logging .getLogger ("distinct.logger.name" )
94
+ distinct_logger .warning ("root handler should capture this warning" )
95
+
96
+ values = metrics .handler .discharge ()
97
+ assert values .get (LOG_WARNING_COUNT .name , 0 ) == 1
98
+ finally :
99
+ root_logger .removeHandler (handler )
100
+ root_logger .setLevel (original_level )
0 commit comments