Logging¶
phēnix features a centralized logging system that aggregates logs from the core daemon, internal Go services, and external user applications.
Architecture¶
The logging architecture is designed to be centralized. The phēnix core acts as the aggregator, capturing stderr from all running applications, parsing the output as JSON, and ingesting it into the centralized logging system.
graph TD
subgraph "phēnix core"
Core[phēnix Daemon]
Plog[plog Package]
FileLog[File Logger]
ConsoleLog[Console Logger]
UILog[UI Logger]
Config[Viper Config]
end
subgraph "Go Apps"
GoApp[Go Application]
GoSlog[slog JSON Handler]
end
subgraph "Python Apps"
PyApp[Python Application]
PyLog[Python Logger]
PySink[phēnix Stderr Sink]
end
Config -->|Watches config.yaml| Plog
Core -->|Uses| Plog
Plog -->|Write JSON/Text| FileLog
Plog -->|Write Text| ConsoleLog
Plog -->|Publish| UILog
GoApp -->|Log| GoSlog
GoSlog -->|JSON via Stderr| Core
PyApp -->|Log| PyLog
PyLog -->|Log| PySink
PySink -->|JSON via Stderr| Core
Core -->|ProcessStderrLogs| Plog
The App Contract¶
All applications (Go or Python) running under phēnix must adhere to the following contract to ensure their logs are correctly parsed and displayed in the UI:
- Output: Logs must be written to
stderr. - Format: Logs must be single-line JSON objects.
- Required Fields:
level:DEBUG,INFO,WARN,ERRORmsg: The log message string.time: Timestamp (RFC3339 or similar).
- Optional Fields:
traceback: For exceptions/panics (string).
Tip
Check out the Example Applications for complete, runnable reference implementations in Go and Python.
Python Apps¶
Use the phenix_apps.common.logger. It is pre-configured to output JSON to stderr.
Important
For fatal errors, raise an exception (e.g., ValueError, RuntimeError) instead of calling sys.exit(1). The AppBase class wraps execution in a try/except block and will automatically catch the exception, log the traceback as structured JSON, and exit cleanly.
from phenix_apps.common.logger import logger
def my_func():
try:
logger.bind(custom_field="value").info("Starting operation")
# ... code ...
except Exception:
# Automatically captures traceback and formats as JSON
logger.exception("Operation failed")
Go Apps¶
Use log/slog with a JSON handler.
import (
"log/slog"
"os"
)
func main() {
logger := slog.New(slog.NewJSONHandler(os.Stderr, nil))
slog.SetDefault(logger)
slog.Info("Application started", "app", "my-app")
}
phēnix Core¶
Use the phenix/util/plog package for logging within the core application.
import "phenix/util/plog"
func MyFunc() {
// Always provide a LogType enum for UI filtering
plog.Info(plog.TypeSystem, "System initialized", "version", "1.0")
}
HTTP Request Logging¶
To view detailed HTTP request logs (method, path, status, duration), start the UI with the --log-requests flag.
Troubleshooting
For common logging issues and solutions, please see the Troubleshooting page.