Azure Container Apps
Monitor Azure Container Apps with logging using Event Hub integration with OpenTelemetry collector and Last9
Use OpenTelemetry to instrument your Azure Container Apps and send logs to Last9.
This guide outlines the steps to setup Azure Container Apps to send logs to Last9 using OpenTelemetry Collector as a sidecar container.
Prerequisites
Before setting up Azure Container Apps monitoring, ensure you have:
- Azure Container Apps
- Event Hubs
- Last9 account with integration credentials
-
Setup Azure Container Apps Environment
Enable logging for the environment of container app to
Azure Monitor. -
Create Event Hubs Infrastructure
Create Event Hubs namespace with name
last9in same region as the container app.Create Event hub in
last9namespace with namelogs-hub. -
Configure Diagnostic Settings
Add Diagnostic Setting for the container app and enable necessary logs (console, system or both) to be sent to Event hub created in Step 2.
-
Setup Event Hub Access Policy
Visit Event hub and setup a Shared Access Policy with following details:
- Scope: Listen
- Name: last9-logs
-
Get Connection String
Copy the Primary connection string displayed after creating the shared access policy. It will look like following:
Endpoint=sb://oteldemo.servicebus.windows.net/;SharedAccessKeyName=last9;SharedAccessKey=<access_key>;EntityPath=oteldemo -
Run OpenTelemetry Collector
Run the OpenTelemetry Collector to pull logs from Event hub and send them to Last9. You can run this on a standalone VM or even locally as Docker Container.
Create directory on the machine where you want to run the OpenTelemetry Collector:
mkdir last9-otel-collectorcd last9-otel-collectormkdir -p storagechmod 777 storageCreate otel.yaml:
receivers:azureeventhub:connection: <event_hub_primary_connection_string>storage: file_storage/otlpformat: "azure"apply_semantic_conventions: trueprocessors:batch:timeout: 5ssend_batch_size: 20000send_batch_max_size: 20000transform/azure_logs:error_mode: ignoreflatten_data: truelog_statements:- context: logstatements:- merge_maps(attributes, body, "insert")- flatten(attributes)# Set body to actual log message- set(body, attributes["properties.Log"])- delete_key(attributes, "properties.Log")# Set service name to container name- set(resource.attributes["service.name"], attributes["properties.ContainerAppName"])# Handle Severity mapping- set(severity_text, "TRACE") where Int(severity_text) >= 1 and Int(severity_text) <= 4- set(severity_text, "DEBUG") where Int(severity_text) >= 5 and Int(severity_text) <= 8- set(severity_text, "INFO") where Int(severity_text) >= 9 and Int(severity_text) <= 12- set(severity_text, "WARN") where Int(severity_text) >= 13 and Int(severity_text) <= 16- set(severity_text, "ERROR") where Int(severity_text) >= 17 and Int(severity_text) <= 20- set(severity_text, "FATAL") where Int(severity_text) >= 21 and Int(severity_text) <= 24transform/add_timestamp:error_mode: ignoreflatten_data: truelog_statements:- context: logconditions:- time_unix_nano == 0statements:- set(observed_time, Now())- set(time_unix_nano, observed_time_unix_nano)exporters:debug:verbosity: detailedotlp/last9:endpoint: "{{ .Logs.WriteURL }}"headers:"Authorization": "{{ .Logs.AuthValue }}"service:extensions: [file_storage/otlp]pipelines:logs:receivers: [azureeventhub]processors: [transform/azure_logs, transform/add_timestamp, batch]exporters: [otlp/last9]extensions:file_storage/otlp:directory: /storagecreate_directory: truetimeout: 10scompaction:directory: /storageon_rebound: truecheck_interval: 1s -
Deploy OpenTelemetry Collector
Create docker-compose.yaml:
services:otel-collector:image: otel/opentelemetry-collector-contrib:latestcontainer_name: otel-collectorvolumes:- ./otel.yaml:/etc/otel-collector/config.yaml- ./storage:/storagecommand:["--config","/etc/otel-collector/config.yaml","--feature-gates","transform.flatten.logs",]restart: unless-stoppedStart the docker container:
docker compose upIf you don’t want to use docker compose, directly start the container:
docker run -d \--name otel-collector \--restart unless-stopped \-v "$(pwd)/otel.yaml:/etc/otel-collector/config.yaml" \-v "$(pwd)/storage:/storage" \otel/opentelemetry-collector-contrib:latest \--config /etc/otel-collector/config.yaml \--feature-gates transform.flatten.logsInstall the Collector:
sudo apt-get updatesudo apt-get -y install wget systemctlwget https://github.com/open-telemetry/opentelemetry-collector-releases/releases/download/v0.118.0/otelcol-contrib_0.118.0_linux_amd64.debsudo dpkg -i otelcol-contrib_0.118.0_linux_amd64.debStart the collector:
otelcol-contrib --config $(pwd)/otel.yaml --feature-gates transform.flatten.logs
Verification
Once the Otel collector is running, the logs will be sent to Last9. You can verify this by checking the Logs Explorer in Last9.
Need Help?
If you encounter any issues or have questions:
- Join our Discord community for real-time support
- Contact our support team at support@last9.io