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

@log_run(log_file="my_experiments.jsonl")
def train_model(learning_rate, n_estimators):
    # Your training logic...
    f1 = 0.85
    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 pd.read_json() with lines=True.

import pandas as pd

Load the raw log file
df = pd.read_json("model_runs.jsonl", lines=True)

# The 'params' and 'metrics' columns will be dictionaries.
# You can "flatten" them to make analysis easy:
df_params = pd.json_normalize(df['params']).add_prefix('param_')
df_metrics = pd.json_normalize(df['metrics']).add_prefix('metric_')

# Join everything into a clean, flat table
df_analysis = pd.concat([
    df.drop(['params', 'metrics'], axis=1),
    df_params,
    df_metrics
], axis=1)

# Find your best run!
df_analysis.sort_values(by="metric_f1", 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.0.1.tar.gz (6.6 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.0.1-py3-none-any.whl (8.0 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for littlelogger-1.0.1.tar.gz
Algorithm Hash digest
SHA256 4cab85354503381268c494d9e5626cdb61e0eda95fdf46a5ea636884a05c4ef5
MD5 b6776fc52fe50343de1f0288cdd1fe34
BLAKE2b-256 66447aeae6f3231090d87c4afe5fd07c4c4b376b56d9476efe19818aa6e3105d

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for littlelogger-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1a9b0291e78739104840c2748612bd83dede4e8f004dba85c1e271004d76dde0
MD5 8f76247151c690ae2ee2251df72d97bc
BLAKE2b-256 9ec700a1c24a9ec2f9593302b9ab77696e70134192d41cf4a8074746eb358134

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