Skip to main content
https://pepy.tech/badge/ntlog/month https://github.com/KenKundert/ntlog/actions/workflows/build.yaml/badge.svg https://coveralls.io/repos/github/KenKundert/ntlog/badge.svg?branch=main https://img.shields.io/pypi/v/ntlog.svg https://img.shields.io/pypi/pyversions/ntlog.svg
Author:

Ken Kundert

Version:

1.2

Released:

2026-06-28

Command-Line Application

ntLog is a simple command line utility used to append discretely generated log files into a running log formulated as a NestedText file. You can specify limits on how many log entries there are or how old they should be. Any entries that do not satisfy the limits are purged.

A discrete log file is a log file generated by program that runs at regular intervals or after particular events. This contrasts from log files generated by continuously running programs such as daemons. With discretely running programs a existing log file will be overwritten on the next run. By using ntLog you can add the most recently generated log file to a running log that will not be overwritten.

Usage:

    ntlog [options] <logfile>

Options:

    -k, --keep-for [days]     drop entries older than this [default: 7]
    -n, --max-entries [N]     maximum number of log entries to keep
    -N, --min-entries [N]     minimum number of log entries to keep [default: 1]
    -d, --delete              delete given logfile after incorporating it
    -h, --help                print this usage message
    -Y, --year <fmt>          add year headers
    -M, --month <fmt>         add month headers
    -D, --day <fmt>           add day headers
    -H, --hour <fmt>          add hour headers
    -E, --entry <fmt>         add entry headers
    -d, --description <text>  add entry headers
    --fold-marker <mapping>   map fold markers contained in logfile
    -e, --editor <editor>     add editor mode line, choose from: vim

When run, ntLog copies the contents of <logfile> into <logfile>.nt.

Log entries older than --keep-for days are deleted. If units are not specified, --keep-for is given in days. However you can directly specify the units in terms of seconds (s, sec, second, seconds), minutes (m, min, minute, minutes), hours (h, hr, hour, hours), days (d, day, days), weeks (w, W, week, weeks), months (M, month, months), and years (y, Y, year, years).

If the number of entries exceeds --max-entries, the oldest entries are deleted even if they are younger than the --keep-for limit.

If --delete is specified, the given log file is deleted after its contents are incorporated into the running log file.

The key used when filing log entries into the NestedText document is the timestamp of the modification time of the given log file.

The given log file is always kept, even if it is older than the --keep-for limit.

Log entries are sorted from most recent to oldest, with the most recent at the top of the NestedText file. The one exception to this rule is that the given log file is always listed first, even if its modification time is older than existing log entries.

Headers

Any headers you specify are added as comments above the appropriate entries. When a year header is specified, it is added before the first entry found from new year. The same is true for month, day, and hour headers. The entry header it given before each entry. An entry is treated as an Arrow format. It consists of tokens that are to be replaced by components from the entry date stamp. For example, if you specify:

--entry 'D MMMM YYYY, h:mm A'

Then you will get a entry header command that looks like this:

# 31 December 2023, 6:00 PM
2023-12-31T18:00:25.680009-08:00:
    > ...

If you specify a description, it will be prepended to the datestamp in the key for the new log entry and will be prepended to the entry header. For example, if --description create were specified, the result might look like:

# create — 31 December 2023, 6:00 PM
create — 2023-12-31T18:00:25.680009-08:00:
    > ...

It is attractive to include editor fold markers in the headers. In doing so you can collapse large log entries into a single line folds until they are needed, at which point you can easily open the fold and examine the contents of the log file. Here is an example set of header specifications that include Vim fold markers:

--year 'YYYY  {{{1'
--month 'MMMM YYYY  {{{2'
--day 'D MMMM YYYY  {{{3'
--entry 'D MMMM YYYY, h:mm A  {{{4'

If your logfiles tend to include fold markers, they can confuse the folds. You can prevent this by mapping the marker into a different string. Use --fold-marker:

--fold-marker '{{{ {<{'

NTlog API

ntLog provides the NTlog class, whose instances can be used as an output file stream in Python programs. Instead of writing to stand-alone files their output is incorporated directly into a NestedText composite logfile.

NTlog provides the normal methods for output file streams, write, flush and close, and can act as a context manager. Only write takes an argument, the text to be written to the logfile.

NTlog Arguments:
running_log_file: (str, os.PathLike):

The path to the composite log file. Normally this uses .log.nt as the suffix. If not given, then the name of the temp_log_file with an added .nt suffix is used.

temp_log_file: (str, os.PathLike):

The path to the temporary log file. Normally this uses .log as the suffix. This is optional.

keep_for (float, str):

Any entries older than keep_for (in seconds) are dropped. If keep_for is a string, it is converted to seconds. In this case it assumed to be a number followed by a unit. For example, ‘1w’, ‘6M’, etc.

max_entries (int):

Maximum number of log entries to keep.

min_entries (int):

Minimum number of log entries to keep.

retain_temp (bool):

Do not delete the temporary log file after writing composite log file.

ctime (datetime):

Used as the creation time of the log entry. If not specified, the current time is used.

year_header (str):

When specified, this header is added above the first entry from a new year.

month_header (str):

When specified, this header is added above the first entry from a new month.

day_header (str):

When specified, this header is added above the first entry from a new day.

hour_header (str):

When specified, this header is added above the first entry from a new hour.

entry_header (str):

When specified, this header is added above every entry.

description (str):

This string is prepended to the datestamp to create the key for the new log entry. It is also prepended to the entry header, if it is requested.

fold_marker_mapping ([str, str]):

When specified, any instances of the first string in a log file are replaced by the second string when incorporating that log into the output NestedText file.

Raises:

OSError, NTlogError

NTlogError is a clone of the Error exception from Inform.

The use of the temp_log_file is optional. It is helpful with long running processes as it provides a way of monitoring the progress of the process, especially if the logfile is routinely flushed.

Example (with error reporting):

from ntlog import NTlog, NTlogError
from inform import Inform, fatal, os_error

try:
    with NTlog('appname.log.nt', keep_for='7d', max_entries=20):
        ntlog.write('a log message')
        ntlog.write('another log message')
        ...
except OSError as e:
    fatal(os_error(e))
except NTlogError as e:
    e.terminate()

Example (with temp log):

with NTlog('appname.log.nt', 'appname.log', keep_for='7d', retain_temp=True):
    ntlog.write('log message')
    ntlog.flush()
    ...

NTlog can be specified as the logfile to Inform.

Example (with inform):

from ntlog import NTlog
from inform import Inform, display, error, log

with (
    NTlog('appname.log.nt', keep_for='7d') as ntlog,
    Inform(logfile=ntlog) as inform,
):
    display('status message')
    log('log message')
    if there_is_a_problem:
        error('error message')
    ...

Example (with temp log and inform):

with (
    NTlog('appname.log.nt', 'appname.log', keep_for='7d') as ntlog,
    Inform(logfile=ntlog, flush=True) as inform,
):
    display('status message')
    log('log message')
    if there_is_a_problem:
        error('error message')
    ...

Installation

Install with:

pip install ntlog

Release files for ntlog 1.2

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

Source distribution (sdist)

Source distribution for ntlog 1.2
File Size Uploaded
ntlog-1.2.tar.gz 11.2 kB Details

Built distribution (wheel)

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

Total release size: 22.8 kB

Release files / ntlog-1.2.tar.gz

Download URL ntlog-1.2.tar.gz
Size 11.2 kB
Tags Source
SHA-256 checksum
How to use checksums
39b856ef268ff3c40b4362b6e2742abc561ba7c2fc799d685e802e88f6e83436
BLAKE2b-256 checksum
How to use checksums
8f82b4a42e23e056cd0833cd12c4bdc97e18bb66dfd680c87b4264ec1aad2578
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.5

Release files / ntlog-1.2-py3-none-any.whl

Download URL ntlog-1.2-py3-none-any.whl
Size 11.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
400fed98aff5ef23f0f85b8bfedc061de73f9ee17eea17aa2ee9de8e44a51ed7
BLAKE2b-256 checksum
How to use checksums
43b8c0ba5bcec46cf92f087f3ef1eca806aa0c06ef75431c8857e408d30291ad
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.5

Release history Release notifications | RSS feed

This release

1.2 This release

2 release files

1.1

2 release files

1.0

2 release files

0.5

2 release files

0.3

2 release files

0.2

2 release files

0.1

2 release files

0.0

2 release files

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