Skip to main content

A lightweight, zero-setup decorator for logging ML experiments to a JSONL file.

Project description

LittleLogger Logo
A lightweight, zero-setup decorator for logging ML experiments to a JSONL file.

This tool is for the solo data scientist, student, or hobbyist in a Jupyter Notebook who just wants to keep track of their experiments without setting up a database or heavy framework.

Quick Setup

Get started in 30 seconds.

1. Install from PyPI:

pip install littlelogger

2. Import and use the decorator:

from littlelogger import log_run

# NOTE: for this to work, we need the training function to input the parameters that need to be logged
# and output the performance metric e.g., f1_score, accuracy_score, etc.
@log_run(log_file="my_experiments.jsonl")
def train_model(learning_rate, n_estimators):
    # Your training logic...
    f1 = 0.80
    return {"f1_score": f1}

# Just run your function as normal
train_model(0.1, 100)
train_model(0.05, 200)

3. Check your results: A my_experiments.jsonl file will be created, logging every run.

See it in Action

Want to see how it works? Check out the Demo Notebook to see a real-world example of logging experiments from different models into one file.

The Problem

You're tuning a model and your notebook looks like this:

# metrics = train_model(max_depth=5, n_estimators=100) # f1: 0.82
# metrics = train_model(max_depth=7, n_estimators=100) # f1: 0.81
metrics = train_model(max_depth=5, n_estimators=200) # f1: 0.83
print(metrics)

A day later, you've lost track of your best run.

The Solution

Wrap your function with the @log_run decorator.

from littlelogger import log_run

@log_run(log_file="experiment_log.jsonl")
def train_model(max_depth, n_estimators):
    # ... your training logic ...
    f1_score = 0.83 # Your metric
    return {"f1": f1_score}

# Run your experiments
train_model(max_depth=5, n_estimators=100)
train_model(max_depth=7, n_estimators=100)
train_model(max_depth=5, n_estimators=200)

This will create a experiment_log.jsonl file with one line per experiment:

{"timestamp": "2025-11-01T16:30:00...", "runtime_seconds": 12.3, "params": {"max_depth": 5, "n_estimators": 100}, "metrics": {"f1": 0.82}}
{"timestamp": "2025-11-01T16:32:12...", "runtime_seconds": 14.1, "params": {"max_depth": 7, "n_estimators": 100}, "metrics": {"f1": 0.81}}
{"timestamp": "2025-11-01T16:34:45...", "runtime_seconds": 23.5, "params": {"max_depth": 5, "n_estimators": 200}, "metrics": {"f1": 0.83}}

Analyzing Your Results

You can easily load your results back into pandas to find your best run. The key is using load_log() from littlelogger

from littlelogger import load_log

log_df = load_log(PATH_TO_LOG_FILE)

# Find your best run!
log_df.sort_values(by="metric_f1_score", ascending=False)

API Reference

@log_run(log_file="experiment_log.jsonl")

This is the main decorator. You place it above your function definition.

Parameters:

  • log_file (str): The path to the .jsonl file where logs will be written.
    • Default: "experiment_log.jsonl"
    • Behavior: The decorator will append to this file. It does not overwrite.

What is Logged?

The decorator will write a single JSON line to the file for each function call, containing:

  • timestamp: An ISO 8601 formatted UTC timestamp.
  • function_name: The name of the function that was run (e.g., train_model).
  • runtime_seconds: The execution time of the function (in seconds).
  • params: A dictionary of all arguments (including defaults) passed to your function.
  • metrics: The value returned by your function. This is expected to be a dictionary (e.g., {"f1": 0.8, "accuracy": 0.9})

⚠️ Important Limitations

This tool is built for simplicity and has intentional trade-offs:

  1. Not Thread-Safe: This logger is NOT designed for concurrency. If you run functions in parallel (using multiprocessing or threading from the same script), they will try to write to the log file at the same time, which will corrupt the file. It is for single-process, iterative experiments only.
  2. JSON-Serializable Data Only: The decorator assumes your function arguments and return values are "JSON-serializable" (strings, ints, floats, lists, dicts). If you return a complex object (like a scikit-learn model), the logger will fail to serialize it.
  3. Best-Effort Logging (No Retries): If logging fails (due to a non-serializable object or a file permission error), littlelogger will not crash your script. It will print a UserWarning to your console and let your function return its value, prioritizing your main script's execution over logging.

License & Contributing

  • License: This project is licensed under the MIT License. See the LICENSE file for details.
  • Contributing: Feel free to open an issue or submit a pull request!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

littlelogger-1.1.1.tar.gz (7.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

littlelogger-1.1.1-py3-none-any.whl (8.7 kB view details)

Uploaded Python 3

File details

Details for the file littlelogger-1.1.1.tar.gz.

File metadata

  • Download URL: littlelogger-1.1.1.tar.gz
  • Upload date:
  • Size: 7.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.13.9 Linux/6.11.0-1018-azure

File hashes

Hashes for littlelogger-1.1.1.tar.gz
Algorithm Hash digest
SHA256 d574feb56043fc19b67001cd748fbdf916330b8dd099c1e398124d2c25120e7f
MD5 bfa53ccf96e6e0f77d48e4bd139f0027
BLAKE2b-256 09a0f1656843dbbccffe60f6a40dc7af574f2b6949e738861830374cae7b4f98

See more details on using hashes here.

File details

Details for the file littlelogger-1.1.1-py3-none-any.whl.

File metadata

  • Download URL: littlelogger-1.1.1-py3-none-any.whl
  • Upload date:
  • Size: 8.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.13.9 Linux/6.11.0-1018-azure

File hashes

Hashes for littlelogger-1.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a4220056fd793b41819c8b1e065c2314b33a8afd327ea4e337fd9130b3f7ee32
MD5 0d4a9e31680b14b381e1b04d49b38830
BLAKE2b-256 a5b16d21bc14579920711f3f90e43b4c9c2fafde705bbf9e7bf89b208a2a3a9f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page