1
1
import ast
2
2
import base64
3
+ import codecs
3
4
import json
4
5
import os
5
6
import re
15
16
from test_framework .messages import ser_uint256
16
17
from test_framework .p2p import MESSAGEMAP
17
18
18
- from .k8s import get_default_namespace , get_mission , get_static_client , kexec
19
+ from .k8s import get_default_namespace , get_mission , get_static_client , kexec , pod_log
19
20
from .process import run_command
20
21
21
22
@@ -94,15 +95,13 @@ def grep_logs(pattern: str, show_k8s_timestamps: bool, no_sort: bool):
94
95
"""
95
96
Grep combined bitcoind logs using regex <pattern>
96
97
"""
97
- sclient = get_static_client ()
98
-
99
98
try :
100
99
tanks = get_mission ("tank" )
101
100
except MaxRetryError as e :
102
101
print (f"{ e } " )
103
102
sys .exit (1 )
104
103
105
- matching_logs = []
104
+ matching_logs : list [ tuple [ str , any ]] = []
106
105
107
106
for tank in tanks :
108
107
pod_name = tank .metadata .name
@@ -117,18 +116,14 @@ def grep_logs(pattern: str, show_k8s_timestamps: bool, no_sort: bool):
117
116
continue
118
117
119
118
# Get logs from the specific container
120
- logs = sclient .read_namespaced_pod_log (
121
- name = pod_name ,
122
- namespace = get_default_namespace (),
123
- container = container_name ,
124
- timestamps = True ,
125
- )
126
-
127
- if logs is not False :
128
- # Process logs
129
- for log_entry in logs .splitlines ():
130
- if re .search (pattern , log_entry ):
131
- matching_logs .append ((log_entry , pod_name ))
119
+ log_stream = pod_log (pod_name , container_name , timestamps = True )
120
+
121
+ compiled_pattern = re .compile (pattern )
122
+
123
+ for log_line in iter_lines_from_stream (log_stream ):
124
+ log_entry = log_line .rstrip ("\n " )
125
+ if compiled_pattern .search (log_entry ):
126
+ matching_logs .append ((log_entry , pod_name ))
132
127
133
128
# Sort logs if needed
134
129
if not no_sort :
@@ -153,6 +148,22 @@ def grep_logs(pattern: str, show_k8s_timestamps: bool, no_sort: bool):
153
148
return matching_logs
154
149
155
150
151
+ def iter_lines_from_stream (log_stream , encoding = "utf-8" ):
152
+ decoder = codecs .getincrementaldecoder (encoding )()
153
+ buffer = ""
154
+ for chunk in log_stream .stream ():
155
+ # Decode the chunk incrementally
156
+ text = decoder .decode (chunk )
157
+ buffer += text
158
+ # Split the buffer into lines
159
+ lines = buffer .split ("\n " )
160
+ buffer = lines .pop () # Last item is incomplete line or empty
161
+ yield from lines
162
+ # Yield any remaining text in the buffer
163
+ if buffer :
164
+ yield buffer
165
+
166
+
156
167
@bitcoin .command ()
157
168
@click .argument ("tank_a" , type = str , required = True )
158
169
@click .argument ("tank_b" , type = str , required = True )
0 commit comments