FERR guard in `FunctionEnvironmentReloadInstrumentation` skips identity-based storage on Functions Flex Consumption
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 68/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Ít trao đổi
- Công nghệ
- azure, java
- Lĩnh vực
- observability
Hướng nghiên cứu
Bắt đầu trong agent/instrumentation/azure-functions/.../FunctionEnvironmentReloadInstrumentation.java và kiểm tra bộ bảo vệ môi trường storage trước khi FERR advice gọi AzureFunctions.configureOnce(). Đọc AzureFunctions.java, SecondEntryPoint.java và AzureFunctionsInitializer.java để hiểu đường dẫn chuyên biệt hóa hiện có. Hoàn thành khi storage dựa trên identity đi đến cùng luồng chuyên biệt hóa mà không thay đổi hành vi opt-in, đồng thời các triệu chứng Flex được báo cáo đã được giải quyết.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Summary
On Azure Functions Flex Consumption (Linux, Java) using identity-based storage (no AzureWebJobsStorage connection string, only AzureWebJobsStorage__accountName + AzureWebJobsStorage__credential), the Application Insights Java agent never runs its specialization initializer. As a result, custom logs are not correlated to operation_Id and sampling stays at the cold default (sampled=false on exported spans, no exports).
The agent's FunctionEnvironmentReloadInstrumentation aborts when the bare AzureWebJobsStorage env var is absent. On identity-based Flex apps that env var is intentionally not set, so the FERR (FunctionEnvironmentReload) signal that should trigger the agent's specialization is dropped.
Environment
- Azure Functions Flex Consumption, Linux
- Java 17 (also reproduces with other Java versions on Flex)
host.json:"telemetryMode": "OpenTelemetry", extension bundle[4.*, 5.0.0)- AI Java agent: 3.7.6 (image-bundled at
/azure-functions-host/workers/java/agent/applicationinsights-agent.jar) - Storage: identity-based (
AzureWebJobsStorage__accountName/AzureWebJobsStorage__credential, no bareAzureWebJobsStorage)
Observed symptoms
- Custom logs from function code arrive in App Insights
traceswith nooperation_Id. - Worker-side OpenTelemetry spans show
sampled=false; downstream sampling decisions are stuck at 0. - The agent's diagnostic log does not emit
Application Insights Java Agent specialized successfullyorApplication Insights Java Agent disabledafter FERR.
Background: how the agent specializes on Flex
The Java worker's worker.config.json selects an AppInsightsPlaceholder profile when env INITIALIZED_FROM_PLACEHOLDER=true. That profile loads -javaagent:applicationinsights-agent.jar with -DLazySetOptIn=false. The agent installs bytecode transformers at premain, but the telemetry pipeline (exporter, sampler, connection string, role name) cannot be configured at premain because no app is assigned yet. So configuration is deferred to specialization:
SecondEntryPointregistersAzureFunctions.setup(hasConnectionString, AzureFunctionsInitializer).- On FERR,
FunctionEnvironmentReloadInstrumentationadvice callsAzureFunctions.configureOnce(), which runs theAzureFunctionsInitializerlazily. AzureFunctionsInitializer.run()consults the opt-in gate (APPLICATIONINSIGHTS_ENABLE_AGENTenv or-DLazySetOptInsys prop). If enabled, it reads the connection string and applies the runtime config.
Root cause
FunctionEnvironmentReloadInstrumentation has this early return:
if (System.getenv("AzureWebJobsStorage") == null) {
return;
}
On identity-based Flex workers this env var is absent (storage is configured via AzureWebJobsStorage__accountName + AzureWebJobsStorage__credential), so the advice returns before invoking AzureFunctions.configureOnce(). The agent stays in its pre-specialization state for the life of the worker. The presence of AzureWebJobsStorage__accountName is not considered.
This was empirically confirmed with an A/B on the same app:
State of AzureWebJobsStorage |
hasConnectionString after FERR |
Worker span exports |
|---|---|---|
| absent (identity-based default) | not consulted, agent never specializes | 0, sampled=false |
| present (bare conn string added) | true, agent specializes | full exports, sampled=true |
Reproduction
- Create a Flex Consumption Java function app with identity-based storage (do not set a bare
AzureWebJobsStorageapp setting). - Set
host.json->"telemetryMode": "OpenTelemetry". - Deploy an HTTP function that logs via
context.getLogger()and emits a worker-side OpenTelemetry span. - Invoke it after specialization (avoid forcing a cold start). Observe:
tracesrows have nooperation_Id.- Worker spans have
sampled=falseand no exports. - Agent diagnostic log lacks the specialization message.
Workarounds and drawbacks
Workaround A: Add a bare AzureWebJobsStorage connection string AND set APPLICATIONINSIGHTS_ENABLE_AGENT=true
Both app settings are required together. Adding only one is not sufficient.
AzureWebJobsStorage=<full connection string>makes the FERR guard pass so the agent's specialization runs.APPLICATIONINSIGHTS_ENABLE_AGENT=trueflips the agent's opt-in gate to true so specialization actually configures the telemetry pipeline (instead of self-disabling). This second setting is required because Flex Consumption does not auto-set it the way Linux Dedicated does. On a portal-created Linux Dedicated Java app,APPLICATIONINSIGHTS_ENABLE_AGENT=trueis added to app settings automatically by the Functions / App Service provisioning layer when Application Insights is configured. On Flex, this auto-set does not happen, so users must set it explicitly. This is a Functions platform gap, not an agent bug, and is tracked separately.
Drawbacks:
- Storing a bare
AzureWebJobsStorageconnection string defeats the purpose of identity-based storage. The connection string is a long-lived account key on app settings, exactly what identity-based storage is intended to eliminate. - Two settings must be coordinated. Missing either silently degrades telemetry, and the failure mode is hard to diagnose without reading the agent code.
Workaround B: Force the worker to restart after the app is assigned (e.g. set languageWorkers__java__arguments to a harmless value)
The restarted worker still receives the Placeholder profile and loads the agent with -DLazySetOptIn=false, but because the app is already assigned by the time the new worker starts, APPLICATIONINSIGHTS_CONNECTION_STRING is present in the process env when premain runs. SecondEntryPoint configures the telemetry client at premain, hasConnectionString() returns true, and configureOnce() short-circuits at FERR. The opt-in gate is never consulted, so neither APPLICATIONINSIGHTS_ENABLE_AGENT nor LazySetOptIn matters. The FERR guard also no longer matters because the lazy path is bypassed.
Drawbacks:
- Every worker recycle and scale-out pays a full Java cold start. For Java workloads this is the most expensive part of placeholder warm-start to lose.
Suggested fix
Relax the FERR guard in FunctionEnvironmentReloadInstrumentation so identity-based storage is also accepted. Options:
- Also treat the worker as Functions-storage-configured when
AzureWebJobsStorage__accountNameis present. - Or remove the guard entirely. The FERR signal itself is the trigger that matters; the guard exists to filter out non-Functions reloads, but the FERR advice path is already Functions-specific.
The first option preserves the original intent of the guard while fixing the identity-based case. Either way, no agent-default change is needed; the existing APPLICATIONINSIGHTS_ENABLE_AGENT opt-in continues to work the same way it does on Linux Dedicated.
Related (not part of this issue)
The need to explicitly set APPLICATIONINSIGHTS_ENABLE_AGENT=true on Flex is a Functions platform gap: Linux Dedicated portal-created apps get this set for the user automatically, Flex does not. That is being tracked separately with the Functions Flex team and is not a bug in this agent. It is mentioned here only so that users following Workaround A have the full picture.
References (code paths)
agent/instrumentation/azure-functions/.../FunctionEnvironmentReloadInstrumentation.java(the guard)agent/agent-bootstrap/.../AzureFunctions.java(configureOnce,hasConnectionString)agent/agent-tooling/.../init/SecondEntryPoint.java(AzureFunctions.setupwiring)agent/agent-tooling/.../init/AzureFunctionsInitializer.java(run,isAgentEnabled,initialize)agent/instrumentation/azure-functions/.../InvocationInstrumentation.java(sampling override gated onhasConnectionString)
- Ngôn ngữ chính
- Java
- Star
- 327
- Fork
- 222
- Merge trung bình
- 22 giờ 34 phút
- Pull request đã merge (30 ngày)
- 14
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của microsoft/ApplicationInsights-Java
-
microsoft/ApplicationInsights-Java#4851 · 1 người được giao ·
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 45/100
microsoft/ApplicationInsights-Java#4817 · 1 bình luận ·
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 42/100
microsoft/ApplicationInsights-Java#4770 · 2 bình luận ·
-
Support for tail based sampling? Đang mở
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 30/100
microsoft/ApplicationInsights-Java#4769 · 2 bình luận ·
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 35/100
microsoft/ApplicationInsights-Java#4729 · 121 bình luận ·
Tất cả issue của microsoft/ApplicationInsights-Java
Issue tương tự
-
documentation
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
inu-appcenter/memorIN-backend#288 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
-
frontend maui-pilot pilot-ask question
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
-
executions.Query — startDate and timeRange filters are sent with inverted comparison operators Đang mởarea/plugin
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
kestra-io/plugin-kestra#190 ·