JJustLog3 Cloud
Start free

Docs / Libraries

Python

Install the justlog3 package, log to a file and to the cloud, levels, batching and shutdown behaviour.

The justlog3 package writes log lines to a file in batches and, once you set an API token, sends them to JustLog3 Cloud from a background thread. log() never waits for the disk or the network.

Install

pip install justlog3

Python 3.8 or newer. httpx, used for cloud sending, is installed with the package. Source and benchmarks: github.com/OAzizjon/justlog3.

Log to a file

from justlog3 import Logger

logger = Logger('app.log')

logger.log('Hi...')
logger.log('debug', off_console=True)
logger.log('There is some error!', red=True)
logger.log('OK', green=True)
logger.log('There is critical error!', red=True, custom_prefix='CRITICAL!!')

The console shows colored lines; app.log gets one line per call with a prefix and a local timestamp with milliseconds:

GREY:2026-10-05 14:03:12.517 - Hi...
RED:2026-10-05 14:03:12.518 - There is some error!
GREEN:2026-10-05 14:03:12.518 - OK

Send to JustLog3 Cloud

import os
from justlog3 import Logger, set_api_token

set_api_token(os.environ['JUSTLOG3_TOKEN'], url='https://jl3-cloud.site/api/logs/')
logger = Logger('app.log')
logger.log('This line goes to the file and to the cloud')

Call set_api_token() once, before or after creating loggers. Keep the token in an environment variable rather than in code.

  • Lines are sent every flush_interval seconds (default 5), or sooner once cloud_cycles lines (default 75) are waiting.
  • A request carries at most 5,000 lines and 512 KB of text; bodies from 1 KB are gzip-compressed.
  • Each logger keeps up to 10,000 unsent lines; beyond that the oldest are dropped with a single warning.
  • No answer or HTTP 5xx: the batch is resent with the same sequence number, so the server stores it once. The wait starts at 5 s and doubles up to 5 minutes.
  • HTTP 429: nothing is sent until Retry-After; lines stay buffered.
  • HTTP 401 / 403: cloud sending stops, files keep being written. Call set_api_token() again with a valid token.
  • On exit the remaining lines are sent, waiting at most timeout seconds.

set_api_token(token, *, url=..., flush_interval=5.0, timeout=5.0) raises ValueError for an empty token.

Levels

from justlog3 import BasicLogger

logger = BasicLogger('app.log', console_level='INFO')
logger.debug('cache warmed')         # file and cloud only: below INFO
logger.info('server started')
logger.warning('disk 85% full')
logger.error('payment failed')
logger.critical('database is down')

console_level only filters the console. Every line still goes to the file and the cloud.

Shutdown and signals

  • Normal exit: every logger is flushed by an atexit hook.
  • SIGTERM (docker stop, systemd, kill): JustLog3 turns the signal into a normal exit so the flush runs. Call off_signal_handler() before creating any logger to keep your own handler.
  • kill -9 or a power cut loses what is still in the buffer: at most cycles - 1 lines (default 49).
  • Call shutdown() yourself before os._exit().

Logger options

Parameter Default Meaning
filename 'app.log' .log is added if missing
with_time True timestamp in every line
filemode 'a' 'w' empties the file once, on creation
cycles 50 lines per disk write
cloud_cycles 75 waiting lines that wake the cloud sender
off_sigmask False don't hold back SIGTERM during writes (Linux, macOS)