OpenHands / OpenHands/software-agent-sdk
Route Laminar and agent-server INFO logs through structured non-error logging
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 1.1k
- Forks
- 542
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 137
Description
Context
Several SDK/agent-server startup observability logs are INFO-level messages, but can be ingested as status:error because they are emitted through third-party/default stderr handlers instead of the SDK's structured stdout logging:
"No path found in HTTP endpoint URL""Laminar is already initialized"- Uvicorn startup/shutdown messages such as
"Uvicorn running on","child process","parent process", and"Received SIGTERM"when emitted by the agent server.
These should remain visible as INFO, not page application-failure monitors.
Investigation notes
Laminar
openhands-sdk/openhands/sdk/observability/laminar.py calls lmnr.Laminar.initialize(...) when observability env vars are present. In lmnr==0.7.49:
No path found in HTTP endpoint URL...is emitted withlogger.info(...)fromlmnr/opentelemetry_lib/tracing/exporter.py.- That logger is created with Laminar's
get_default_logger(..., propagate=False), which attaches a plainlogging.StreamHandler(); the default stream is stderr. Laminar is already initialized. Skipping initialization.is emitted withcls.__logger.info(...)fromlmnr/sdk/laminar.pyafterLaminar._initialize_logger()attaches another default stderrStreamHandler.
So the Python log level is INFO, but the stream/formatter can make Datadog classify the record as status:error.
Agent-server/Uvicorn
In openhands-agent-server:
openhands-agent-server/openhands/agent_server/logging_config.pydefines the JSON access handler withstream: ext://sys.stderr.openhands-sdk/openhands/sdk/logger/logger.pyuseslogging.StreamHandler()without an explicit stream, which defaults to stderr for the root SDK handler.- Uvicorn's startup/shutdown messages are INFO logs. If they are written to stderr, container log ingestion can classify them as error status.
Proposed fix
- Normalize Laminar loggers after initialization:
- remove Laminar-installed stderr handlers for
lmnr*loggers, or replace them with SDK-compatible structured handlers; - set propagation so INFO records flow through the SDK logger once;
- preserve INFO visibility rather than silencing the messages globally.
- remove Laminar-installed stderr handlers for
- Update SDK/agent-server logging to route INFO/WARNING JSON logs to stdout and reserve stderr for real ERROR/CRITICAL records, or otherwise emit a Datadog-compatible status/severity field that overrides stream classification.
- Adjust
openhands-agent-serverUvicorn logging config so access/error INFO logs do not use stderr in production JSON mode. - Add tests that simulate Laminar/Uvicorn INFO records and assert they are emitted with INFO severity/status and not via stderr-only handlers.
Acceptance criteria
No path found in HTTP endpoint URLandLaminar is already initializedare ingested as INFO, notstatus:error.- Agent-server Uvicorn startup/shutdown INFO logs are ingested as INFO.
- Real ERROR/CRITICAL logs still surface as errors.
This issue was created by an AI agent (OpenHands) on behalf of the user.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read openhands-sdk/openhands/sdk/observability/laminar.py and openhands-sdk/openhands/sdk/logger/logger.py, then inspect openhands-agent-server/openhands/agent_server/logging_config.py. Reproduce Laminar and Uvicorn INFO records and trace their handlers and streams. Add tests for INFO severity and stdout routing while confirming ERROR and CRITICAL logs remain errors.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend, observability
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100