This document shows how to instrument your Dify application.
Component overview
workflow application (LLM application): An LLM application built using the Dify visual interface, which typically exists as a workflow or a chatbot. It defines the application's logic, prompts, model selection, variable handling, conditional branching, and tool calls.
dify-api (execution engine API): Dify's core backend service, which receives frontend requests, manages data, schedules workflow executions, invokes large language models, coordinates plugin calls, and returns results.
dify-plugin-daemon (plugin engine): Dify's plugin engine that securely executes user-defined or official plugins in an isolated environment.
nginx (ingress gateway): Dify's ingress gateway for distributing incoming traffic.
If you use Dify through the ack-dify component in Container Service for Kubernetes (ACK), we recommend performing a one-click integration by updating the Helm chart. You can update the ack-dify component on the Applications page of your ACK cluster.
In the parameter configuration of the update release page, search for the arms field and set enabled to true.
Alternatively, you can enable application monitoring by configuring the settings when you create the ack-dify component.
In the Parameter Configuration step of the YAML editor, set arms.enabled to true, appName to "dify", and applicationType to "Dify", and then click OK to complete the creation.
Prerequisites
ack-onepilot 5.1.2 or later.
Python agent 2.2.0 or later.
Procedure
Step 1: Instrument the dify-api
Choose a method based on your Dify API deployment:
(Recommended) Automatic instrumentation for K8s containers: Follow the instructions in Install the Python agent by using the ack-onepilot component for ACK and ACS to add the following labels to your Dify API's Deployment:
labels: apsara.apm/application-type: Dify aliyun.com/app-language: python # Required for Python applications. armsPilotAutoEnable: 'on' armsPilotCreateAppName: "deployment-name" # The display name of the application in ARMS.Obtain the entrypoint.sh startup script and make the following changes:
Add the following commands at the beginning of the script to uninstall conflicting plugins and install the Python agent.
python3 -m ensurepip --upgrade# Uninstall conflicting OTel plugins. pip3 uninstall -y opentelemetry-instrumentation-celery \ opentelemetry-instrumentation-flask \ opentelemetry-instrumentation-redis \ opentelemetry-instrumentation-requests \ opentelemetry-instrumentation-logging \ opentelemetry-instrumentation-wsgi \ opentelemetry-instrumentation-fastapi \ opentelemetry-instrumentation-asgi \ opentelemetry-instrumentation-sqlalchemy# Install the Python agent. pip3 config set global.index-url https://mirrors.aliyun.com/pypi/simple/ && pip3 config set install.trusted-host mirrors.aliyun.com pip3 install aliyun-bootstrap && aliyun-bootstrap -a installAdd the
aliyun-instrumentcommand to the startup section at the end of the script.# Start with aliyun-instrument. exec aliyun-instrument gunicorn \ --bind "${DIFY_BIND_ADDRESS:-0.0.0.0}:${DIFY_PORT:-5001}" \ --workers ${SERVER_WORKER_AMOUNT:-1} \ --worker-class ${SERVER_WORKER_CLASS:-gevent} \ --worker-connections ${SERVER_WORKER_CONNECTIONS:-10} \ --timeout ${GUNICORN_TIMEOUT:-200} \ app:app
Configure the environment variables.
Parameter
Value
Description
GEVENT_ENABLE
true
Dify uses gevent. This variable must be set to
true.ARMS_APP_NAME
dify-api
The application name.
ARMS_REGION_ID
cn-heyuan
The ID of your region.
ARMS_LICENSE_KEY
xxx
Your License Key.
APSARA_APM_APP_TYPE
microservice
Identifies the application as a microservice.
2. To view monitoring data for the dify-api component, find the dify-api application in the Application Monitoring list. The Application Overview page displays the following monitoring data:
Summary metric cards: requests, errors, average latency, instances, and day-over-day changes
Time-series charts: Requests/1m, Errors/1m and error rate, Latency/1m, CPU utilization
Top 5 rankings: request count, error count, average latency
The trace shows information about upstream and downstream calls.
The trace details page shows the TraceID, total duration, number of applications, and number of spans at the top. The middle section contains a span timeline Gantt chart showing the duration distribution of each span. The call tree on the lower left displays the complete call path from the /console/api gateway entry to the Dify API endpoints and database queries in a hierarchical structure. The span details panel on the right shows attributes such as the application name, endpoint, IP address, spanId, parentSpanId, and status code.
Step 2: Instrument the Dify workflow
1.6.0 < dify-api version < 1.11.2
To instrument a single application, see Enable observability for a Dify application and configure the settings for your Dify application.
To instrument multiple applications in bulk, see Bulk integration for Dify LLM application monitoring.
dify-api version <= 1.6.0 or version >= 1.11.2
The Dify workflow application requires no extra configuration. If you instrumented the dify-api component in the previous step, the trace data from the workflow is automatically collected and correlated.
dify-api version >= 1.13.0
See Configure OTel for Dify and set the required environment variables on the dify-worker component. To obtain the OTel endpoint, see Prerequisites.
View workflow monitoring data
The application details page contains the following tabs: Overview, Performance Analysis, Token Analysis, LLM Operations, Provided Services, Dependent Services, Trace Analysis, Exception Analysis, and Session Analysis. The Overview tab displays the following monitoring data:
Key metric cards: Model Calls, Token Usage (with day-over-day comparison), Traces, Spans, Sessions, and Users
Operation type distribution pie chart (TASK, TOOL, CHAIN, LLM, RETRIEVER)
Line charts for average LLM calls per request, request count trend, and session count trend
Model Call Ranking (Top 5) bar chart and Request Count User Ranking (Top 5) table
Trace details example: The trace details include node information, such as LLM calls, retrieval, and tool invocation.
The trace details page displays a waterfall chart on the left that shows step nodes (types include CHAIN, TOOL, TASK, LLM, and RETRIEVER), each with a Gantt chart time bar. The panel on the right shows detailed information about the selected node, including the application name, endpoint, hostname, spanId, parentSpanId, and status code. The Additional Information section at the bottom allows you to view the input and output message content of the node, such as JSON input for alert analysis and root cause analysis results.
Step 3: Instrument the dify-plugin-daemon
Modify the Dockerfile and rebuild the corresponding image. The following code shows an example of a modified local.dockerfile:
FROM golang:1.23-alpine AS builder ARG VERSION=unknown # copy project COPY . /app # set working directory WORKDIR /app # using goproxy if you have network issues # ENV GOPROXY=https://goproxy.cn,direct # download arms instgo RUN wget "http://arms-apm-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/instgo/instgo-linux-amd64" -O instgo RUN chmod 777 instgo # instgo build RUN INSTGO_EXTRA_RULES="dify_python" ./instgo go build \ -ldflags "\ -X 'github.com/langgenius/dify-plugin-daemon/internal/manifest.VersionX=${VERSION}' \ -X 'github.com/langgenius/dify-plugin-daemon/internal/manifest.BuildTimeX=$(date -u +%Y-%m-%dT%H:%M:%S%z)'" \ -o /app/main cmd/server/main.go # copy entrypoint.sh COPY entrypoint.sh /app/entrypoint.sh RUN chmod +x /app/entrypoint.sh FROM ubuntu:24.04 WORKDIR /app # check build args ARG PLATFORM=local # Install python3.12 if PLATFORM is local RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y curl python3.12 python3.12-venv python3.12-dev python3-pip ffmpeg build-essential \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* \ && update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.12 1; # preload tiktoken ENV TIKTOKEN_CACHE_DIR=/app/.tiktoken # Install dify_plugin to speedup the environment setup, test uv and preload tiktoken RUN mv /usr/lib/python3.12/EXTERNALLY-MANAGED /usr/lib/python3.12/EXTERNALLY-MANAGED.bk \ && python3 -m pip install uv \ && uv pip install --system dify_plugin \ && python3 -c "from uv._find_uv import find_uv_bin;print(find_uv_bin());" \ && python3 -c "import tiktoken; encodings = ['o200k_base', 'cl100k_base', 'p50k_base', 'r50k_base', 'p50k_edit', 'gpt2']; [tiktoken.get_encoding(encoding).special_tokens_set for encoding in encodings]" ENV UV_PATH=/usr/local/bin/uv ENV PLATFORM=$PLATFORM ENV GIN_MODE=release COPY --from=builder /app/main /app/entrypoint.sh /app/ # run the server, using sh as the entrypoint to avoid process being the root process # and using bash to recycle resources CMD ["/bin/bash", "-c", "/app/entrypoint.sh"]NoteThe
INSTGO_EXTRA_RULESoption enables automatic monitoring of the plugin runtime. To prevent the plugin agent from launching with the plugin-daemon, removeINSTGO_EXTRA_RULES="dify_python"from the build file.Configure the environment variables:
For ECS environments:
Parameter
Value
Description
ARMS_LICENSE_KEY
xxx@xxx
Your License Key.
ARMS_REGION_ID
cn-heyuan
Your region ID.
ARMS_ENABLE
true
Enables or disables the agent.
ARMS_APP_NAME
dify-plugin-daemon
The application name.
For containerized ack-onepilot environments: In the YAML configuration for the dify-plugin-daemon application, add the following labels under spec.template.metadata.
labels: aliyun.com/app-language: golang armsPilotAutoEnable: 'on' armsPilotCreateAppName: "dify-daemon-plugin"
Deploy and view monitoring data for dify-plugin-daemon. On the application list page, navigate to the dify-plugin-daemon application. The application overview page displays the following monitoring information:
Metric cards: Requests, Errors, Average Latency, and Instances, with day-over-day and week-over-week changes
Trend charts: Requests/1m bar chart, Errors/1m line chart, Latency/1m line chart (with P99, P90, and P75 percentiles), and Peak CPU Utilization ring chart
Top 5 ranking panels: Request Count, Error Count, Average Latency, and Peak CPU Utilization by Instance
The trace waterfall chart shows the call chain details of
insight-agent-plugin-daemon. The key spans include:GET (python/redis, 1.95 ms)
connect (python/sqlalchemy)
SELECT dify (sqlalchemy, 34.95 ms)
/v1/sandbox/runmulti-layer calls (POST httpx → SERVER go net_http_server → INTERNAL, approximately 28–30 ms)UPDATE dify (sqlalchemy, 2.38 ms)
The details panel on the right shows the hostname, start time, end time, spanId, parentSpanId, status code, and an Attributes list (such as
net.protocol.name,component.name, andendpoint) for the selected span.View monitoring data for plugins. After you install the agent, the plugin-daemon automatically starts the agent for the plugin runtime. Each plugin runtime corresponds to a separate observable application, named in the format {plugin_daemon_name}_plugin_{plugin_name}_{plugin_version}. For example, if your plugin-daemon application is named local-dify-plugin-daemon and you have installed version 0.0.53 of the tongyi plugin, an application named local-dify-plugin-daemon_plugin_tongyi_0.0.53 is automatically created. The plugin monitoring overview page displays the following information:
Top tabs: Application Overview, Application Topology, Provided Services, Dependent Services, Trace Analysis, Instance Monitoring, Scenario Analysis, and Application Configuration
Key metric cards: requests, errors, average latency, and instances (with day-over-day and week-over-week changes)
Time-series charts: trends for request count, error count, latency, and peak CPU utilization
Top 5 rankings: request count, error count, and average latency, showing plugin endpoint-level calls (such as
invoke_llm,get_ai_model_schemas, andinvoke_rerank)
(Optional) Step 4: Monitor the code sandbox
The code sandbox is Dify's code execution engine, which runs Python/Node.js code within a workflow. You can use the Go agent to monitor the sandbox. To do so, modify the Dockerfile, rebuild the image, and configure the environment variables.
Modify the build/build_[amd64|arm64].sh file and rebuild the corresponding image.
Add the command to download instgo. The following code shows an example. For download commands for other regions and architectures, see Download instgo.
wget "http://arms-apm-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/instgo/instgo-linux-amd64" -O instgo chmod 777 instgoAdd the
instgocommand beforego build. The following code shows an example for the amd64 architecture:rm -f internal/core/runner/python/python.so rm -f internal/core/runner/nodejs/nodejs.so rm -f /tmp/sandbox-python/python.so rm -f /tmp/sandbox-nodejs/nodejs.so wget "http://arms-apm-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/instgo/instgo-linux-amd64" -O instgo chmod 777 instgo echo "Building Python lib" CGO_ENABLED=1 GOOS=linux GOARCH=amd64 ./instgo go build -o internal/core/runner/python/python.so -buildmode=c-shared -ldflags="-s -w" cmd/lib/python/main.go && echo "Building Nodejs lib" && CGO_ENABLED=1 GOOS=linux GOARCH=amd64 ./instgo go build -o internal/core/runner/nodejs/nodejs.so -buildmode=c-shared -ldflags="-s -w" cmd/lib/nodejs/main.go && echo "Building main" && GOOS=linux GOARCH=amd64 ./instgo go build -o main -ldflags="-s -w" cmd/server/main.go echo "Building env" GOOS=linux GOARCH=amd64 ./instgo go build -o env -ldflags="-s -w" cmd/dependencies/init.go
Configure the environment variables.
For K8s container deployments: In the YAML configuration for the dify-plugin-daemon application, add the following labels under spec.template.metadata.
labels: aliyun.com/app-language: golang armsPilotAutoEnable: 'on' armsPilotCreateAppName: "dify-daemon-plugin"For manual integration:
Parameter
Value
Description
ARMS_LICENSE_KEY
xxx
Your License Key.
ARMS_REGION_ID
cn-heyuan
Your region ID.
ARMS_ENABLE
true
Enables or disables the agent.
ARMS_APP_NAME
dify-plugin-daemon
The application name.
Deploy and view monitoring data for the sandbox. On the application list page, navigate to the dify-sandbox application. The Application Overview tab displays the following summary metrics:
Requests: 3,051.00 (1.60% day-over-day)
Errors: 0.00 (0% day-over-day)
Average Latency: 47.7 ms (1.36% day-over-day)
Instances: 9 (0% week-over-week)
The time-series charts show Requests/1m, Errors/1m, Latency/1m (with P99, P90, and P75 curves), and CPU utilization. The Top 5 Provided Services ranking shows the primary request path as
/v1/sandbox/runwith 3,051 requests, 0 errors, and an average latency of 47.7 ms.The ARMS trace details page shows a trace with a total duration of 8.7 seconds, spanning 5 applications and 1,039 endpoints, with detected anomalies. Component tags include redis (575), sqlalchemy (337), net_http_server (16), and httpx (14). The span waterfall chart shows the multi-layer call chain from
SELECT difyto/v1/sandbox/run POST 200, illustrating the complete path of Dify calling the sandbox. The span details panel shows the application name insight-agent-sandbox, endpoint/v1/sandbox/run, hostnamesandbox-7489d68cd5-xcqv8, with a normal status code. The Attributes section shows fields such asnet.protocol.name,component.name, and other detailed information.
(Optional) Step 5: Monitor the Nginx ingress gateway
Nginx is Dify's ingress gateway. Nginx configuration issues can cause timeouts and file upload failures for the knowledge base, plugins, and workflows. To monitor Nginx, see Trace Nginx with OpenTelemetry and use the OpenTelemetry method to report data.
Configuration
Input/output content collection
Default: True (enabled by default).
Effect when disabled: For user queries, detailed fields such as the input and output of models, tools, and the knowledge base, only their size is collected, not their content.
How to configure: Set the environment variable OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=False.
Split LLM applications
Default: False (disabled by default).
Effect when enabled: Reported data is split into LLM sub-applications. Each LLM application, such as a Dify workflow, agent, or chatbot, corresponds to a separate application in ARMS.
How to configure: Set the environment variable PROFILER_GENAI_SPLITAPP_ENABLE=True.
Supported regions: China (Heyuan), Singapore.
Message content length limit
Default: 4,000 characters.
Effect when enabled: Limits the length of each LLM message content field, such as input or output. Message content that exceeds the specified length is truncated.
Applicable plugins: This setting is currently supported only by Dify and LangChain.
How to configure: If your agent version is 1.8.3 or later, set the environment variable OTEL_INSTRUMENTATION_GENAI_MESSAGE_CONTENT_MAX_LENGTH=<integer_value>. Replace <integer_value> with the desired character limit.
Span attribute value length limit
Default: No limit.
Effect when enabled: Limits the length of reported span attribute values, such as gen_ai.agent.description. Attribute values that exceed the specified length are truncated.
Applicable plugins: This configuration applies to all OpenTelemetry-compatible plugins, such as LangChain, DashScope, and Dify.
How to configure: Set the environment variable OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT=<integer_value>. Replace <integer_value> with the desired character limit.