@@ -71,97 +71,91 @@ Build the `Datadog.AzureFunctions` NuGet package with your changes:
7171.\tracer\tools\Build-AzureFunctionsNuget.ps1 -BuildId 12345 -CopyTo D:\temp\nuget -Verbose
7272```
7373
74- ### 2. Deploy to Azure
74+ ### 2. Deploy and Test Function
7575
76- Navigate to sample app and deploy :
76+ Use the ` Deploy-AzureFunction.ps1 ` script to automate deployment, wait, and trigger :
7777
78- ``` bash
79- cd D:/source/datadog/serverless-dev-apps/azure/functions/dotnet/isolated-dotnet8-aspnetcore
80- dotnet restore
81- func azure functionapp publish lucasp-premium-linux-isolated-aspnet
78+ ``` powershell
79+ .\tracer\tools\Deploy-AzureFunction.ps1 `
80+ -AppName "lucasp-premium-linux-isolated-aspnet" `
81+ -ResourceGroup "lucas.pimentel" `
82+ -SampleAppPath "D:\source\datadog\serverless-dev-apps\azure\functions\dotnet\isolated-dotnet8-aspnetcore" `
83+ -Verbose
8284```
8385
84- ** IMPORTANT** : Wait 1-2 minutes after deployment for the worker process to restart before testing.
86+ ** What this does** :
87+ 1 . Runs ` dotnet restore ` in the sample app directory
88+ 2 . Publishes to Azure with ` func azure functionapp publish `
89+ 3 . Waits 2 minutes for worker process to restart
90+ 4 . Triggers the HTTP endpoint and captures execution timestamp
91+ 5 . Outputs a result object for pipeline usage
92+
93+ ** Options** :
94+ - ` -SkipBuild ` - Skip ` dotnet restore `
95+ - ` -SkipWait ` - Skip 2-minute wait (not recommended)
96+ - ` -WaitSeconds 60 ` - Custom wait duration
97+ - ` -SkipTrigger ` - Skip HTTP trigger
98+ - ` -TriggerUrl "https://..." ` - Custom trigger URL
8599
86100** Default app** : If no app name specified, use ` lucasp-premium-linux-isolated-aspnet `
87101
88- ### 3. Test Function
89-
90- Trigger the HTTP test endpoint:
91-
92- ``` bash
93- curl https://lucasp-premium-linux- isolated-aspnet.azurewebsites.net/api/HttpTest
102+ ** Pipeline usage ** (save output for log analysis):
103+ ``` powershell
104+ $deploy = .\tracer\tools\Deploy-AzureFunction.ps1 `
105+ -AppName "lucasp-premium-linux-isolated-aspnet" `
106+ -ResourceGroup "lucas.pimentel" `
107+ -SampleAppPath "D:\source\datadog\serverless-dev-apps\azure\functions\dotnet\ isolated-dotnet8-aspnetcore"
94108```
95109
96- ** Note ** : Azure URL pattern uses base name without ` -aspnet ` suffix for this specific app.
110+ ### 3. Download and Analyze Logs
97111
98- ** Capture timestamp** when triggering (for log analysis):
99- ``` bash
100- echo " Triggered at $( date -u +%Y-%m-%d\ %H:%M:%S) UTC"
101- ```
112+ Use the ` Get-AzureFunctionLogs.ps1 ` script to download, extract, and analyze logs:
102113
103- ### 4. Download and Analyze Logs
104-
105- ** Download logs** :
106- ``` bash
107- az functionapp log download \
108- --name lucasp-premium-linux-isolated-aspnet \
109- --resource-group lucas.pimentel \
110- --log-path D:/temp/logs-$( date +%H%M%S) .zip
114+ ``` powershell
115+ .\tracer\tools\Get-AzureFunctionLogs.ps1 `
116+ -AppName "lucasp-premium-linux-isolated-aspnet" `
117+ -ResourceGroup "lucas.pimentel" `
118+ -ExecutionTimestamp "2026-01-23 17:53:00" `
119+ -All `
120+ -Verbose
111121```
112122
113- ** Extract logs** :
114- ``` bash
115- cd D:/temp
116- unzip -q -o logs-* .zip
117- ls -la LogFiles/datadog/
123+ ** What this does** :
124+ 1 . Downloads logs from Azure to a timestamped zip file
125+ 2 . Extracts the archive
126+ 3 . Identifies host and worker log files
127+ 4 . Analyzes tracer version, span count, and trace parenting
128+
129+ ** Analysis options** :
130+ - ` -ShowVersion ` - Display Datadog tracer version from worker logs
131+ - ` -ShowSpans ` - Count spans at execution timestamp (split by host/worker)
132+ - ` -CheckParenting ` - Validate trace parenting (detect root span duplication)
133+ - ` -All ` - Enable all analysis (recommended)
134+
135+ ** Pipeline usage** (with Deploy script):
136+ ``` powershell
137+ $deploy = .\tracer\tools\Deploy-AzureFunction.ps1 `
138+ -AppName "lucasp-premium-linux-isolated-aspnet" `
139+ -ResourceGroup "lucas.pimentel" `
140+ -SampleAppPath "D:\source\datadog\serverless-dev-apps\azure\functions\dotnet\isolated-dotnet8-aspnetcore"
141+
142+ .\tracer\tools\Get-AzureFunctionLogs.ps1 `
143+ -AppName $deploy.AppName `
144+ -ResourceGroup "lucas.pimentel" `
145+ -ExecutionTimestamp $deploy.ExecutionTimestamp `
146+ -All
118147```
119148
120149** Log file patterns** :
121150- ** Host process** : ` dotnet-tracer-managed-Microsoft.Azure.WebJobs.Script.WebHost-{pid}.log `
122151- ** Worker process** : ` dotnet-tracer-managed-dotnet-{pid}.log `
123152
124- ** CRITICAL** : Always filter logs by timestamp - never use head/tail on downloaded files:
125-
126- ``` bash
127- # Replace with actual execution timestamp
128- grep " 2026-01-23 17:53:" LogFiles/datadog/dotnet-tracer-managed-dotnet-* .log
129- ```
130-
131- ** Why** : Log files are append-only and contain entries from multiple deployments/restarts.
132-
133- ### 5. Verify Tracer Version
134-
135- Check the worker loaded the expected version:
136-
137- ``` bash
138- # Find most recent initialization
139- grep " Assembly metadata" LogFiles/datadog/dotnet-tracer-managed-dotnet-* .log | tail -1
140-
141- # Verify version in recent logs
142- grep " 2026-01-23 17:53:" LogFiles/datadog/dotnet-tracer-managed-dotnet-* .log | grep " TracerVersion" | head -1
143- ```
144-
145- ### 6. Analyze Trace Context Flow
146-
147- ** Find host trace ID** :
148- ``` bash
149- grep " 2026-01-23 17:53:39" LogFiles/datadog/dotnet-tracer-managed-Microsoft.Azure.WebJobs.Script.WebHost-* .log | grep " Span started"
150- ```
151-
152- ** Check worker spans use same trace ID** :
153- ``` bash
154- # Replace with actual trace ID from above
155- grep " 68e948220000000047fef7bad8bb854e" LogFiles/datadog/dotnet-tracer-managed-dotnet-* .log
156- ```
157-
158- ** Span fields** :
159- - ** s_id** (span ID): Unique identifier for this span
160- - ** p_id** (parent ID): Span ID of parent span (` null ` = root span)
161- - ** t_id** (trace ID): Trace this span belongs to
153+ ** CRITICAL** : The script automatically filters logs by execution timestamp. Raw log files are append-only and contain entries from multiple deployments/restarts.
162154
163- ** Healthy trace** : Worker spans have same ` t_id ` as host and ` p_id ` matching host span IDs
164- ** Broken trace** : Worker spans have different ` t_id ` or ` p_id: null ` (orphaned root)
155+ ** Parenting analysis** :
156+ - ** Span fields** : ` s_id ` (span ID), ` p_id ` (parent ID), ` t_id ` (trace ID)
157+ - ** Healthy trace** : Worker spans have same ` t_id ` as host, ` p_id ` matching host span IDs
158+ - ** Broken trace** : Worker spans have different ` t_id ` or ` p_id: null ` (orphaned root)
165159
166160## Verification Checklist
167161
0 commit comments