DEBUG upward. The console shows only the level you configure.
How Logging Works in Cognee
When you import or start Cognee,setup_logging() is called automatically. The first call in a process configures two handlers:
- Console handler — writes colored output to
stderr, filtered byLOG_LEVEL(default:INFO) - File handler — writes plain text to a timestamped
.logfile, always atDEBUGlevel
Logging Is Configured Once Per Process
setup_logging() is idempotent. Cognee calls it from four places during a normal server start — importing cognee, importing cognee.api.client, importing the vector embeddings utilities, and server startup — but only the first call does any configuration work. That call installs the console and file handlers, sets up the sys.excepthook, opens the log file, and emits the startup messages. Every later call, including one you write yourself, returns a structlog logger and changes nothing: the handlers, log file, and excepthook from the first call stay in place, and the startup banner is not repeated. Because the first call wins, arguments you pass to a later setup_logging(log_level=...) call are ignored — see Setting the Log Level for the supported way to control verbosity.
The guard is per interpreter. A sub-process starts fresh, configures its own handlers, and appends to the same log file, which is how one file ends up holding output from all of them.
Default log file locations
Default log file locations
The default Running from source (cloned repository):Using the MCP server:
The MCP server uses the same logging setup. The log directory is the same as above, depending on your environment. When a background task is launched, the MCP server returns the full path to the active log file in its response.
logs/ directory is created next to the cognee package directory, one level above it. The exact path depends on how Cognee is installed.Installed via pip (e.g. pip install cognee):Size-Based Rotation
The file handler also caps how large a single startup’s log can grow. Before writing each record it checks the current file size, and once the file has reachedCOGNEE_LOG_MAX_BYTES (default 50 MB) it rolls over: the active file is renamed to <name>.log.1, any existing backups shift up by one, and logging continues in a fresh file under the original name. At most COGNEE_LOG_BACKUP_COUNT backups (default 5) are kept, so on the defaults one startup’s logs occupy roughly 300 MB at the ceiling — one active 50 MB file plus five 50 MB backups.
Rotation and the keep-10 cleanup are independent mechanisms. Rotation bounds the size of one startup’s log; the keep-10 cleanup prunes old startups’ files. The cleanup only matches files ending in .log, so numbered rotation backups (.log.1, .log.2, …) are not counted by it and are not removed when their originating startup’s .log file is pruned. If you run with a large COGNEE_LOG_BACKUP_COUNT and restart often, prune the log directory yourself.
Controlling Logging
Environment Variables
COGNEE_LOGS_DIR— Absolute path to a custom log directory. Cognee creates it if it does not exist. Must be an absolute path — relative paths cause a startup error. Default:logs/next to thecogneepackage.LOG_LEVEL— Console log verbosity. One ofDEBUG,INFO,WARNING,ERROR,CRITICAL. Default:INFO. Does not affect the log file, which always capturesDEBUGand above.COGNEE_LOG_MAX_BYTES— Size in bytes at which the active log file is rotated. Default:52428800(50 MB). Set it to0to turn size-based rotation off and let a startup’s log file grow without a cap.COGNEE_LOG_BACKUP_COUNT— How many rotated backups to keep alongside the active file. Default:5. Backups are named<name>.log.1through<name>.log.<count>, oldest last.
Setting the Log Level
LOG_LEVEL is read when logging is configured, which happens on the first setup_logging() call — and import cognee makes that call for you. So the level must be in place before the import:
.env file works too, and takes precedence: Cognee loads .env with override=True at import time, just before configuring logging. If LOG_LEVEL is in your .env, change it there rather than in the shell or in code.
Configuration Examples
Fallback Behavior
If Cognee cannot write toCOGNEE_LOGS_DIR, it falls back to /tmp/cognee_logs. If that also fails, file logging is skipped silently and only console output is produced.
Log Files and Their Content
File Format
Log files use plain text, one entry per line. Timestamps are in UTC:Console Format
The console uses structlog’s colored renderer, written tostderr. Level colors: DEBUG blue, INFO green, WARNING yellow, ERROR and CRITICAL red.
Logged exception tracebacks are rendered without per-frame local variables (show_locals=False). The traceback itself is still shown, but the values of locals in each frame are omitted. This keeps memory bounded when exceptions are logged in the retrieval/search path, where frame locals can hold graph objects carrying embedding vectors and deep node/edge references — rendering those recursively could spike memory to multiple GB and OOM-kill the process.
Cognee also installs a safe sys.excepthook, so uncaught non-KeyboardInterrupt exceptions are logged through structlog before Python’s default traceback is printed. If rich traceback rendering fails, Cognee falls back to plain traceback output.
Exception Details
When an exception is logged, the structured log event includes the exception type inexception_type alongside the exception message. This makes error entries easier to interpret because they show both what failed and the exception class that raised it, for example ValueError.
What to Expect at Startup
Cognee initializes logging once per process, and that initialization logs the following four messages in order:- INFO — The full path to the log file created for this session.
- WARNING — The
Cognee 1.0 changesbanner: the new remember/recall/forget/improve API, session memory on by default, multi-user access control on by default, and agents auto-verified on registration. This is expected and not an error. - INFO —
Logging initialized, with system metadata attached as structured fields: Python version, structlog version, Cognee version, OS, and the database storage path. - INFO — The database storage path again, as a plain-text line.
COGNEE_LOGS_DIR to a path you control.
The active graph, vector, and relational providers are not part of these messages. Cognee defers that configuration logging to the first actual pipeline call, because importing those configs pulls in heavy dependencies.
File Naming
Each log file is named after the startup timestamp:2025-02-14_15-32-47.log
When that file hits the size cap it is rotated, so a long-running startup leaves numbered backups next to it — 2025-02-14_15-32-47.log.1 is the most recent rotated segment, .log.2 the one before it, and so on.
Troubleshooting
Can't find the log file
Can't find the log file
Run this snippet after importing cognee to get the exact path:
No log file is created
No log file is created
Cognee falls back to console-only logging if the log directory is not writable. This is common in managed environments where
site-packages/ is read-only.Set COGNEE_LOGS_DIR to an absolute path you own:LOG_LEVEL is ignored
LOG_LEVEL is ignored
Logging is configured on the first
setup_logging() call, which import cognee triggers. If you set LOG_LEVEL after that import — or call setup_logging(log_level=...) yourself — the level is already fixed and your change does nothing. Set LOG_LEVEL in your .env file or in the environment before importing Cognee. See Setting the Log Level.Overview
Return to setup configuration overview
Relational Databases
Configure metadata and state storage
Installation
Install Cognee and set up your environment