Auto-discover your Container Apps and stream logs in real time. No code changes, no agents to install. Deploy ZenoLog as a Container App and get instant visibility into your entire environment.
Three steps to visibility across your ACA environment.
ZenoLog polls the ARM API to find all Container Apps in your environment, their active revisions, and running replicas.
Select which apps to stream from the Web UI, TUI, or API. Choose specific containers or stream all of them.
Container stdout/stderr flows into ZenoLog's ring buffers with Azure resource attributes, searchable alongside your OTLP logs.
Authenticate with system or user-assigned Managed Identity. No secrets to rotate. Falls back to DefaultAzureCredential for local dev with az login.
Polls the ARM API every 30 seconds (configurable). Detects new apps, removed apps, and replica changes automatically.
Run ACA and K8s discovery simultaneously. Multi-provider architecture with unified search, tail, and source management.
ZenoLog automatically excludes itself from discovery when running as a Container App. No log feedback loops.
All settings via environment variables with the ZENOLOG_ACA_ prefix.
| Variable | Default | Description |
|---|---|---|
| ZENOLOG_ACA_ENABLED | false | Enable ACA discovery (true, auto, or false) |
| ZENOLOG_ACA_SUBSCRIPTION_ID | required | Azure subscription ID containing the ACA environment |
| ZENOLOG_ACA_RESOURCE_GROUP | required | Resource group containing the ACA environment |
| ZENOLOG_ACA_ENVIRONMENT | required | Name of the ACA Managed Environment |
| ZENOLOG_ACA_CLIENT_ID | optional | User-assigned Managed Identity client ID (if omitted, uses system MI or DefaultAzureCredential) |
| ZENOLOG_ACA_POLL_INTERVAL | 30s | How often to poll ARM API for app changes |
| ZENOLOG_ACA_MAX_STREAMS | 100 | Maximum concurrent log stream goroutines |
| ZENOLOG_ACA_EXCLUDE_APPS | none | Comma-separated app names to exclude from discovery |
ZenoLog needs access to discover and stream logs from your Container Apps. Assign the built-in ContainerApp Contributor role, or create a custom role for least-privilege.
Enable system MI on the ZenoLog Container App and assign the ContainerApp Contributor role. No configuration needed beyond the three required env vars.
Create a user-assigned MI, assign it to the ZenoLog app, and set ZENOLOG_ACA_CLIENT_ID to its client ID. Useful when sharing identities across apps.
For local development, run az login or set AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, and AZURE_TENANT_ID. Handled automatically by DefaultAzureCredential.
Two commands to get ZenoLog running in your ACA environment.
az containerapp create \
--name zenolog \
--resource-group my-rg \
--environment my-env \
--image jimmytoenners/zenolog:0.3.4 \
--min-replicas 1 --max-replicas 1 \
--ingress external --target-port 8081 \
--system-assigned \
--env-vars \
ZENOLOG_ACA_ENABLED=true \
ZENOLOG_ACA_SUBSCRIPTION_ID=<subscription-id> \
ZENOLOG_ACA_RESOURCE_GROUP=my-rg \
ZENOLOG_ACA_ENVIRONMENT=my-env
# Assign ContainerApp Contributor role to the system MI
az role assignment create \
--assignee $(az containerapp show -n zenolog -g my-rg \
--query identity.principalId -o tsv) \
--role "ContainerApp Contributor" \
--scope /subscriptions/<subscription-id>/resourceGroups/my-rg