The ultimate rotation and windows friendly log tailer plus a lot more…
backfills rotated files
handles gz and bz2 files
handles multi line records
doesn’t break windows rotating log handlers
easy to extend
Free software: BSD license
other than six pure Python stdlib.
Installation
pip install tailchaser
Thsi will install the tailchaser library in your site-packages and it will also add the script tailchase to your Scripts directory.
Usage
$ tailchase /where/my/logs/*.log
$ tailchase -h
usage: tailchase [-h] [--only-backfill] [--dont-backfill]
[--clear-checkpoint] [--read-period READ_PERIOD]
[--read-pause READ_PAUSE] [--reading-from {unix,win}]
[--temp-dir TEMP_DIR]
[--logging {DEBUG,INFO,WARN,ERROR,CRITICAL}]
file-pattern
positional arguments:
file-pattern The file pattern to tail, such as /var/log/access.*
optional arguments:
-h, --help show this help message and exit
--only-backfill dont't tail, default: False
--dont-backfill basically only tail, default: False
--clear-checkpoint start form the begining, default: False
--read-period READ_PERIOD
how long you read before you pause. If zero you don't
pause, default: 1
--read-pause READ_PAUSE
how long you pause between reads, default: 0
--reading-from PLATFORM
sets how long you read and then pause can be one of {unix,win}, default: win
--temp-dir TEMP_DIR on back fill files are copied to a temp directory.Use
this to set this directory, default: None
--logging LEVEL
logging level it can be one of DEBUG,INFO,WARN,ERROR,CRITICAL, default: ERROR
In its simplest form
In its simplest form tailchase works like a combination of cat and tail -f except it will start with the oldest rotated file. So if you were to have
/var/log/opendirectoryd.log /var/log/opendirectoryd.log.0 /var/log/opendirectoryd.log.1 /var/log/opendirectoryd.log.2 /var/log/opendirectoryd.log.3 /var/log/opendirectoryd.log.4
it would first output the text of /var/log/opendirectoryd.log.4, then /var/log/opendirectoryd.log.3, etc. until it reached the newest file then when it has reached the end of /var/log/opendirectoryd.log revert to a “tail -f” behaviour.
So if you were to do
tailchase 'tests/logs/opendirectoryd.*'
“note: In bash you need to quote the wildcard otherwise it will be expanded into the scripts argv array.”
you would get something like
2015-12-24 15:39:56.733754 EST - AID: 0x0000000000000000 - Registered node with name '/Contacts' 2015-12-24 15:39:56.733933 EST - AID: 0x0000000000000000 - Registered node with name '/LDAPv3' as hidden 2015-12-24 15:39:56.736154 EST - AID: 0x0000000000000000 - Registered node with name '/Local' as hidden 2015-12-24 15:39:56.736868 EST - AID: 0x0000000000000000 - Registered node with name '/NIS' as hidden 2015-12-24 15:39:56.737134 EST - AID: 0x0000000000000000 - Discovered configuration for node name '/Search' at path ' 2015-12-24 15:39:56.737151 EST - AID: 0x0000000000000000 - Registered node with name '/Search' 2015-12-24 15:39:56.738794 EST - AID: 0x0000000000000000 - Loaded bundle at path '/System/Library/OpenDirectory/Modules 2015-12-24 15:39:56.740509 EST - AID: 0x0000000000000000 - Loaded bundle at path '/System/Library/OpenDirectory/Modules/
Coding with tailchaser
Using the tailchaser library in a project is probably best done by example.
Example 1 - Tailchase to a REST service.
#
# Example 1 - Tail to Elastic
#
import requests
import tailchaser
class TailToElastic(tailchaser.Tailer):
def handoff(self, file_tailed, checkpoint, record):
""" Expect a record like:
20160204 10:28:15,525 INFO PropertiesLoaderSupport - Loading properties file from URL [file:C:/WaterWorks/Broken/BSE//config/lme-market.properties]
20160204 10:28:15,541 INFO PropertiesLoaderSupport - Loading properties file from URL [file:C:/WaterWorks/Broken/BSE//config/default-database.properties]
20160204 10:28:15,541 INFO PropertiesLoaderSupport - Loading properties file from URL [file:C:/WaterWorks/Broken/BSE//config/default-hibernate.properties]
"""
date, time, level, source, _, message = record.split(5)
result = requests.json("http://someelacticserver.com:9200/myindex/log", json={
'timestamp': '{}T{}'.format(date, time)
'level': level,
'source': source,
'message': message
})
return result.status_code == requests.codes.ok
Example 2 - Tailchase to Kafka
#
# Example 2 - Tail to Kafka - shows how to add your own arguments and then send messages to kafka.
#
from kafka import KafkaProducer
rom tailchaser.tailer import Tailer
class TailToKafka(Tailer):
def add_arguments(cls, parser=None):
parser = super(TailToKafka, cls).add_arguments(parser)
HOSTS = 'localhost:1234'
TOPIC = b'log'
def startup(self):
self.kafka_producer = KafkaProducer(bootstrap_servers=self.HOSTS,value_serializer=msgpack.dumps)
def handoff(self, file_tailed, checkpoint, record):
""" Expect a record like:
20160204 10:28:15,525 INFO PropertiesLoaderSupport - Loading properties file from URL [file:C:/WaterWorks/Broken/BSE//config/lme-market.properties]
20160204 10:28:15,541 INFO PropertiesLoaderSupport - Loading properties file from URL [file:C:/WaterWorks/Broken/BSE//config/default-database.properties]
20160204 10:28:15,541 INFO PropertiesLoaderSupport - Loading properties file from URL [file:C:/WaterWorks/Broken/BSE//config/default-hibernate.properties]
"""
self.kafka_producer.send(self.TOPIC, record).get(timeout=10)
return True
Example 3 - Saving and Loading last Offset from Zookeeper
#
# Example 3 - Saving and Loading last Offset from Zookeeper
#
import platform
import pickle
import six
from kazoo.client import KazooClient
from tailchaser.tailer import Tailer
class TailToElastic(Tailer):
def start(self):
self.zk = KazooClient(hosts=self.config.zookeeper_host)
self.zk.start()
def stop():
self.zk.stop()
def load_checkpoint(self):
zk_path = self.config.checkpoint_filename
try:
checkpoint = pickle.loads(self.zk.get(zk_path))
log.debug('loaded: %s %s', zk_path, checkpoint)
return checkpoint
except (IOError, EOFError):
log.debug('failed to load: %s', zk_path)
return self.INIT_CHECKPOINT
def save_checkpoint(self, checkpoint):
log.debug('dumping %s %s', self.config.checkpoint_filename, checkpoint)
return self.zk.set(self.config.checkpoint_filename, six.b(pickle.dumps(checkpoint)))
@staticmethod
def make_checkpoint_filename(source_pattern, path=None):
zk_path = '/'.join(['tailchase', platform.node(), slugify(source_pattern)]
self.zk.ensure_path(zk_path)
return zk_path
Documentation
Development
To run the all tests run:
tox
Note, to combine the coverage data from all the tox environments run:
Windows |
set PYTEST_ADDOPTS=--cov-append tox |
|---|---|
Other |
PYTEST_ADDOPTS=--cov-append tox |
Changelog
0.2.7 (2016-07-24)
added –filter-re to filter out lines #15
0.2.1 (2016-04-30)
Fixed #12 where Handoff is getting the tmp file name…
removed temp files after handoff #14
0.2.0 (2016-04-30)
Added pipe code from ilabs code base.
Added example of storing check points remotely #8
Added REST configuration #9
Added INIT_CHECKPOINT class attribute to Tailer #11
0.1.3 (2016-04-12)
Added break tail tests and fixes drived from it - #6
fixed app description ! - #7
0.1.2 (2016-04-05)
Add multi-line record support - #3
add –start-of-record-re option for multi-line records. - #4
move argparser definition from cli to Tailer class. - #5
0.1.0 (2016-02-21)
First release on PyPI.
Metadata
Release files for tailchaser 0.2.8
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distributions (sdists)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| tailchaser-0.2.8.tar.gz | 29.5 kB | Without provenance | Details for tailchaser-0.2.8.tar.gz | |
| tailchaser-0.2.8.linux-x86_64.tar.gz | 18.7 kB | Without provenance | Details for tailchaser-0.2.8.linux-x86_64.tar.gz |
Release files / tailchaser-0.2.8.tar.gz
| Download URL | tailchaser-0.2.8.tar.gz |
|---|---|
| Size | 29.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
aa1034014ac885813efd1a4810e60778b5a4a1ef0d6b934c43e6c5944fb1d3f4
|
|
BLAKE2b-256 checksum How to use checksums |
b7604532b95f070077b04981acdc060e8058f56d7057f19ce33e7fe20f2ff890
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
Release files / tailchaser-0.2.8.linux-x86_64.tar.gz
| Download URL | tailchaser-0.2.8.linux-x86_64.tar.gz |
|---|---|
| Size | 18.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ab3047ebe603182b68aeafbd0e8a14e818565a80b8aac0a6856e907354e5115d
|
|
BLAKE2b-256 checksum How to use checksums |
6aec9a17ab9ddedec0a792dcda66ee643fa224e00adcd2911c3a51d14c2834d8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
Security for tailchaser 0.2.8
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.