11import ast
22import base64
3+ import codecs
34import json
45import os
56import re
1516from test_framework .messages import ser_uint256
1617from test_framework .p2p import MESSAGEMAP
1718
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
1920from .process import run_command
2021
2122
@@ -94,15 +95,13 @@ def grep_logs(pattern: str, show_k8s_timestamps: bool, no_sort: bool):
9495 """
9596 Grep combined bitcoind logs using regex <pattern>
9697 """
97- sclient = get_static_client ()
98-
9998 try :
10099 tanks = get_mission ("tank" )
101100 except MaxRetryError as e :
102101 print (f"{ e } " )
103102 sys .exit (1 )
104103
105- matching_logs = []
104+ matching_logs : list [ tuple [ str , any ]] = []
106105
107106 for tank in tanks :
108107 pod_name = tank .metadata .name
@@ -117,18 +116,14 @@ def grep_logs(pattern: str, show_k8s_timestamps: bool, no_sort: bool):
117116 continue
118117
119118 # 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 ))
132127
133128 # Sort logs if needed
134129 if not no_sort :
@@ -153,6 +148,22 @@ def grep_logs(pattern: str, show_k8s_timestamps: bool, no_sort: bool):
153148 return matching_logs
154149
155150
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+
156167@bitcoin .command ()
157168@click .argument ("tank_a" , type = str , required = True )
158169@click .argument ("tank_b" , type = str , required = True )
0 commit comments