Build a pipeline of small generator functions that process log lines lazily (one at a time, never building lists):
read(lines): yields lines with trailing whitespace stripped, skipping blank onesparse(lines): each line is LEVEL|service|message; yield dicts with those three keys (skip lines without exactly two |)only(records, level): yield records with the given levelpipeline(lines, level): compose the threeThe pipeline must be lazy: pulling one result must not consume the whole input.