in ccmlib/node.py [0:0]
def watch_log_for(self, exprs, from_mark=None, timeout=600,
process=None, verbose=False, filename='system.log',
error_on_pid_terminated=False):
"""
Watch the log until one or more (regular) expressions are found or timeouts (a
TimeoutError is then raised). On successful completion, a list of pair (line matched,
match object) is returned.
Will raise NodeError if error_on_pit_terminated is True and C* pid is not running.
"""
start = time.time()
tofind = [exprs] if isinstance(exprs, string_types) else exprs
tofind = [re.compile(e) for e in tofind]
matchings = []
reads = ""
if len(tofind) == 0:
return None
log_file = os.path.join(self.log_directory(), filename)
output_read = False
while not os.path.exists(log_file):
time.sleep(.5)
TimeoutError.raise_if_passed(start=start, timeout=timeout, node=self.name,
msg="Timed out waiting for {} to be created.".format(log_file))
if process and not output_read:
process.poll()
if process.returncode is not None:
self.print_process_output(self.name, process, verbose)
output_read = True
if process.returncode != 0:
raise RuntimeError() # Shouldn't reuse RuntimeError but I'm lazy
with open(log_file) as f:
if from_mark:
f.seek(from_mark)
while True:
# First, if we have a process to check, then check it.
# Skip on Windows - stdout/stderr is cassandra.bat
if not common.is_win() and not output_read:
if process:
process.poll()
if process.returncode is not None:
self.print_process_output(self.name, process, verbose)
output_read = True
if process.returncode != 0:
raise RuntimeError() # Shouldn't reuse RuntimeError but I'm lazy
line = f.readline()
if line:
reads = reads + line
for e in tofind:
m = e.search(line)
if m:
matchings.append((line, m))
tofind.remove(e)
if len(tofind) == 0:
return matchings[0] if isinstance(exprs, string_types) else matchings
else:
# wait for the situation to clarify, either stop or just a pause in log production
time.sleep(1)
if error_on_pid_terminated:
self.raise_node_error_if_cassandra_process_is_terminated()
TimeoutError.raise_if_passed(start=start, timeout=timeout, node=self.name,
msg="Missing: {exprs} not found in {f}:\n Head: {head}\n Tail: {tail}"
.format(
exprs=[e.pattern for e in tofind], f=filename,
head=reads[:50], tail="..."+reads[len(reads)-150:]))
# Checking "process" is tricky, as it may be itself terminated e.g. after "verbose"
# or if there is some race condition between log checking and start process finish
# so if the "error_on_pid_terminated" is requested we will give it a chance
# and will not check parent process termination
if process and not error_on_pid_terminated:
if common.is_win():
if not self.is_running():
return None
else:
process.poll()
if process.returncode == 0:
common.debug("{pid} or its child process terminated. watch_for_logs() for {l} will not continue.".format(
pid=process.pid, l=[e.pattern for e in tofind]))
return None