Logging Management
Most customers manage loggers through the Console UI. The management API is for infrastructure-as-code, CI/CD pipelines, setup scripts, and automated testing. Management operations are stateless HTTP calls — no start() or WebSocket needed.
Create a Logger
Create a logger with an explicit key and managed status. Managed loggers have their levels controlled by smplkit; unmanaged loggers are tracked but not actively managed. All mutations are local until save() is called.
async with AsyncSmplClient(environment="production", service="my-service") as client:
lg = client.logging.management.new("app", name="app", managed=True)
lg.setLevel(LogLevel.WARN)
await lg.save()Log Levels
Available log levels, from finest to most restrictive:
| Level | Description |
|---|---|
TRACE | Finest-grained diagnostic output |
DEBUG | Detailed diagnostic information |
INFO | General operational information |
WARN | Potential issues that do not prevent operation |
ERROR | Errors that affect operation |
FATAL | Severe errors that may cause termination |
SILENT | Suppresses all output |
from smplkit import LogLevel
lg.setLevel(LogLevel.WARN)Level Management
Convenience methods for setting and clearing levels. All are local mutations — call save() to persist.
Set Base Level
lg.setLevel(LogLevel.ERROR)
await lg.save()Set Environment-Specific Level
Override the base level for a specific environment. At runtime, the environment override takes precedence over the base level.
lg.setEnvironmentLevel("production", LogLevel.ERROR)
lg.setEnvironmentLevel("staging", LogLevel.DEBUG)
await lg.save()Clear Levels
Clear the base level (falls back to group or ancestor inheritance), clear a specific environment override, or clear all environment overrides.
lg.clearLevel()
await lg.save()
lg.clearAllEnvironmentLevels()
await lg.save()Log Groups
Log groups organize loggers. A group has its own base level and environment overrides. Loggers assigned to a group inherit the group's level when they don't have their own explicit level.
Create a Log Group
group = client.logging.management.new_group("databases", name="Databases")
group.setLevel(LogLevel.ERROR)
group.setEnvironmentLevel("production", LogLevel.WARN)
await group.save()List and Get Groups
groups = await client.logging.management.list_groups()
group = await client.logging.management.get_group("databases")Update a Group
Fetch a group, mutate its properties, and save.
group = await client.logging.management.get_group("databases")
group.setLevel(LogLevel.WARN)
await group.save()Delete a Group
await client.logging.management.delete_group("databases")Group Assignment
Assign a logger to a group by setting the logger's group property to the group's ID. Save to persist.
lg.group = group.id
await lg.save()Promote and Release
Toggle a logger's managed status. Releasing a managed logger (managed=false) removes it from active management. Re-promoting sets managed=true and starts fresh with level=null.
Auto-demote: If a managed logger's base level, environment overrides, and group assignment are all cleared (all null/empty), the server automatically sets
managed=falseon save. This prevents "zombie" managed loggers that have no configuration. To keep a logger managed with no explicit level, set at least one environment override, or assign it to a group before saving.
lg.managed = False
await lg.save()
lg.managed = True
await lg.save()List, Get, Delete Loggers
loggers = await client.logging.management.list()
lg = await client.logging.management.get("app")
await client.logging.management.delete("app")Sync Client (Python)
For synchronous applications (Django, Flask, CLI tools), use SmplClient instead of AsyncSmplClient. The API is identical but without await.
from smplkit import SmplClient, LogLevel
with SmplClient(environment="production", service="my-service") as client:
lgr = client.logging.management.new("my.logger", managed=True)
lgr.setLevel(LogLevel.WARN)
lgr.save()
lgr = client.logging.management.get("my.logger")
lgr.setEnvironmentLevel("production", LogLevel.ERROR)
lgr.save()
grp = client.logging.management.new_group("sql", name="SQL Loggers")
grp.setLevel(LogLevel.WARN)
grp.save()
lgr.group = grp.id
lgr.save()
client.logging.management.delete("my.logger")
client.logging.management.delete_group("sql")Next Steps
- Logging Runtime — Start the runtime, react to level changes
- Smpl Config — Manage application configuration across environments
- API Reference — Logging — Full REST API documentation

