>>> import itertools
>>> import io
>>>
>>> text = """\
... [2018-05-17 11:30:58.873687] NOK
... [2018-05-17 11:30:58.873687] OK
... [2018-05-17 11:30:59.873687] NOK
... [2018-05-17 11:31:29.873687] OK
... [2018-05-17 11:31:41.873687] NOK
... [2818-05-17 11:32:13.873687] OK
... [2818-05-17 11:32:27.873687] OK
... [2918-05-17 11:32:29.873687] OK
... [2818-05-17 11:33:11.873687] NOK
... [2218-05-17 11:33:48.873687] OK
... [2818-05-17 11:34:16.873687] OK
... [2218-05-17 11:34:58.873687] NDK
... [2018-05-17 11:35.34.873687] OK"""
>>>
>>> ifp = io.StringIO(text)
>>>
>>> filtered_stream = (i for i in ifp if i.endswith('NOK\n'))
>>> groups = itertools.groupby(filtered_stream, key=lambda i: i[1:17])
>>> for key, grp in groups:
... print(key, len(tuple(grp)))
...
2018-05-17 11:30 2
2018-05-17 11:31 1
2818-05-17 11:33 1
>>>
vladimir_vl_vlad
Проблема в том, что мое решение не учитывает самую последнюю строку файла
Там надо полноценный конечный автомат делать. Для этого делается цикл while, а чтение производится через функцию next().
Можно, конечно, и через for сделать, но тогда там надо и до цикла производить действия, и после цикла производить действия, чтобы не пытаться искать что-то в пустом или однострочном файле и чтобы если файл закончился внезапно, вывести на экран то, что было подсчитано в последних строках, пока они читались и не выводились.