Logging
Configure Levee's diagnostic logs with config.json, read them with levee log, and understand how they differ from the audit trail
Diagnostic logs record what Levee's own components were doing, so IT and Vediram support can fix problems. They are not the audit trail. The audit trail is the evidence of what the AI agent asked for and what Levee decided, and it is always on. This page covers diagnostic logs only.
How do diagnostic logs differ from the audit trail?
| Audit trail | Diagnostic logs | |
|---|---|---|
| Purpose | Evidence: what the agent requested and what Levee decided | Troubleshooting: what Levee's own components were doing |
| Audience | Security, compliance, auditors | IT and Vediram support |
| Location | levee-audit.db, levee-audit.jsonl | %ProgramData%\Vediram\Levee\logs\ |
| Retention | Kept until you remove it | Bounded by size and age (below) |
| Configured by | Always on | config.json |
For the audit trail, see Activity and audit.
Diagnostic logs are built not to contain secrets or sensitive content: no credentials, tokens, cookies, connection strings, SQL text, search queries, or prompts.
config.json
Logging is configured in one file, %ProgramData%\Vediram\Levee\config.json. The defaults suit most organizations. Change them only to get more detail for a support case, or to keep logs longer.
The installer creates the file with these defaults and never overwrites it on upgrade, so your changes survive updates.
{
"schemaVersion": 1,
"logging": {
"defaultLevel": "Information",
"componentLevels": {},
"categoryLevels": {
"Microsoft": "Warning",
"System.Net.Http": "Warning"
},
"retention": {
"maxTotalSizeMb": 256,
"maxAgeDays": 7,
"segmentSizeMb": 8
}
}
}
The file is readable by all users and writable only by Administrators. It must never contain secrets.
Keys
| Key | Default | Allowed values |
|---|---|---|
schemaVersion | 1 | 1 |
logging.defaultLevel | Information | Trace, Debug, Information, Warning, Error, Critical, None |
logging.componentLevels | {} | Component name to level, overriding defaultLevel for that component |
logging.categoryLevels | Microsoft and System.Net.Http at Warning | Framework category prefix to level, to quiet noisy libraries |
logging.retention.maxTotalSizeMb | 256 | 32 to 4096. Total disk space for all logs. |
logging.retention.maxAgeDays | 7 | 1 to 365. Older data is deleted. |
logging.retention.segmentSizeMb | 8 | 1 to 64, and at most a quarter of maxTotalSizeMb. Size of each log file before it rolls over. |
Component names
| Component | What it covers |
|---|---|
service | The Levee service |
app | The desktop app |
cli | The levee command-line tool |
engine | The container engine |
proxy.http | Web access |
proxy.llm | Model access |
proxy.odbc | Database access |
proxy.search | Web search |
proxy.pkg | Packages (preview) |
proxy.m365 | Microsoft 365 (preview) |
m365.addin | The Levee Office add-in (preview) |
fs.service, fs.driver | File access: the LeveeFSHost service and the LeveeFS driver |
proxy.mcp | Plugins (preview): the MCP plugin runner |
An unknown component name is ignored with a warning (logging.unknown_component).
Example: debug web access for a troubleshooting session
{
"schemaVersion": 1,
"logging": {
"defaultLevel": "Information",
"componentLevels": {
"proxy.http": "Debug",
"service": "Debug"
},
"categoryLevels": {
"Microsoft": "Warning",
"System.Net.Http": "Warning"
},
"retention": { "maxTotalSizeMb": 512, "maxAgeDays": 7, "segmentSizeMb": 8 }
}
}
Set levels back to Information when you're done; Debug and Trace produce a lot of data and use up the size budget faster.
Applying changes
Most changes apply on their own within moments. Only the container engine needs a restart.
- Changes are picked up automatically by the service, the app, and the Levee channels. No restart is needed.
- The container engine is the exception: after changing the
enginelevel, restart it (Restart-Service LeveeContainerEngine, elevated). - If the file becomes invalid, unreadable, or is deleted, every component keeps its last good configuration. A typo never turns logging off.
Validate a file before you deploy it:
levee config validate .\config.candidate.json
# Valid.
Diagnostic codes you may see:
| Code | Meaning |
|---|---|
config.invalid_json | The file isn't valid JSON. |
config.invalid_schema_version | schemaVersion isn't 1. |
logging.invalid_default_level, logging.invalid_component_level, logging.invalid_category_level | A level name isn't one of the allowed values. |
logging.invalid_retention | A retention value is out of range, or segmentSizeMb is more than a quarter of maxTotalSizeMb. |
logging.unknown_component | A component name isn't recognized (ignored). |
config.missing, config.unreadable | The file is missing or couldn't be read; the last known configuration is kept. |
How do I read the logs?
Use levee log tail. It merges all components, decompresses rolled files, and enforces who may see what, so you don't need to open the files.
# Your recent warnings and errors
levee log tail --level Warning --since 1h
# One component for one project, live
levee log tail --component proxy.llm --project 3f9c1a7e42b0 --follow
# Several components at once
levee log tail --component service --component engine --since 30m
# Everything on the machine (elevated PowerShell)
levee log tail --all --since 1d --json > "$env:TEMP\levee-logs.json"
| Option | Effect |
|---|---|
--component <name> | Filter by component. Repeatable. |
--project <id> | Only one project. |
--level <level> | Minimum level. |
--since <age> | 30m, 2h, 1d, ... |
--follow | Keep reading new events. |
--lines <n> | Only the most recent n events (at most 1000 by default). |
--all | Every scope on the machine. Requires elevation; otherwise fails with --all requires an elevated (Administrator) session. |
Who can read what?
- Each user sees their own app and CLI logs and the logs of projects they own.
- Administrators (with
--all) see machine logs, every project, and every user.
Log store status
levee log status
Reports the space used against maxTotalSizeMb, the oldest data kept, whether each component has applied the current configuration, and whether any events were recently dropped.
Where are the files?
%ProgramData%\Vediram\Levee\logs\
machine\<component>\...
projects\<project id>\<component>\...
users\<user SID>\<component>\...
Files are JSON lines, compressed (.gz) once rolled. The LeveeFSHost service writes its log in the project's folder, under fs.service. If a component can't write to this folder at all, it writes to an emergency location instead, %TEMP%\Vediram\Levee\<component>-<pid>-fallback, so nothing is lost silently.
Other logs worth knowing:
| Log | Where |
|---|---|
| Installer host preparation (prerequisite checks, including LeveeFS) | %SystemRoot%\Temp\levee-prepare-host.log |
| LeveeFS driver preparation report | %SystemRoot%\Temp\LeveeFs-<random>\prepare.log, one folder per attempt, readable by SYSTEM and Administrators only |
Installer (when using install-levee.ps1) | %ProgramData%\Vediram\Levee\installer\logs\ |
| Container engine errors | Windows Event Log, Application, source docker |
Sending logs to Vediram support
See Collecting logs for support for the exact commands to gather everything support needs in one archive.