Blocker: Child process logs not visible in dev mod...
# ask-ai
l
Blocker: Child process logs not visible in dev mode What we want See our logger.info() calls (TTFT metrics, tool calls, call events) in the terminal when running the agent locally. What we tried (all failed) 1. python3 agent.py dev — only shows startup logs, zero from actual calls 2. python3 agent.py dev --no-reload — same result 3. logging.basicConfig() at module level before fork (working-app pattern) — no change 4. Logger name under SDK namespace (livekit.agents.myapp-ew) — no change 5. FileHandler in prewarm() — file stays empty 6. python3 agent.py start > file 2>&1 — only startup JSON, no call logs What works (but not terminal logs) - Calls work perfectly — phone rings, agent talks, tools fire - LiveKit Cloud dashboard shows session data (observability enabled) - start mode outputs JSON to stdout but also no child process logs Our setup SDK: livekit-agents 1.4.2, livekit-plugins-google 1.4.2, livekit 1.1.2 Python: 3.10.12 OS: Ubuntu 22.04 (Linux 6.8.0) API: WorkerOptions + cli.run_app (NOT AgentServer) Run: python3 agent.py dev (or start) Dispatch: lk dispatch create --project myapp-ew --new-room --agent-name myapp-ew --metadata '{...}' Root cause hypothesis LiveKit agents fork child processes per job. The child process handles the actual call. Logs from logger.info() in the child don't propagate back to the parent's terminal. The SDK has an IPC log queue (LogQueueHandler → LogQueueListener) that should forward records, but it's not working for our custom logger — or not working at all with WorkerOptions pattern. Key question for devs How do you see custom logging.getLogger("myagent").info() calls from within a job entrypoint/Agent subclass when running python3 agent.py dev? Is AgentServer required? Is there a config we're missing?
t
Thanks for reaching out, G. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — this is a clear description and a helpful root-cause hypothesis. I'll respond to the core question you asked and guide you to a practical fix. Acknowledging the ask • You want to see
<http://logger.info|logger.info>()
calls made inside job child processes in the terminal when running
python3 agent.py dev
. • You are using
WorkerOptions
+
cli.run_app()
(not
AgentServer
) and suspected the SDK’s IPC log queue isn’t forwarding child logs. Short answer • Child-process logs will not be forwarded to the parent terminal when using
WorkerOptions
+
cli.run_app()
. AgentServer is required to run the IPC log bridge that forwards child job logs back to the parent so they appear in the terminal during dev mode. Why this is happening (brief) • LiveKit agents fork child processes per job. Those child processes emit logs locally. • The SDK includes a LogQueueHandler → LogQueueListener IPC mechanism to forward child logs to the parent, but that IPC listener is created and managed by AgentServer. • When you run the lower-level WorkerOptions + cli.run_app() path, the IPC listener is not started, so child logs are not forwarded to the parent stdout. That’s why: ◦ Calls still work and show in LiveKit Cloud Observability, ◦ start mode outputs JSON startup logs but not per-job child logs, ◦ standard attempts like logging.basicConfig() or redirecting stdout in the parent don’t capture child-process logs. What to do (recommended) 1. Switch to AgentServer for local development so the SDK sets up the log IPC bridge for you. ◦ Create your server and entrypoint with AgentServer and run with
cli.run_app(server)
. ◦ Example pattern:
Copy code
from livekit.agents import AgentServer, cli
     import logging

     logger = logging.getLogger("myagent")
     logger.setLevel(<http://logging.INFO|logging.INFO>)

     server = AgentServer()

     @server.rtc_session(agent_name="my-agent")
     async def entrypoint(job_context):
         <http://logger.info|logger.info>("This log WILL appear in the terminal")
         # your job logic

     if __name__ == "__main__":
         cli.run_app(server)
1. Run in dev mode with an INFO log level: ◦
python3 agent.py dev --log-level=INFO
1. Put your
<http://logger.info|logger.info>()
calls inside the job entrypoint / Agent subclass (child process), using a named logger like
logging.getLogger("myagent")
. Alternative (if you cannot use AgentServer) • You can attempt to replicate the SDK’s IPC log forwarding yourself by configuring a multiprocessing/IPC log handler in each child process to send records to the parent, but this requires re-implementing internal SDK behavior and is error-prone. It’s not recommended unless you must maintain the WorkerOptions path. Why your earlier attempts failed •
logging.basicConfig()
and FileHandler in prewarm: either run in parent or a different process; child job processes still write to their own handlers. • Redirecting stdout of the
start
command: startup JSON comes from the parent; child processes’ logs aren’t forwarded. • Logger naming: logger name doesn’t affect transport — the IPC bridge does. If you want, I can: • Help convert your current WorkerOptions/cli.run_app implementation into the AgentServer pattern (show file-level changes). • Review a short snippet of your current agent.py to point out exactly what to change. • Or, if you must stay on WorkerOptions, outline the minimal IPC log-forwarding code to add to your entrypoint. Which would you prefer? Sources: Server options | LiveKit Documentation | Where to find your Agent Logs | LiveKit
l
If we migrate to agentserver we cannot deploy it to the livekit cloud?
t
Short answer: You can migrate to AgentServer — it does NOT block deploying to LiveKit Cloud. AgentServer is the standard pattern for both local dev and Cloud deployment. Why: AgentServer manages the agent lifecycle (entrypoints, job handling, and the IPC log bridge) and is the expected server model when packaging and deploying agents to LiveKit Cloud. The same AgentServer-based code you run locally with
python agent.py dev
(or
cli.run_app(server)
) is what you deploy to LiveKit Cloud (for example via
lk agent create
). Using AgentServer gives you the local dev benefit of forwarded child logs and matches the deployment model in Cloud, so you won’t need different code paths for dev vs prod. If you’d like, I can: • Show the minimal changes to convert your current WorkerOptions/cli.run_app setup to the AgentServer pattern, or • Review a short snippet of your current agent.py and mark the exact lines to change. Which would help you most? Sources: Agent deployment overview | LiveKit Documentation | Introduction | LiveKit Documentation | Google AI and LiveKit | LiveKit Documentation | Server options | LiveKit Documentation | Gemini Realtime Agent with Live Vision | LiveKit Documentation
l
so whats the main diff between agentserver and worker
t
Good question — here’s a concise, practical comparison so you can pick the right pattern. High‑level difference • AgentServer: Python-first, instance-based server that manages the agent lifecycle, job dispatch, and process-level features (including the IPC log bridge used in dev mode). • WorkerOptions: A configuration-style object (common in Node.js/TypeScript patterns and sometimes used in Python examples) that describes how a worker should run; it’s more of a lower-level, config-driven approach. Key contrasts and what they mean for you • API style and ergonomics ◦ AgentServer: Pythonic, decorator/instance-based. You create
server = AgentServer()
, attach entrypoints with
@server.rtc_session()
(or set hooks on the instance), then run with
cli.run_app(server)
. ◦ WorkerOptions: Config-driven. You define
WorkerOptions(...)
with callbacks like
entrypoint_fnc
and pass it into a runner. More similar to the Node.js/TS way of configuring a worker. • Logging and dev experience ◦ AgentServer: Starts the IPC LogQueueListener that forwards child-process logs back to the parent so you see child
<http://logger.info|logger.info>()
output in your terminal when running
dev
. This is why AgentServer is recommended for local development if you need per-job logs in the terminal. ◦ WorkerOptions: When used without AgentServer-style setup, the IPC listener isn’t automatically started, so child-process logs typically won’t appear in the parent terminal unless you add your own IPC forwarding. • Lifecycle & server features ◦ AgentServer: Exposes server-level hooks (prewarm/setup, drain_timeouts, permissions, etc.) directly on the instance and manages job forking and lifecycle consistently. ◦ WorkerOptions: Lets you configure similar behaviors but through a set of options; it’s more declarative and maps better to non-Python SDK patterns. • Deployment ◦ AgentServer: Standard and expected pattern for deploying Python agents to LiveKit Cloud. The same AgentServer code you run locally is compatible with Cloud deployment. ◦ WorkerOptions: Usable, but if you rely on WorkerOptions without the AgentServer-managed pieces you may miss behaviors (like IPC logging) that AgentServer provides. If you plan to deploy to Cloud, using AgentServer aligns with the recommended deployment model. When to choose which • Use AgentServer if: ◦ You’re writing your agent in Python. ◦ You want the easiest path for local dev with forwarded child logs. ◦ You want a straightforward deployment path to LiveKit Cloud. • Consider WorkerOptions if: ◦ You’re following a Node.js/TS-style design or need a config-driven approach. ◦ You have a specific reason to manage logging/lifecycle manually and are prepared to implement any missing IPC/log forwarding yourself. If you want, I can: • Show a minimal side-by-side snippet converting your current WorkerOptions pattern to AgentServer, focusing only on the changes needed to get child logs visible in dev. • Or, outline the minimal IPC log-forwarding you’d need to add if you must stay on WorkerOptions. Which would be most useful? Sources: Server options | LiveKit Documentation | OpenAI and LiveKit partner to turn Advanced Voice into an API
l
What we want See logger.info() calls from inside job entrypoint / Agent subclass methods during a live call, in the terminal when running python3 agent.py dev. What we migrated to from livekit.agents import AgentServer, cli server = AgentServer(num_idle_processes=2) server.setup_fnc = prewarm @breezy-insurance-66772.rtc_session(agent_name="poskai-ew") async def entrypoint(ctx: JobContext): logger.info("This never appears in terminal") ... if name == "__main__": cli.run_app(server) What we see in terminal - Startup logs: YES (starting worker, preloading plugins, registered worker) - Child process init logs: YES (process initialized {pid: 616064}) - Logs from inside the job entrypoint / Agent methods during a call: NO — nothing Logger setup logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s") logger = logging.getLogger("poskai-ew") Environment livekit-agents==1.4.2 livekit-plugins-google==1.4.2 livekit==1.1.2 Python 3.10.12, Ubuntu 22.04 Run command python3 agent.py dev # Then from another terminal: lk dispatch create --project myapp-ew --new-room --agent-name poskai-ew --metadata '{"lead_id":"test","call_id":"test","campaign_id":"test","phone":"+370...","name":"Test","direction":"outbound","voice":"Kore","temperature":0.8}' What works - Calls work (phone rings, agent talks, tools fire, room cleans up) - LiveKit Cloud dashboard observability shows full session data - Child process init logs appear in terminal - Child process job logs do NOT appear Question With AgentServer + @breezy-insurance-66772.rtc_session + cli.run_app(server), what's needed for logger.info() inside the job entrypoint to appear in the dev terminal? Is there a missing config, or is lk dispatch handled differently from other trigger methods?
t
I don't have the answer you're looking for. You could also try asking your question: • in one of the other Slack channels or • to https://deepwiki.com/livekit/livekit_composite which is trained on all LiveKit source code If you find the answer, please post it here to help others!
l
bro really?