This solution provides a Python-based listener for Optimizely Agent that forwards notifications to Google Analytics and Amplitude.
The solution consists of the following components:
main.py
- Core application that connects to Optimizely Agent's SSE (Server-Sent Events) endpoint and processes notifications.notification_listener.py
- Module for listening to Optimizely Agent notification stream.notification_processor.py
- Module for processing notifications and routing them to analytics platforms.event_buffer.py
- Module for buffering events to handle high volumes and retries.google_analytics.py
- Module for sending metrics to Google Analytics.amplitude.py
- Module for sending metrics to Amplitude.logger_config.py
- Module for configuring logging.Dockerfile
- Container definition for running the listener in a Kubernetes pod.requirements.txt
- Python dependencies required by the solution.decide_testing.py
- Utility script for simulating production traffic patterns to test the listener.
The application is configured using environment variables:
OPTIMIZELY_SDK_KEY
- Your Optimizely SDK key
OPTIMIZELY_AGENT_BASE_URL
- Base URL of the Optimizely Agent (default:http://localhost:8080
)NOTIFICATION_FILTER
- Filter for specific notification types (e.g.,decision
)
GA_MEASUREMENT_ID
- Google Analytics measurement IDGA_API_SECRET
- Google Analytics API secretGA_DEBUG_MODE
- Set to "true" to enable debug mode (default: "false")
AMPLITUDE_API_KEY
- Amplitude API keyAMPLITUDE_TRACKING_URL
- Amplitude tracking URL (default:https://api2.amplitude.com/2/httpapi
)
Before running the listener, you need to have an instance of Optimizely Agent running. The easiest way to do this is using Docker:
docker run -d -p 8080:8080 -p 8085:8085 -p 8088:8088 -e OPTIMIZELY_LOG_PRETTY=true -e OPTIMIZELY_SERVER_HOST=0.0.0.0 -e OPTIMIZELY_SERVER_ALLOWEDHOSTS=localhost,127.0.0.1 -e OPTIMIZELY_API_ENABLENOTIFICATIONS=1 --rm optimizely/agent
This command:
- Runs the Optimizely Agent container in detached mode
- Maps the necessary ports (8080, 8085, 8088) to your local machine
- Configures the agent to accept requests from localhost
- Enables the notification stream (required for the listener)
- Automatically removes the container when it stops
- Remove the
-d
flag to run the container in the foreground (for debugging)
You can verify the agent is running correctly by accessing the configuration endpoint:
curl -X GET "http://localhost:8080/v1/config" -H "X-Optimizely-SDK-Key: YOUR_SDK_KEY"
For local development, you can run the listener directly on your machine using a virtual environment:
- Create a virtual environment:
# On Windows
python -m venv venv
# On macOS/Linux
python3 -m venv venv
- Activate the virtual environment:
# On Windows
venv\Scripts\activate
# On macOS/Linux
source venv/bin/activate
- Install the required dependencies:
pip install -r requirements.txt
- Copy the sample environment file to create your local configuration:
# On Windows
copy .env.sample .env
# On macOS/Linux
cp .env.sample .env
-
Edit the
.env
file with your actual configuration values. -
Run the listener:
python main.py
The script will automatically load environment variables from the .env
file if it exists.
You can test the listener by sending requests to the Optimizely Agent's decide endpoint. The included decide_testing.py
script simulates production traffic patterns:
# Run the testing script
python decide_testing.py
This will send requests with varying user IDs (400-500 by default) at random intervals to simulate real-world traffic patterns.
Build the container:
docker build -t optimizely-agent-listener .
Run the container with proper environment variables:
docker run -d \
--name optimizely-agent-listener \
-e OPTIMIZELY_SDK_KEY=<your-sdk-key> \
-e OPTIMIZELY_AGENT_BASE_URL=http://optimizely-agent:8080 \
-e GA_MEASUREMENT_ID=<your-ga-id> \
-e GA_API_SECRET=<your-ga-secret> \
-e AMPLITUDE_API_KEY=<your-amplitude-key> \
optimizely-agent-listener
The listener is designed to run as a third container in the same pod as the application and Optimizely Agent. Here's an example snippet to add to your existing Kubernetes pod configuration:
- name: optimizely-agent-listener
image: optimizely-agent-listener:latest
env:
- name: OPTIMIZELY_SDK_KEY
valueFrom:
secretKeyRef:
name: optimizely-secrets
key: sdk-key
- name: OPTIMIZELY_AGENT_BASE_URL
value: "http://localhost:8080" # Since running in same pod
- name: GA_MEASUREMENT_ID
valueFrom:
secretKeyRef:
name: analytics-secrets
key: ga-id
- name: GA_API_SECRET
valueFrom:
secretKeyRef:
name: analytics-secrets
key: ga-secret
- name: AMPLITUDE_API_KEY
valueFrom:
secretKeyRef:
name: analytics-secrets
key: amplitude-key
- An example PHP website sends requests to the Optimizely Agent for decisions and to track events.
- The listener connects to the Agent's SSE endpoint to receive notifications.
- When a notification is received, it is processed and forwarded to:
- Google Analytics using the Measurement Protocol
- Amplitude using their HTTP API
- All API keys and secrets are passed via environment variables and should be stored securely.
- The container is based on the official Python 3.13 slim image for minimal attack surface.
- No sensitive data is logged in the application logs.
The listener includes robust error handling with:
- Automatic reconnection if the SSE connection is lost
- Exponential backoff for retry attempts
- Event buffering to handle temporary failures
- Detailed logging for troubleshooting
- Graceful handling of configuration errors
All dependencies are pinned to specific versions for stability in the requirements.txt
file.