Skip to main content

dailylogfile

Python package for creating and managing daily log files that roll over at midnight.

This is an opinionated logger that handles the following:

  • makes one log file per day with the date added to the log file name.
  • rolls over log files at midnight.
  • optionally handles bz2 compressing older log files.
  • optionally handles aging off of really old log files.

Installation

Install from pypi via:

pip install dailylogfile

Usage

The most basic usage is to import setup_daily_logger and use the arguments to configure the logger.

from dailylogfile import setup_daily_logger

logger = setup_daily_logger('/data/logs/MyProject.log')
logger.info('Logger initialized')

The following arguments are supported by setup_daily_logger and are passed to the DailyLogFileHandler class initiator:

  • logfile: log file path to pass to the DailyLogFileHanlder, passing None logs to stdout.
  • date_format: the date format to add to the logfile name (default = '%Y-%m-%d').
  • date_sep: the separator to use between the logfile prefix and date (default = '_').
  • compress_after_days: files older than this many days are bz2 compressed, use None to disable (default = 2).
  • max_history_days: files older than this many days are removed, use None to disable (default = 30).
  • logger_name: name of the logger, None uses the stem of the log file as the logger name (default = None).
  • logger_level: log level to set for the logger (default = logging.INFO).
  • logger_format: log format to use when writting (default = '[%(asctime)s] %(levelname)s - %(message)s').
  • logger_date_format: date format to use in the log messages (default = '%Y-%m-%d %H:%M:%S').
  • mode: mode to use when opening logfile (default = 'a').
  • encoding: text encoding to use when writing (default = None).
  • delay: whether file opening is deferred until the first emit() (default = False).
  • errors: determines how encoding errors are handled (default = None).
  • file_permission: permissions to set for the logs (default=0o640).

Details

This is how the DailyLogFileHandler handles files under the hood.

File name templating

The logfile names are generated using a template.

logfile

The logfile argument NOT where the log file will be written. It is parsed and then included in the tamplate when creating the log file name. If a file extension is present, it will be used, otherwise '.log' is used. The log file names are formatted something like: /data/logs/MyProject_2025-08-22.log.

date_format

The format of the date appended to the logfile name is controlled using date_format. See the Python docs on time code formats for my information. Note: the current date is used when generating logfile names, not the datetime, i.e. hours, minutes, and seconds are all zeros.

date_sep

This is the string used to join the logfile name with the date string. Avoid using % here as it could cause the parsing for date strings to fail.

File rollover

If a script is running the logger or when logger is instantiated, it will check if a rollover needs to be run. During rollover, the logger will look for files in the log directory that match the log file naming scheme and optionally compress and/or age-off log files.

compress_after_days

During rollover, matching files older than this number of days will be compressed using bz2 compression. If compress_after_days is None or zero, this is disabled.

max_history_days

During rollover, matching files older than this number of days will be removed. If max_history_days is None or zero, this is disabled.

Detailed Example

This is an example with all options explained:

from dailylogfile import setup_daily_logger

logger = setup_daily_logger(
    logfile='/data/logs/MyProject.zzz,
    date_format='%Y-%m-%d',
    date_sep='___',
    compress_after_days=1,
    max_history_days=4,
    logger_name = None,
    logger_level=logging.INFO,
    logger_format='[%(asctime)s] %(levelname)s - %(message)s',
    logger_date_format='%Y-%m-%d %H:%M:%S',
    mode='a',
    encoding=None,
    delay=False,
    errors=None,
    file_permission=0o640,
)

The arguments logfile='/data/logs/MyProject.zzz, date_format='%Y-%m-%d', and date_sep='___' will set the log name template to be /data/logs/MyProject___YYYY-MM-DD.zzz, e.g. the log files would be:

/data/logs/MyProject___2025-08-23.zzz
/data/logs/MyProject___2025-08-24.zzz

The next arguments: compress_after_days=1 and max_history_days=4 will cause log files older than 1 day to compress and older than 4 days to be deleted. On 2025-08-25, the log files would be:

# 2025-08-25 log files:
/data/logs/MyProject___2025-08-23.zzz.bz2
/data/logs/MyProject___2025-08-24.zzz            # 1 day old
/data/logs/MyProject___2025-08-25.zzz            # today, 0 days old

And on 2025-08-27 the previously .zzz log files have been compressed:

# 2025-08-27 log files:
/data/logs/MyProject___2025-08-23.zzz.bz2
/data/logs/MyProject___2025-08-24.zzz.bz2
/data/logs/MyProject___2025-08-25.zzz.bz2
/data/logs/MyProject___2025-08-26.zzz
/data/logs/MyProject___2025-08-27.zzz

When the date moves from 2025-08-27 to 2025-08-28, the oldest log file will be aged off:

# 2025-08-28 log files:
/data/logs/MyProject___2025-08-24.zzz.bz2
/data/logs/MyProject___2025-08-25.zzz.bz2
/data/logs/MyProject___2025-08-26.zzz.bz2
/data/logs/MyProject___2025-08-27.zzz
/data/logs/MyProject___2025-08-28.zzz

The argument logger_name = None will use the logfile name as the logger name, setting it to 'MyProject'. This allows you to get the logger via:

import logging
logging.getLogger('MyProject')

The next arguments: logger_level=logging.INFO, logger_format='[%(asctime)s] %(levelname)s - %(message)s', and logger_date_format='%Y-%m-%d %H:%M:%S' set the logger level for this logger to INFO, set the logger format, and datetime format for %(asctime)s.

The arguments: mode='a', encoding=None, delay=False, and errors=None are the passed to the super class logging.FileHandler. They control the file mode, file encoding, delayed file creation, and how encoding errors are handled.

The final argument is used to set file permissions when creating adding the log file.

Metadata

Release files for dailylogfile 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dailylogfile 0.3.1
File Size Uploaded Provenance Actions
dailylogfile-0.3.1.tar.gz 8.8 kB Without provenance Details for dailylogfile-0.3.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for dailylogfile 0.3.1
File Interpreter ABI Platform Actions
dailylogfile-0.3.1-py3-none-any.whl Python 3 none any Details for dailylogfile-0.3.1-py3-none-any.whl

Total release size: 16.1 kB

Release files / dailylogfile-0.3.1.tar.gz

Download URL dailylogfile-0.3.1.tar.gz
Size 8.8 kB
Tags Source
SHA-256 checksum
How to use checksums
2de7b06c0503ff6b73507e08d34be04ab795224caf7e11e4aabf8dd73f547f35
BLAKE2b-256 checksum
How to use checksums
65e227d5a3547619f10cd699e75c99f12f14fc52029624f8c0264c6020f37a92
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.0.1 CPython/3.11.13

Release files / dailylogfile-0.3.1-py3-none-any.whl

Download URL dailylogfile-0.3.1-py3-none-any.whl
Size 7.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
41e96c5c631ac904de335537addb98403089b2226e0c743b02a44cb71ae8edb6
BLAKE2b-256 checksum
How to use checksums
50dc51b98b1116ea42780ab914d345e151805010b79a359884fd768ecf0debcf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.0.1 CPython/3.11.13

Security for dailylogfile 0.3.1

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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page