1818import sys
1919import json
2020
21- keys_to_skip = ['controller' , 'controllerGroup' , 'controllerKind' , 'reconcileID' ,
22- 'HetznerCluster' , 'Cluster' ,
23- 'namespace' , 'name' , 'Machine' , 'stack' , 'stacktrace' ,
24- 'logger' ,
25- ]
21+ keys_to_skip = [
22+ "controller" ,
23+ "controllerGroup" ,
24+ "controllerKind" ,
25+ "reconcileID" ,
26+ "HetznerCluster" ,
27+ "Cluster" ,
28+ "namespace" ,
29+ "name" ,
30+ "Machine" ,
31+ "stack" ,
32+ "stacktrace" ,
33+ "logger" ,
34+ ]
35+
36+ # Only show the name. Not a nested struct.
37+ # in: 'HCloudMachine': {'name': 'myname', 'namespace': '...'}
38+ # out:'HCloudMachine': 'myname'
39+ keys_to_name = [
40+ "HCloudMachine" ,
41+ "HCloudMachineTemplate" ,
42+ "HCloudRemediation" ,
43+ "HCloudRemediationTemplate" ,
44+ "HetznerBareMetalHost" ,
45+ "HetznerBareMetalMachine" ,
46+ "HetznerBareMetalMachineTemplate" ,
47+ "HetznerBareMetalRemediation" ,
48+ "HetznerBareMetalRemediationTemplate" ,
49+ "HetznerCluster" ,
50+ "HetznerClusterTemplate" ,
51+ ]
52+
53+ rows_to_skip_regex = [
54+ r"maxprocs: Leaving GOMAXPROCS=\d+: CPU quota undefined" ,
55+ r"^Random Seed: \d+" ,
56+ ]
57+
58+ rows_to_trigger_test_filter = ["Running Suite:" ]
2659
60+ # List of fixed-strings.
2761rows_to_skip = [
28- 'controller-runtime.webhook' , 'certwatcher/certwatcher' , 'Registering a validating webhook' ,
29- 'Registering a mutating webhook' , 'Starting EventSource' ,
30- 'Starting Controller' ,
3162 '"Starting workers" controller/controller' ,
3263 '"starting manager"' ,
3364 '"Starting metrics server"' ,
4071 '"Serving metrics server"' ,
4172 '"Starting webhook server"' ,
4273 '"Serving webhook server"' ,
43- 'attempting to acquire leader lease caph-system/hetzner.cluster.x-k8s.io.' ,
44- 'Update to resource only changes insignificant fields' ,
4574 '"approved csr"' ,
4675 '"Registering webhook"' ,
4776 '"Stopping and waiting for' ,
5079 "'statusCode': 200, 'method': 'GET', 'url': 'https://robot-ws.your-server.de" ,
5180]
5281
82+ rows_to_skip_for_tests = [
83+ "attempting to acquire leader lease caph-system/hetzner.cluster.x-k8s.io." ,
84+ "Update to resource only changes insignificant fields" ,
85+ '"Wait completed, proceeding to shutdown the manager"' ,
86+ '"starting control plane" logger="controller-runtime.test-env"' ,
87+ '"installing CRDs" logger="controller-runtime.test-env"' ,
88+ '"reading CRDs from path"' ,
89+ '"read CRDs from file"' ,
90+ '"installing CRD"' ,
91+ '"adding API in waitlist" logger="controller-runtime.test-env"' ,
92+ '"installing webhooks" logger="controller-runtime.test-env"' ,
93+ '"installing mutating webhook" logger="controller-runtime.test-env"' ,
94+ '"installing validating webhook" logger="controller-runtime.test-env"' ,
95+ 'cluster.x-k8s.io\\ ": prefer a domain-qualified finalizer' ,
96+ '"Update to resource changes significant fields, will enqueue event"' ,
97+ '"Wait for update being in local cache"' ,
98+ '"Created load balancer"' ,
99+ '"Created network with opts' ,
100+ '"Starting workers" controller="' ,
101+ '"controller-runtime.certwatcher"' ,
102+ "controller-runtime.webhook" ,
103+ "certwatcher/certwatcher" ,
104+ "Registering a validating webhook" ,
105+ "Registering a mutating webhook" ,
106+ "Starting EventSource" ,
107+ "Starting Controller" ,
108+ "Wait completed, proceeding to shutdown the manager" ,
109+ "unable to decode an event from the watch stream: context canceled" ,
110+ "client rate limiter Wait returned an error: context canceled" ,
111+ 'os-ssh-secret": context canceled' ,
112+ "http: TLS handshake error from 127.0.0.1:" ,
113+ '"Cluster infrastructure did not become ready, blocking further processing"' ,
114+ 'predicate="IgnoreInsignificant' ,
115+ '"HetznerCluster is not available yet"' ,
116+ '"Unable to write event (broadcaster is shut down)"' ,
117+ '"Unable to write event (may retry after sleeping)"' ,
118+ ]
119+
120+
53121def main ():
54122
55- if len (sys .argv ) == 1 or sys .argv [1 ] in ['-h' , '--help' ]:
56- print ('''%s [file|-]
123+ if len (sys .argv ) == 1 or sys .argv [1 ] in ["-h" , "--help" ]:
124+ print (
125+ """%s [file|-]
57126 filter the logs of caph-controller-manager.
58127 Used for debugging.
59- ''' % sys .argv [0 ])
128+ """
129+ % sys .argv [0 ]
130+ )
60131 sys .exit (1 )
61132
62- if sys .argv [1 ] == '-' :
133+ if sys .argv [1 ] == "-" :
63134 fd = sys .stdin
64135 else :
65136 fd = open (sys .argv [1 ])
@@ -68,17 +139,68 @@ def main():
68139
69140def read_logs (fd ):
70141 for line in fd :
71- handle_line (line )
142+ try :
143+ handle_line (line )
144+ except BrokenPipeError :
145+ return
146+
147+
148+ ansi_pattern = re .compile (r"\x1B\[[0-9;]*[A-Za-z]" )
149+
150+ filtering_test_data = False
151+
152+
153+ def write_line (line ):
154+ ascii_line = ansi_pattern .sub ("" , line )
155+ for r in rows_to_trigger_test_filter :
156+ if r in ascii_line :
157+ global filtering_test_data
158+ filtering_test_data = True
159+ rows_to_skip .extend (rows_to_skip_for_tests )
160+
161+ for r in rows_to_skip :
162+ if r in ascii_line :
163+ return
164+ for r in rows_to_skip_regex :
165+ if re .search (r , ascii_line ):
166+ return
167+ sys .stdout .write (line )
168+
72169
73170def handle_line (line ):
74- if not line .startswith ('{' ):
75- sys .stdout .write (line )
171+ # Extract leading dots (•) and print them on a separate line
172+ leading_dots = ""
173+ while line .startswith ("•" ):
174+ leading_dots += "•"
175+ line = line [1 :]
176+ if leading_dots :
177+ print (leading_dots )
178+ if not (line .startswith ("{" ) and line .rstrip ().endswith ("}" )):
179+ write_line (line )
180+ return
181+ try :
182+ data = json .loads (line )
183+ except json .decoder .JSONDecodeError as err :
184+ write_line ("\n " )
185+ write_line (str (err ))
186+ write_line (line )
187+ write_line ("\n " )
76188 return
77- data = json .loads (line )
78189 for key in keys_to_skip :
79190 data .pop (key , None )
80- t = data .pop ('time' , '' )
81- t = re .sub (r'^.*T(.+)*\..+$' , r'\1' , t ) # '2023-04-17T12:12:53.423Z
191+
192+ # in: 'HCloudMachine': {'name': 'myname', 'namespace': '...'}
193+ # out:'HCloudMachine': 'myname'
194+ for key in keys_to_name :
195+ value = data .get (key )
196+ if not value :
197+ continue
198+ name = value .get ("name" )
199+ if name :
200+ data [key ] = name
201+
202+ t = data .pop ("time" , "" )
203+ t = re .sub (r"^.*T(.+)*\..+$" , r"\1" , t ) # '2023-04-17T12:12:53.423Z
82204
83205 # skip too long entries
84206 for key , value in list (data .items ()):
@@ -87,20 +209,24 @@ def handle_line(line):
87209 if len (value ) > 1_000 :
88210 data [key ] = value [:1_000 ] + "...cut..."
89211
90- level = data .pop ('level' , '' ).ljust (5 )
91- file = data .pop ('file' , '' )
92- message = data .pop ('message' , '' )
93-
94- if not data :
95- data = ''
212+ level = data .pop ("level" , "" ).ljust (5 )
213+ file = data .pop ("file" , "" )
214+ message = data .pop ("message" , "" )
215+
216+ if data :
217+ values = []
218+ for key , value in data .items ():
219+ value = str (value )
220+ if any (c .isspace () for c in value ):
221+ value = f"<{ value } >"
222+ values .append (f"{ key } ={ value } " )
223+ data = " " .join (values )
224+ else :
225+ data = ""
96226
97227 new_line = f'{ t } { level } "{ message } " { file } { data } \n '
98- for r in rows_to_skip :
99- if r in new_line :
100- return
101-
102- sys .stdout .write (new_line )
228+ write_line (new_line )
103229
104230
105- if __name__ == ' __main__' :
231+ if __name__ == " __main__" :
106232 main ()
0 commit comments