big-application-86058
12/21/2025, 9:16 PMtall-airline-16756
12/21/2025, 9:16 PMtall-airline-16756
12/21/2025, 9:16 PMbig-application-86058
12/21/2025, 9:17 PMcli.run_app(
WorkerOptions(
entrypoint_fnc=entrypoint,
agent_name=agent_name,
prewarm_fnc=AgentEntrypoint.prewarm,
initialize_process_timeout=float(os.getenv("INITIALIZE_PROCESS_TIMEOUT", 30)),
job_memory_warn_mb=float(os.getenv("MEMORY_WARN_MB", 2500)),
job_memory_limit_mb=float(os.getenv("MEMORY_LIMIT_MB", 3000)),
),
)tall-airline-16756
12/21/2025, 9:18 PMcli.run_app (e.g., create handlers, call logging.basicConfig, or add a FileHandler)?
2. Which logger/name are you attaching your file handler to (root logger or a named logger)?
3. Are the duplicates written to both console and file, or only file?
4. Which agent/CLI mode are you running (start or dev) and how do you invoke it (command line flags)?
5. Can you paste the minimal logging setup code you use (the few lines that add handlers or set levels)?
Based on your answers I’ll show the minimal change to prevent double-handlers (examples include checking existing handlers before adding, removing duplicate handlers, or configuring logging after cli.run_app).
Sources: Agent server options | LiveKit docs | Simple Call Answering Agent | LiveKit docsbig-application-86058
12/21/2025, 9:19 PM_logging_configured = False
def setup_logging():
"""Configure file logging without duplicates"""
global _logging_configured
if _logging_configured:
return
root = logging.getLogger()
# Check if we already have a file handler for livekit.log
has_file_handler = any(
isinstance(h, logging.FileHandler) and h.baseFilename.endswith('livekit.log')
for h in root.handlers
)
if not has_file_handler:
# Remove only file handlers pointing to livekit.log to prevent duplicates
for handler in root.handlers[:]:
if isinstance(handler, logging.FileHandler) and handler.baseFilename.endswith('livekit.log'):
root.removeHandler(handler)
# Add file handler
file_handler = logging.FileHandler('livekit.log')
file_handler.setLevel(<http://logging.INFO|logging.INFO>)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
root.addHandler(file_handler)
_logging_configured = True
setup_logging()tall-airline-16756
12/21/2025, 9:19 PMsetup_logging and what you described, here are concise, safe next steps to eliminate duplicates and confirm whether cli.run_app is adding handlers.
1) Quick checks (run before and after calling cli.run_app)
• Print current handlers to see what’s being added:
import logging
root = logging.getLogger()
print([type(h).__name__ + ":" + getattr(h, "baseFilename", "stream") for h in root.handlers])
If you see another FileHandler or handlers added after cli.run_app, that confirms duplication.
2) Low-risk fixes you can try
• Configure logging after cli.run_app returns (so your file handler is only added once).
• Or, remove duplicate handlers just before adding yours:
for handler in root.handlers[:]:
if isinstance(handler, logging.FileHandler) and handler.baseFilename.endswith('livekit.log'):
root.removeHandler(handler)
# then add your file handler
Your code already does this removal check — ensure it runs after cli.run_app if cli.run_app is the one adding handlers.
3) Use a named logger instead of the root logger
• Avoid side effects on framework logging by attaching your file handler to a module-specific logger:
logger = logging.getLogger("<http://my.app|my.app>")
logger.addHandler(file_handler)
Log via that logger (<http://logger.info|logger.info>(...)) and leave framework logs on the root logger.
4) Prevent double propagation (if you use a child logger)
• If you attach to a named logger and still see duplicates, disable propagation:
logger.propagate = False
5) If you prefer detecting additions automatically
• Keep your _logging_configured guard but detect new handlers after cli.run_app and remove them, or record handler identities before calling cli.run_app and remove any new ones that match file targets.
If you’d like, tell me:
• The handler list output from step 1 (before/after cli.run_app), and
• Whether you can move your setup_logging() call to run after cli.run_app returns.
I’ll recommend the exact code change once I see that output.
Sources: Simple Call Answering Agent | LiveKit docs