def watch_log_for()

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