All Products
Search
Document Center

Application Real-Time Monitoring Service:Monitor a Python application in an ACK cluster

Last Updated:Mar 11, 2026

Application Real-Time Monitoring Service (ARMS) collects traces, analyzes performance, and provides alerting for Python applications running in Container Service for Kubernetes (ACK) clusters -- without requiring code changes to your application.

Note

To monitor Python applications in other environments, see Application monitoring.

How it works

ARMS monitors Python applications in ACK through three components:

  1. ack-onepilot -- An ACK add-on that connects Java, Go, or Python applications deployed in ACK clusters to ARMS.

  2. aliyun-bootstrap -- A pip package that downloads and installs the ARMS Python agent in your container image.

  3. aliyun-instrument -- A wrapper command that initializes the ARMS agent for Python and instruments data in a non-intrusive way.

After setup, traces and metrics flow automatically from your application to the ARMS console, where you can view them in real time.

Prerequisites

Before you begin, make sure you have:

  • An ACK managed cluster, ACK dedicated cluster, or registered cluster. See Create an ACK managed cluster

  • A Python application that uses a supported framework or library

  • Application Monitoring activated with pay-by-observable-data billing enabled. A free monthly quota of 50 GB is included. Unused quota does not roll over. For pricing details, see Billing

Note

If your application uses Gevent, set the GEVENT_ENABLE environment variable to true.

Step 1: Install the ack-onepilot add-on

  1. Log on to the ACK console. On the Clusters page, click the name of your cluster.

  2. In the left-side navigation pane, click Add-ons. On the Add-ons page, search for ack-onepilot.

  3. In the ack-onepilot section, click Install. In the dialog box, click OK.

Important

The ack-onepilot version must be 3.2.4 or later.

ack-onepilot installation

Step 2: Update the Dockerfile

Add the ARMS agent to your container image by installing aliyun-bootstrap and wrapping your application startup command with aliyun-instrument.

Before (original Dockerfile)

# Use the base image for Python 3.10.
FROM docker.m.daocloud.io/python:3.10

# Set the working directory.
WORKDIR /app

# Copy the requirements.txt file to the working directory.
COPY requirements.txt .

# Install dependencies using pip.
RUN pip install --no-cache-dir -r requirements.txt

COPY ./app.py /app/app.py
# Expose port 8000 of the container.
EXPOSE 8000
CMD ["python","app.py"]

After (with ARMS agent)

# Use the base image for Python 3.10.
FROM docker.m.daocloud.io/python:3.10

# Set the working directory.
WORKDIR /app

# Copy the requirements.txt file to the working directory.
COPY requirements.txt .

# Install dependencies using pip.
RUN pip install --no-cache-dir -r requirements.txt

# Install the ARMS Python agent
RUN pip3 install aliyun-bootstrap && aliyun-bootstrap -a install

COPY ./app.py /app/app.py

# Expose port 8000 of the container.
EXPOSE 8000

# Start the application through the ARMS agent
CMD ["aliyun-instrument","python","app.py"]

The two added lines do the following:

LinePurpose
RUN pip3 install aliyun-bootstrap && aliyun-bootstrap -a installDownloads and installs the ARMS Python agent
CMD ["aliyun-instrument","python","app.py"]Starts the application with non-intrusive instrumentation
Note

If you use Gunicorn with Uvicorn workers, the startup command looks like this:

aliyun-instrument gunicorn -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000 app:app

After updating the Dockerfile, rebuild and push the image to your container registry.

Step 3: Add monitoring labels to the deployment YAML

Add labels to your Deployment's pod template so ack-onepilot can identify and instrument the application.

  1. In the left-side navigation pane of the ACK console, choose Workloads > Deployments. Select the namespace where your Deployment resides. Find the Deployment and choose More icon > Edit YAML in the Actions column.

  2. In the Edit YAML dialog box, add the following labels under spec.template.metadata and click Update: Replace <your-deployment-name> with a name for your application.

       labels:
         aliyun.com/app-language: python           # Specifies the application language.
         armsPilotAutoEnable: 'on'                  # Enables ARMS monitoring.
         armsPilotCreateAppName: "<your-deployment-name>"  # Sets the display name in ARMS.
  3. After the Deployment redeploys automatically, wait 1 to 2 minutes for monitoring data to appear. Open the ARMS console and choose Application Monitoring > Application List to verify. Your application should appear in the list. Click the application name to view its metrics. For more information, see View monitoring details.

Application list in ARMS

View monitoring data

Once monitoring data starts flowing, the ARMS console provides several tools to analyze application performance.

Trace Explorer

Trace Explorer provides real-time trace analysis with customizable filters and aggregation. Use it to identify slow or failed requests.

Trace Explorer

Click a trace to view the full call chain with timing breakdown for each span.

Trace details

LLM trace view

If your application uses large language models (LLMs), switch to the LLM view for per-operation input/output details and token consumption metrics.

LLM trace viewLLM call details

Metrics

The Application overview page shows request count, response time, and error rate.

Application overview

The Topology view maps dependencies between services, helping you identify bottlenecks and failure points across your microservice architecture.

Service topology

Set up alerting

Configure alert rules to receive notifications when application metrics exceed defined thresholds. Notifications can be sent to contacts or DingTalk group chats. For details, see Alert rules.

Alert rules

Clean up

After completing this tutorial:

  • To continue monitoring, make sure your Alibaba Cloud account has no overdue payments.

  • To stop monitoring, uninstall the ARMS agent.

(Optional) Deploy a sample application

If you do not have a Python application ready, use the following YAML template to deploy a demo client-server application. For more information, see Create a stateless application by using a Deployment.

The template creates the following resources in the arms-demo namespace:

Resource typeNameDescription
Deploymentarms-python-clientA FastAPI app that calls a LangChain LLM chain
Deploymentarms-python-serverA FastAPI app that calls the client service
Servicearms-python-client-svcExposes the client on port 8000
Servicearms-python-server-svcExposes the server on port 8000

View the complete YAML file

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: arms-python-client
  name: arms-python-client
  namespace: arms-demo
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: arms-python-client
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: arms-python-client
    spec:
      containers:
        - image: registry.cn-hangzhou.aliyuncs.com/private-mesh/arms-python-demo:client
          imagePullPolicy: Always
          name: client
          resources:
            requests:
              cpu: 250m
              memory: 300Mi
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30

---

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: arms-python-server
  name: arms-python-server
  namespace: arms-demo
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: arms-python-server
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: arms-python-server
    spec:
      containers:
        - env:
          - name: CLIENT_URL
            value: 'http://arms-python-client-svc:8000'
        - image: registry.cn-hangzhou.aliyuncs.com/private-mesh/arms-python-demo:server
          imagePullPolicy: Always
          name: server
          resources:
            requests:
              cpu: 250m
              memory: 300Mi
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30

---

apiVersion: v1
kind: Service
metadata:
  labels:
    app: arms-python-server
  name: arms-python-server-svc
  namespace: arms-demo
spec:
  internalTrafficPolicy: Cluster
  ipFamilies:
    - IPv4
  ipFamilyPolicy: SingleStack
  ports:
    - name: http
      port: 8000
      protocol: TCP
      targetPort: 8000
  selector:
    app: arms-python-server
  sessionAffinity: None
  type: ClusterIP

---

apiVersion: v1
kind: Service
metadata:
  name: arms-python-client-svc
  namespace: arms-demo
spec:
  internalTrafficPolicy: Cluster
  ipFamilies:
    - IPv4
  ipFamilyPolicy: SingleStack
  ports:
    - name: http
      port: 8000
      protocol: TCP
      targetPort: 8000
  selector:
    app: arms-python-client
  sessionAffinity: None
  type: ClusterIP

View the sample application code

arms-python-client

from fastapi import FastAPI
from langchain.llms.fake import FakeListLLM
import uvicorn
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate

app = FastAPI()
llm = FakeListLLM(responses=["I'll callback later.", "You 'console' them!"])

template = """Question: {question}

Answer: Let's think step by step."""

prompt = PromptTemplate(template=template, input_variables=["question"])

llm_chain = LLMChain(prompt=prompt, llm=llm)

question = "What NFL team won the Super Bowl in the year Justin Beiber was born?"

@app.get("/")
def call_langchain():
    res = llm_chain.run(question)
    return {"data": res}

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

arms-python-server

import uvicorn
from fastapi import FastAPI, HTTPException
from logging import getLogger
_logger = getLogger(__name__)
import requests
import os
app = FastAPI()

def call_client():
    url = 'https://www.aliyun.com'  # Replace it with the URL that you use.
    call_url = os.environ.get("CLIENT_URL")
    if call_url is None or call_url == "":
        call_url = url
    response = requests.get(call_url)
    print(f"response code: {response.status_code} - {response.text}")
    return response.text

@app.get("/")
async def call():
    call_client()
    return {"data": f"call"}


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

To monitor the sample application, follow steps 1 through 3 above, using arms-python-client and arms-python-server as the armsPilotCreateAppName values.

arms-python-client YAML with labelsarms-python-server YAML with labels

Related topics