Application logs
Logs let you follow the behavior of a request, command, or job through events with different severity levels. Orionis includes the Logger service, the ILogger contract, and the Log facade: all three access paths belong to the same component.
The service writes UTF-8 text files and uses one active channel per process. Configuration provides six channels: stack, hourly, daily, weekly, monthly, and chunked. stack is a single file, rather than a channel aggregation. The component requires no additional driver installation.
Start recording
Section titled “Start recording”Select the channel and severity threshold in your project’s .env:
LOG_CHANNEL=dailyLOG_LEVEL=INFOLOG_RETENTION=int:7The config/logging.py file reads these variables during configuration. Do not use Env from controllers to configure the logger: consume the service that the application has already prepared. Channels and configuration explains every variable, its defaults, and file locations.
After application startup, use the facade from a controller:
from orionis.http import JSONResponsefrom orionis.support.facades import Log
class ReportStatusController: async def index(self) -> JSONResponse: Log.info("event=report-status-read") return JSONResponse({"status": "ready"})In your API route file:
from app.http.controllers.report_status_controller import ReportStatusControllerfrom orionis.support.facades import Route
Route.get("/reports/status", [ReportStatusController, "index"])Save the controller as app/http/controllers/report_status_controller.py. With the daily channel, an example record looks like:
2026-10-23 10:30:00 [INFO]: event=report-status-readThe file follows storage/logs/daily_YYYY-MM-DD.log, relative to the project root. The provider pins the facade during its asynchronous boot; after that startup completes, Log.info() is a synchronous call, including inside an async method. Do not add await. For integrations accessing it before that boot, see facade dispatch.
From the component to the file
Section titled “From the component to the file”flowchart TD
accTitle: Application log record flow
A[config/logging.py: channel, level, and file] --> B[Provider: ILogger singleton and Log facade]
B --> C[Controller, command, job, or service]
C --> D[Log or ILogger: synchronous write]
D --> E[Lazy logger and handler initialization]
E --> F{Does the level meet the effective threshold?}
F -->|Yes| G[Format the UTF-8 record]
F -->|No| H[Filter the record]
G --> I[Handler: check rotation and retention]
I --> J[Write the line]Rotating handlers check rotation before writing the line; there is no independent process rotating files at a fixed time. The process’s standard logger is named __orionis__ and does not propagate records to Python’s root logger.
Choose a guide
Section titled “Choose a guide”| Need | Guide |
|---|---|
| Select a channel, level, and directory | Channels and configuration. |
| Use every method, inject ILogger, or record an exception | Writing logs. |
| Understand suffixes, retention, compression, shutdown, and multiple workers | Rotation and lifecycle. |
Retention limits file counts, including settings named retention_days or retention_hours; it does not delete a file when it reaches an exact age. The chunked implementation generates a new suffix for every record and can rotate before reaching mb_size. Review policy behavior before choosing one.
Exception handling and presentation are documented in Exceptions. That section explains when the handler reports an error; these guides explain how that record is written and retained.