hi there
# ask-ai
b
hi there
t
Thanks for reaching out, Jupiter. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Hi — thanks for reaching out! How can I help you today? If you’re not sure where to start, you can tell me: • What you're trying to build with LiveKit (web, mobile, server-side). • Any error messages or unexpected behavior you’re seeing. • Room or project IDs and timestamps for troubleshooting (if applicable). I’ll take it from there.
b
I want to create a logger for my livekit application, do for me
t
Thanks — I can help build a logger. A few quick questions so I deliver the right code and steps: 1. Which platform and language is your LiveKit app using? (e.g., JavaScript/Node, TypeScript, React Web, Android/Kotlin, iOS/Swift, Go, Python) 2. Do you want client-side logging (in participants' apps), server-side logging (your backend/game server), or both? 3. What should the logger capture? (examples: connection events, room join/leave, track publish/unpublish, errors, stats like bitrate/packet loss, custom app events) 4. Where should logs be stored/viewed? (console only, files, remote logging service like Datadog/Logflare/Sentry, or cloud storage) 5. Desired format/leveling? (structured JSON, plain text, levels: debug/info/warn/error) 6. Any retention/rotation or privacy considerations (PII redaction)? Reply with answers and I’ll provide a ready-to-use implementation and setup steps.
b
I use python, and desired format is plain text with timestamp
t
Great — I can build that. A couple quick clarifying questions so I deliver the right Python logger: 1. Is this for the server-side (your backend using the LiveKit server SDK or REST APIs) or client-side (a Python client connecting to a room)? 2. Which events do you want logged at minimum? (connection/room join/leave, track publish/unpublish, errors, stats like bitrate/packet loss, or custom app events) 3. Where should logs be written? (console only, file on disk, or forwarded to a remote service) 4. Any specific timestamp format you prefer? (e.g., ISO 8601 like 2025-12-23T150405Z) Answer those and I’ll provide a ready-to-use Python implementation (plain-text logs with timestamps) and setup steps.
b
client side, logs be written to console and file, use IS0 8601
t
Thanks — I’ll build the logger. I just need two final details so I deliver exactly what you want: 1. Which Python LiveKit client library are you using (official LiveKit Python client, aiortc-based custom client, or other)? 2. What minimum events should be logged (pick from: connection, room join/leave, local publish/unpublish, remote subscribe/unsubscribe, errors, periodic stats)? Default will be connection, room join/leave, publish/unpublish, and errors. Reply with those two answers and I’ll provide a ready-to-run Python logger (console + file) that writes plain-text ISO 8601 timestamps and example integration showing where to attach to client events. Sources: Job lifecycle | LiveKit docs | How to Send Logs from the JavaScript SDK to Providers like Datadog | VAD Metrics | LiveKit docs | TTS Metrics | LiveKit docs | LLM Metrics | LiveKit docs
b
yes official livekit python client, and use default events
t
Thanks — I’ll provide a ready-to-use Python logger for the official LiveKit Python client that logs the default events (connection, room join/leave, publish/unpublish, errors) to both console and a file in plain-text with ISO 8601 timestamps, plus a short example of how to wire it into a LiveKit client. 1) Logger implementation (save as e.g.
livekit_logger.py
)
Copy code
import logging
from logging.handlers import RotatingFileHandler
from datetime import datetime, timezone

ISO_FORMAT = "%Y-%m-%dT%H:%M:%S%z"

class ISOFormatter(logging.Formatter):
    def formatTime(self, record, datefmt=None):
        # Use UTC ISO 8601 with timezone Z
        dt = datetime.fromtimestamp(record.created, tz=timezone.utc)
        return dt.strftime("%Y-%m-%dT%H:%M:%SZ")

def setup_logger(name: str,
                 logfile: str = "livekit_client.log",
                 level=<http://logging.INFO|logging.INFO>,
                 max_bytes: int = 10 * 1024 * 1024,
                 backup_count: int = 3):
    """
    Creates a logger that writes plain-text messages prefixed with ISO 8601 timestamps
    to both console and a rotating file.
    """
    logger = logging.getLogger(name)
    logger.setLevel(level)
    logger.propagate = False

    fmt = "%(asctime)s %(levelname)s %(name)s: %(message)s"
    formatter = ISOFormatter(fmt)

    # Console handler
    ch = logging.StreamHandler()
    ch.setLevel(level)
    ch.setFormatter(formatter)

    # Rotating file handler
    fh = RotatingFileHandler(logfile, maxBytes=max_bytes, backupCount=backup_count)
    fh.setLevel(level)
    fh.setFormatter(formatter)

    # Clear existing handlers to avoid duplicates if called multiple times
    if logger.hasHandlers():
        logger.handlers.clear()

    logger.addHandler(ch)
    logger.addHandler(fh)

    return logger
2) Example integration with the official LiveKit Python client • This example assumes you are using the official LiveKit Python client and have an async client/room connection. Adjust event hooks to match the specific client API you use.
Copy code
import asyncio
from livekit import Room, RoomOptions  # adjust imports to match your LiveKit client package
from livekit_logger import setup_logger

logger = setup_logger("livekit_client", logfile="livekit_client.log")

async def on_connected():
    <http://logger.info|logger.info>("Connected to LiveKit server")

async def on_disconnected():
    <http://logger.info|logger.info>("Disconnected from LiveKit server")

async def on_joined_room(room_name: str, participant_id: str):
    <http://logger.info|logger.info>(f"Joined room '{room_name}' as participant '{participant_id}'")

async def on_left_room(room_name: str, participant_id: str):
    <http://logger.info|logger.info>(f"Left room '{room_name}' as participant '{participant_id}'")

async def on_local_track_published(track_id: str, kind: str):
    <http://logger.info|logger.info>(f"Published local track id={track_id} kind={kind}")

async def on_local_track_unpublished(track_id: str, kind: str):
    <http://logger.info|logger.info>(f"Unpublished local track id={track_id} kind={kind}")

async def on_error(exc: Exception):
    logger.error(f"Error: {exc}", exc_info=True)

async def main():
    # Create/connect your Room/client here (example is schematic)
    room = Room()  # replace with actual client constructor and connection logic

    # Hook into events - adjust to match the client's event API
    # Examples (pseudo-code, adapt to actual LiveKit Python client event names):
    room.on("connected", lambda: asyncio.create_task(on_connected()))
    room.on("disconnected", lambda: asyncio.create_task(on_disconnected()))
    room.on("room_joined", lambda room_name, pid: asyncio.create_task(on_joined_room(room_name, pid)))
    room.on("room_left", lambda room_name, pid: asyncio.create_task(on_left_room(room_name, pid)))
    room.on("published", lambda track_id, kind: asyncio.create_task(on_local_track_published(track_id, kind)))
    room.on("unpublished", lambda track_id, kind: asyncio.create_task(on_local_track_unpublished(track_id, kind)))
    room.on("error", lambda exc: asyncio.create_task(on_error(exc)))

    # Connect / run client per your app flow
    await room.connect("<wss://your-livekit-server>", token="YOUR_TOKEN")

if __name__ == "__main__":
    asyncio.run(main())
3) Notes and quick customization • The logger writes plain-text lines like: 2025-12-23T150405Z INFO livekit_client: Joined room 'myroom' as participant 'user123' • File rotation is enabled (default 10MB, 3 backups). Change
max_bytes
/
backup_count
in
setup_logger
. • If you prefer local timezone instead of UTC, modify
ISOFormatter.formatTime
. • Adapt the event names/hooks in the integration code to the exact official LiveKit Python client API you have — the example shows the pattern for wiring event callbacks to the logger. If you’d like, I can: • Provide the exact integration code for the specific LiveKit Python client version you’re using (tell me the package name and version). • Add periodic stats logging (bitrate/packet loss) or redact PII before logging. Which would you like next?