-
Notifications
You must be signed in to change notification settings - Fork 6
How to diagnose codeless startup
When you enable the profiler codelessly (via the Windows App Service
site extension or the Linux enable
script), activation happens very early in the startup sequence — before your
app's Main runs. That makes its diagnostics easy to miss in the normal log
stream. This page shows how to capture and read a full startup trace.
Before digging into logs, restart the app and give it a couple of minutes:
- Restart the app from the Azure Portal (App Service → Overview → Restart). Restart from the portal, not from Kudu — a full site restart is required, not just an SCM/Kudu restart. The injected environment variables only take effect on a fresh worker process, so a restart is required after installing, upgrading, or changing settings.
- Send some traffic to the app so a request pipeline actually starts.
- Wait ~2 minutes for the worker to recycle, the profiler to activate, and the first trace to be captured and uploaded.
Then check Application Insights (Investigate → Performance → Profiler) or the startup log below. Many "it's not working" reports resolve simply because the app wasn't restarted or wasn't given enough time.
Set the SP_STARTUP_LOG environment variable, then restart the app.
| Value | Behavior |
|---|---|
| unset / empty | Off — standard output only (the default). |
1 or true
|
On — writes to the default log path (below). |
| any other value | On — treated as an explicit log file path. |
Windows App Service: add the app setting under App Service → Settings → Environment variables → App settings:
SP_STARTUP_LOG = 1
Linux App Service: the enable script sets this for you when you pass
--debug (enable-linux-appservice.sh) or -DebugLog
(Enable-LinuxAppService.ps1).
With SP_STARTUP_LOG = 1, the log is written under the App Service persistent
root:
-
Windows:
D:\home\LogFiles\AzureMonitorProfiler\startup_<pid>.log -
Linux:
/home/LogFiles/AzureMonitorProfiler/startup_<pid>.log
Read it through Kudu (https://<your-app>.scm.azurewebsites.net) or via log
streaming. Files are per-process (<pid>), so the app worker and the platform
worker never overwrite each other.
Startup-file logging is fail-safe: if the file can't be written, it falls back to standard output and never affects app startup.
Each line is formatted as UTC-timestamp [PID <pid>] <level> <component>: <message>. On a successful activation you'll see the stack detection followed by
the matching profiler being enabled — for an OpenTelemetry app:
[Azure.Monitor.OpenTelemetry.Profiler.StartupHook] Detected telemetry stack: OpenTelemetry
[Azure.Monitor.OpenTelemetry.Profiler.StartupHook] Assembly resolver installed. Probe order: ...\payload\<version>\otel, ...\payload\<version>
[Azure.Monitor.OpenTelemetry.Profiler.HostingStartup] info: Detected a supported OpenTelemetry-based telemetry stack. Enabling the Azure Monitor OpenTelemetry profiler.
A classic Application Insights app shows the same pattern routed to the classic
payload instead.
-
"Detected telemetry stack: None" / nothing activated. The app doesn't reference a supported telemetry stack (or has no
*.deps.jsonto scan). Add OpenTelemetry (Azure.Monitor.OpenTelemetry.AspNetCoreorMicrosoft.ApplicationInsights.AspNetCore3.x) or classic Application Insights SDK ≥ 2.23.0 and < 3.0.0, then redeploy. -
Codeless backed off because a profiler NuGet is already referenced. If your app references
Azure.Monitor.OpenTelemetry.ProfilerorMicrosoft.ApplicationInsights.Profiler.AspNetCore, codeless enablement intentionally does nothing to avoid enabling the profiler twice. The app is expected to activate the profiler in its own code. -
A dependency is below the supported floor. The log names the assembly and the required minimum (for example,
OpenTelemetry≥ 1.8.1 orAzure.Core≥ 1.46.1). The profiler skips activation and the app keeps running. Upgrade the named dependency and redeploy. -
Invalid or missing connection string. With a missing or malformed
APPLICATIONINSIGHTS_CONNECTION_STRING, the profiler disables itself (logged) but the app keeps running. Set a valid connection string for traces to capture and upload. -
No profiler lines at all in the log. The injection likely never ran. Confirm the environment variables and the Kudu transform log (see Confirm the injection was applied) and that the app was restarted. On non-.NET stacks (Node.js, Python, Java, PHP) the enablement is a safe no-op and produces no profiler output.
If you see no startup logs at all, the codeless injection itself may not have
been applied. On Windows App Service the site extension injects three environment
variables into the worker via an applicationHost.xdt transform that Kudu applies
on install:
| Environment variable | Points to |
|---|---|
DOTNET_STARTUP_HOOKS |
…\payload\<version>\Azure.Monitor.OpenTelemetry.Profiler.StartupHook.dll |
ASPNETCORE_HOSTINGSTARTUPASSEMBLIES |
Azure.Monitor.OpenTelemetry.Profiler.HostingStartup |
SP_UPLOADER_PATH |
…\payload\<version>\Uploader\Microsoft.ApplicationInsights.Profiler.Uploader.dll |
Check the variables on the running process. In Kudu
(https://<your-app>.scm.azurewebsites.net) open Process explorer, select the
app worker — the w3wp process whose APP_POOL_ID equals the site name, not
the ~1-prefixed SCM/Kudu worker — and inspect its environment variables (or use
the REST API: GET /api/processes then GET /api/processes/<pid>/environ).
Confirm all three variables are present and point to the extension's payload
folder.
Because these variables are set globally, they also appear on the SCM/Kudu worker. Always verify the app worker, not the
~1SCM worker.
Check the transform log in Kudu. When the extension installs, Kudu applies the
applicationHost.xdt transform and writes a log for it under
C:\home\LogFiles\Transform (Kudu → Debug console →
LogFiles/Transform). Review the most recent transform log for errors. If the
transform didn't apply, the variables above will be missing.
No injection means no logs. If the transform never applied (install error, or the variables aren't on the app worker), the
StartupHookandHostingStartupnever run — so there will be noSP_STARTUP_LOGoutput at all. In that case, don't look for startup logs: confirm the environment variables and the Kudu transform log first, then reinstall the extension and restart.