A hierarchical, context-manager logger utility with multiprocess mapping capabilities
Project description
logmap
A hierarchical context-manager logger with multiprocess mapping.
Install
pip install logmap
Usage
from logmap import logmap
Basic
with logmap('testing...'):
# ... do something ...
pass
⎾ testing... @ 2026-04-19 15:12:55,349
⎿ 0 seconds @ 2026-04-19 15:12:55,349
Duration
with logmap('testing...') as lm:
naptime = lm.nap()
assert naptime == lm.duration
⎾ testing... @ 2026-04-19 15:12:55,349
│ napping for 0.6 seconds @ 2026-04-19 15:12:55,349
⎿ 0.6 seconds @ 2026-04-19 15:12:55,954
Nested
Nesting indents automatically. lm.log("msg") writes at the current depth.
with logmap('outer') as lm:
with logmap('middle') as lm2:
with logmap('inner') as lm3:
lm3.nap()
⎾ outer @ 2026-04-19 15:12:55,954
│ ⎾ middle @ 2026-04-19 15:12:55,954
│ │ ⎾ inner @ 2026-04-19 15:12:55,954
│ │ │ napping for 0.2 seconds @ 2026-04-19 15:12:55,954
│ │ ⎿ 0.2 seconds @ 2026-04-19 15:12:56,159
│ ⎿ 0.2 seconds @ 2026-04-19 15:12:56,159
⎿ 0.2 seconds @ 2026-04-19 15:12:56,159
Parallel map
import random, time
def fn(naptime):
t = random.random() * naptime / 2
time.sleep(t)
return t
with logmap('function mapping') as lm:
results = lm.map(fn, list(range(5)), num_proc=2)
⎾ function mapping @ 2026-04-19 15:12:56,159
│ mapping fn to 5 objects [2x]: 100%|██████████| 5/5 [00:02<00:00, 2.31it/s]
⎿ 2.2 seconds @ 2026-04-19 15:12:58,335
For streaming results as they arrive:
with logmap('function mapping') as lm:
for res in lm.imap(fn, list(range(5)), num_proc=2):
lm.log(f'got {res:.2f}') # updates the progress bar
lm.run(...) is the same but discards results — useful when you only care about side effects.
Module-level helpers pmap, pmap_iter, pmap_run provide the same semantics without a logmap context:
from logmap import pmap
pmap(fn, items, num_proc=4)
Note:
logmapuses stdlibmultiprocessing, so functions passed to parallel map must be picklable (defined at module level — no lambdas or closures).
Without a with block
# just a logger
lm = logmap('app')
lm.log('ready')
lm.warning('careful')
# explicit lifecycle (equivalent to a `with` block)
lm = logmap('manual').start()
lm.log('doing stuff')
lm.stop()
Redirecting output
logmap writes to sys.stderr by default. Use configure() to redirect:
from logmap import configure
import sys
configure(sink=sys.stdout) # e.g. so it doesn't mingle with stderr diagnostics
configure(sink="run.log") # path — opened line-buffered
configure(sink=my_stringio) # any writable stream
configure(level="INFO") # drop DEBUG messages
Colors auto-disable when the sink isn't a TTY (files, StringIO, etc.).
Stdlib logging integration
Route all logmap output through a standard library logging.Logger:
import logging
from logmap import configure
configure(logger=logging.getLogger("myapp"))
This lets you attach any stdlib handler (file, syslog, etc.) and have logmap participate in your application's logging hierarchy. Level integers match stdlib conventions, so filtering works as expected. Pass logger=None to switch back to direct sink output.
Structured (JSON) output
For log aggregation or machine parsing, enable JSON-lines mode:
configure(structured=True)
Each line becomes a JSON object:
{"ts": "2026-04-19T15:12:55.349000", "level": "INFO", "msg": "doing work", "depth": 1, "task": "outer"}
The msg field contains the clean message (no indentation prefix), while depth and task give you the hierarchical context as structured data.
Silencing
with logmap.quiet():
with logmap('no output'): # nothing gets printed
...
logmap.disable() # global off switch
logmap.enable() # back on
with logmap('task', announce=False): suppresses just the open/close lines while keeping lm.log() active.
Thread safety
Nesting depth and quiet state are thread-local — multiple threads can use logmap concurrently without interleaving indentation or silencing each other. Output writes are serialized with a lock to prevent garbled lines.
Multiprocessing on macOS
On macOS, logmap defaults to the forkserver multiprocessing context instead of fork (which Python 3.12+ deprecates due to deadlock risk with threads). You can still pass context="spawn" or context="fork" explicitly to lm.map() / pmap() if needed.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file logmap-0.3.0.tar.gz.
File metadata
- Download URL: logmap-0.3.0.tar.gz
- Upload date:
- Size: 27.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0675a522356d62575cf74c6bfca0ee89092924304d4f3d47648499423667c84d
|
|
| MD5 |
0f87943adc0f12c06dab7d17b43572a5
|
|
| BLAKE2b-256 |
6f2957bdd8908cfc94dd899a8dea52f3e336e356760c9e2b86a2d3b3f4881e2d
|
Provenance
The following attestation bundles were made for logmap-0.3.0.tar.gz:
Publisher:
publish.yml on quadrismegistus/logmap
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
logmap-0.3.0.tar.gz -
Subject digest:
0675a522356d62575cf74c6bfca0ee89092924304d4f3d47648499423667c84d - Sigstore transparency entry: 1387316014
- Sigstore integration time:
-
Permalink:
quadrismegistus/logmap@784124cf306cf8564a21941d90a438448a646afa -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/quadrismegistus
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@784124cf306cf8564a21941d90a438448a646afa -
Trigger Event:
release
-
Statement type:
File details
Details for the file logmap-0.3.0-py3-none-any.whl.
File metadata
- Download URL: logmap-0.3.0-py3-none-any.whl
- Upload date:
- Size: 21.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ce1d9c0b607d2ce281974e2febd491bf1f4ec72feea6d6dbd050d739861d5fc9
|
|
| MD5 |
d5889c441dbde87ce4e7f9964542383c
|
|
| BLAKE2b-256 |
23a091338b9955596e5540443c2555541efe49e99f7318f5ddd8c379365bf7b7
|
Provenance
The following attestation bundles were made for logmap-0.3.0-py3-none-any.whl:
Publisher:
publish.yml on quadrismegistus/logmap
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
logmap-0.3.0-py3-none-any.whl -
Subject digest:
ce1d9c0b607d2ce281974e2febd491bf1f4ec72feea6d6dbd050d739861d5fc9 - Sigstore transparency entry: 1387316160
- Sigstore integration time:
-
Permalink:
quadrismegistus/logmap@784124cf306cf8564a21941d90a438448a646afa -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/quadrismegistus
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@784124cf306cf8564a21941d90a438448a646afa -
Trigger Event:
release
-
Statement type: