Renamed a method for clarity.
Refactored and tested run().
Moved seeking-related methods down in the file.
Replaced magic numbers with constants.

This speeds up unit tests by 0.2 seconds, since NO_ENTRIES_SLEEP_INTERVAL can be set to 0 for unit testing.

Also, unit tests set the reader's chunk size now to the expected value where relevant, to ensure the tests test what they are supposed to tests even if the default chunk size changes.
Some comments.
Fixed -tn0.

Previously, specifiying a tail length of zero would seek to the beginning of the file. It now seeks to the end of the file instead.
Some more gratuitous renaming.
Unbroke --grep.

Also added unit tests for LogFilter. The logreader module is now at 100% test coverage. \o/
The program terminates now if no Redis connection can be established.

(Also, fixed improper FakeLogging cleanup in the tests.)
Light refactoring of RedisOutputThread.run().
Miscellaneous tests.
Fixed file/logfile confusion in the tests.
Moved adding the logfile into as_logstash().
Renamed LogEntryFields.

The names are now consistent with the rest of the program, and there is no more confusion whether fid is the ID of the logfile or the reader, or whether file is the logfile or the source file.

The keys in the JSON dict pushed to Redis remain unaltered, of course.
Gave LogEntry __slots__ = ().

This should save a couple hundred bytes per instance, and we might create a whole bunch of 'em.
Got rid of the whole RedisOutputThread._connect() thing.

Turns out, this is completely pointless. The redis module will happily create a pipeline even if Redis is offline, and that pipeline will start working once it comes back online.
Got rid of RedisOutputThread._import_redis() too.
Failure to connect to Redis no longer causes entries to be dropped.
Some refactoring of the log aggregators.
Some quick test cleanup.