-
Notifications
You must be signed in to change notification settings - Fork 4
Azure monitoring alerts and logging improvements #88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
- fix: dependabot build fails (no secrets) - remove hard-coded location etc. - add alerts (prod)
📝 WalkthroughWalkthroughThis PR adds Bicep-based alerting for the Function App, updates Function App infrastructure and CI/CD workflows to support alert deployment and tag-based resource operations, introduces structured logging and timeout settings for the Functions runtime, and adds comprehensive logging and monitoring documentation while removing an existing DEPLOYMENT doc. Changes
Sequence Diagram(s)mermaid Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🚀 Deployed to Azure FunctionsEnvironment: This environment will be automatically cleaned up when the PR is closed. |
- logs not appearing in App Insights
🚀 Deployed to Azure FunctionsEnvironment: This environment will be automatically cleaned up when the PR is closed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (8)
.github/workflows/dotnet.yml (1)
49-60: Consider duplicate comment prevention.The step will run on every Dependabot PR workflow execution. If the PR has multiple pushes or re-runs, this could create duplicate comments.
🔎 Optional: Add duplicate comment check
- name: Comment on Dependabot PR if: github.actor == 'dependabot[bot]' && github.event_name == 'pull_request' uses: actions/github-script@v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | + // Check for existing comment to avoid duplicates + const comments = await github.rest.issues.listComments({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo + }); + const hasComment = comments.data.some(c => + c.user.login === 'github-actions[bot]' && + c.body.includes('Build Successful (Dependabot)') + ); + if (hasComment) return; + github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: `### ✅ Build Successful (Dependabot)\n\n**Note:** Integration tests requiring secrets were skipped for security.\n\n- ✅ Build completed\n- ✅ Unit tests passed\n- ⏭️ Integration tests skipped (no secrets)\n- ⏭️ Azure deployment skipped\n\nOnce merged, full integration tests and deployment will run automatically.` })docs/AZURE-LOGGING-QUERIES.md (2)
26-28: Add language specifier to fenced code blocks.Per static analysis (markdownlint MD040), these navigation path code blocks should have a language specifier. Using
textis appropriate for plain text content.🔎 Suggested fix
-``` +```text Function App → Monitoring → Log streamApply similar fix to lines 34 and 262. </details> Also applies to: 34-36, 262-264 --- `279-281`: **Consider updating deprecated instrumentation key reference.** `APPINSIGHTS_INSTRUMENTATIONKEY` is being deprecated in favor of `APPLICATIONINSIGHTS_CONNECTION_STRING`. Consider updating the troubleshooting guidance to mention both, with the connection string as the primary reference. <details> <summary>🔎 Suggested update</summary> ```diff **Logs not appearing:** -- Check Application Insights connection string is configured -- Verify `APPINSIGHTS_INSTRUMENTATIONKEY` in function app settings +- Check `APPLICATIONINSIGHTS_CONNECTION_STRING` is configured in function app settings +- (Legacy) Verify `APPINSIGHTS_INSTRUMENTATIONKEY` if using older setup - Wait 2-3 minutes for logs to appear in Application Insights.azure/function-app.bicep (1)
84-90: Consider using managed identity for storage access.The storage connection strings use account keys, which is the standard pattern. When feasible, consider migrating to managed identity-based access (
AzureWebJobsStorage__accountName) to eliminate key rotation concerns.This is a future improvement opportunity, not a blocker for this PR.
.github/workflows/cleanup-azure-functions.yml (1)
95-105: Consider logging when storage accounts are found but have unexpected tags.If the deployment fails partway through or tags aren't applied correctly, storage accounts might exist without the expected tags. The current logic handles this gracefully, but a debug log could aid troubleshooting.
🔎 Optional: Add debug logging for all storage accounts
+ # Debug: List all storage accounts for visibility + echo "All storage accounts in resource group:" + az storage account list \ + --resource-group ${{ env.AZURE_RESOURCE_GROUP }} \ + --query "[].{name:name, env:tags.Environment, func:tags.FunctionApp}" \ + --output table || true + if [ -n "$STORAGE_ACCOUNTS" ]; then for STORAGE in $STORAGE_ACCOUNTS; dodocs/AZURE-MONITORING-ALERTS.md (1)
34-36: Consider using placeholder email in documentation.The example uses what appears to be a real email address. Consider using a generic placeholder like
alerts@example.comoryour-email@example.com.🔎 Suggested change
-4. Value: Your email address (e.g., `matthew.oconnell@gmail.com`) +4. Value: Your email address (e.g., `alerts@example.com`).azure/alert-rules.bicep (2)
16-18: Consider parameterizing the Application Insights name.The Application Insights name is hard-coded as
'yolo-funk-insights'. If your naming convention changes or you deploy to different environments with different insights instances, this will cause issues.🔎 Proposed refactor to add parameter
@description('Resource location') param location string = resourceGroup().location + +@description('Application Insights name') +param appInsightsName string = 'yolo-funk-insights' // Get existing Application Insights resource appInsights 'Microsoft.Insights/components@2020-02-02' existing = { - name: 'yolo-funk-insights' + name: appInsightsName }
137-142: Timer trigger failure detection is heuristic-based.The query searches for "Timer trigger" with "error" or "failed" in trace messages. This is a reasonable heuristic but may:
- Miss failures with different error message formats
- Generate false positives if "error" or "failed" appear in non-failure contexts
Consider supplementing this with additional telemetry or custom logging for more reliable timer trigger monitoring.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
.azure/alert-rules.bicep.azure/function-app.bicep.github/workflows/cleanup-azure-functions.yml.github/workflows/deploy-azure-functions.yml.github/workflows/dotnet.ymldocs/AZURE-LOGGING-QUERIES.mddocs/AZURE-LOGGING-TROUBLESHOOT.mddocs/AZURE-MONITORING-ALERTS.mddocs/STRATEGY-ARCHITECTURE.mdsrc/YoloFunk/appsettings.jsonsrc/YoloFunk/docs/DEPLOYMENT.mdsrc/YoloFunk/host.json
💤 Files with no reviewable changes (1)
- src/YoloFunk/docs/DEPLOYMENT.md
🧰 Additional context used
🪛 markdownlint-cli2 (0.18.1)
docs/AZURE-LOGGING-QUERIES.md
26-26: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
34-34: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
262-262: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (14)
.github/workflows/dotnet.yml (3)
5-7: LGTM!The permissions are appropriately scoped -
contents: readfor checkout andpull-requests: writefor commenting on Dependabot PRs.
11-12: LGTM!Good approach to conditionally skip the environment requirement for Dependabot PRs, as they cannot access repository secrets.
25-37: LGTM!Clean implementation of conditional test execution - full tests with secrets for regular PRs, filtered unit tests for Dependabot. The
Category!=Integrationfilter correctly excludes integration tests.docs/AZURE-LOGGING-QUERIES.md (1)
1-300: LGTM! Comprehensive logging guide.Well-structured documentation covering log locations, KQL queries, structured logging patterns, and troubleshooting. The guidance on disabling sampling (line 85) aligns with the
host.jsonchanges in this PR..azure/function-app.bicep (2)
31-36: LGTM! Clean tag management.Using
union()to merge tags ensures environment-specific tags take precedence while preserving any custom tags passed in. This aligns well with the tag-based cleanup logic in the workflow.
173-180: LGTM! Schedule settings now persisted in infrastructure.Good fix for the environment variable persistence issue. The NCRONTAB expressions are valid Azure Functions format (6 fields: second minute hour day month day-of-week).
src/YoloFunk/appsettings.json (1)
6-16: LGTM! Well-structured logging configuration.Adding explicit categories for
YoloFunk,YoloTrades, andYoloBrokerenables granular log filtering. The ApplicationInsights section ensures consistent log levels when writing to Application Insights.src/YoloFunk/host.json (2)
5-7: Good fix: Disabling sampling prevents log loss.Setting
isEnabled: falseensures all logs reach Application Insights. This is the correct fix for the "only seeing framework logs" issue mentioned in the documentation.
17-17: Verify timeout aligns with function execution needs.The 10-minute timeout is the maximum for Consumption plan. Ensure your rebalance operations complete well within this window, or consider Premium plan if longer execution is needed.
.github/workflows/cleanup-azure-functions.yml (1)
89-105: LGTM! Tag-based cleanup is more reliable.Using
tags.Environmentandtags.FunctionAppfor storage account discovery is a robust improvement over name-based matching. This aligns with theresourceTagsimplementation infunction-app.bicep.docs/AZURE-MONITORING-ALERTS.md (1)
1-140: LGTM! Clear and actionable documentation.Good explanation of the environment variable persistence issue, with concrete steps for setting up email alerts. The troubleshooting section covers common issues effectively.
docs/AZURE-LOGGING-TROUBLESHOOT.md (1)
1-113: LGTM! Excellent quick-reference troubleshooting guide.This document provides actionable steps for the most common logging issue. The quick reference table (lines 99-106) and common issues checklist (lines 107-113) are particularly useful for rapid diagnosis.
.azure/alert-rules.bicep (1)
79-118: LGTM! Exception alert implementation looks solid.The scheduled query rule correctly filters exceptions by
cloud_RoleNameand alerts on any exception count. The 5-minute evaluation frequency with a 15-minute window provides good balance between responsiveness and noise reduction..github/workflows/deploy-azure-functions.yml (1)
65-70: LGTM! Dependabot skip logic is correct.Properly prevents deployment failures for Dependabot PRs that lack access to secrets. This is a best practice for workflows requiring authenticated Azure operations.
🚀 Deployed to Azure FunctionsEnvironment: This environment will be automatically cleaned up when the PR is closed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
.github/workflows/deploy-azure-functions.yml (2)
120-133: Don’t suppress all errors on role assignment creation—this can mask real permission/tenant failures.
2>/dev/null || echo "…failed"will let the job continue even when the role assignment wasn’t created and doesn’t already exist.Proposed diff
az role assignment create \ --assignee-object-id $SP_OBJECT_ID \ --assignee-principal-type ServicePrincipal \ --role "User Access Administrator" \ --scope /subscriptions/${{ secrets.AZURE_SUBSCRIPTION_ID }}/resourceGroups/${{ vars.AZURE_RESOURCE_GROUP }} \ - 2>/dev/null || echo "Role assignment already exists or failed (may already be assigned)" + || { + echo "Role assignment create failed. Existing assignments (if any):" + az role assignment list \ + --assignee-object-id "$SP_OBJECT_ID" \ + --scope "/subscriptions/${{ secrets.AZURE_SUBSCRIPTION_ID }}/resourceGroups/${{ vars.AZURE_RESOURCE_GROUP }}" \ + -o table || true + exit 1 + }
152-177: Quote JSON parsing to avoid word-splitting issues (echo $OUTPUT | jq …).
This is a reliability footgun if the JSON ever contains whitespace/newlines.Proposed diff
- FUNCTION_APP_NAME=$(echo $OUTPUT | jq -r '.functionAppName.value') - PRINCIPAL_ID=$(echo $OUTPUT | jq -r '.principalId.value') + FUNCTION_APP_NAME=$(jq -r '.functionAppName.value' <<<"$OUTPUT") + PRINCIPAL_ID=$(jq -r '.principalId.value' <<<"$OUTPUT")
🤖 Fix all issues with AI agents
In @.github/workflows/deploy-azure-functions.yml:
- Around line 8-12: Replace the overly-broad branch glob 'feat*/**' in the
workflow's branches list with the documented pattern 'feature/*' so only
branches named feature/<name> trigger feature deployments; update the branches
array entry in the deploy-azure-functions.yml workflow (where 'branches:'
contains 'master', 'develop', and 'feat*/**') to use 'feature/*' instead.
🧹 Nitpick comments (4)
.github/workflows/deploy-azure-functions.yml (4)
63-77: Dependabot deploy skip is correct; consider logging the reason into job summary for visibility.
Right now it prints to stdout only; adding a$GITHUB_STEP_SUMMARYline can make it easier to diagnose “why didn’t this deploy?” from the UI.
91-100: Feature env naming can collide across branches; add a short SHA (or PR number) to avoid accidental shared deployments.
Withcut -c1-20, two branches with the same first 20 sanitized chars will deploy to the same Azure resources.Proposed diff
# Extract branch name and sanitize for Azure naming # Handles both feat/* and feature/* patterns - BRANCH_NAME=$(echo "${{ github.ref }}" | sed 's/refs\/heads\/feat[^\/]*\///' | sed 's/[^a-zA-Z0-9-]/-/g' | cut -c1-20) + BRANCH_NAME=$(echo "${{ github.ref }}" | sed 's/refs\/heads\/feat[^\/]*\///' | sed 's/[^a-zA-Z0-9-]/-/g' | cut -c1-12) + SHORT_SHA=$(echo "${{ github.sha }}" | cut -c1-7) - ENV="feat-$BRANCH_NAME" + ENV="feat-$BRANCH_NAME-$SHORT_SHA"
134-140: Fail fast if required GitHub Variables are missing (AZURE_RESOURCE_GROUP,AZURE_LOCATION).
Otherwise the Azure CLI calls will fail later with less obvious errors.Proposed diff
- name: Ensure Resource Group exists run: | + if [ -z "${{ vars.AZURE_RESOURCE_GROUP }}" ] || [ -z "${{ vars.AZURE_LOCATION }}" ]; then + echo "Missing required variables: vars.AZURE_RESOURCE_GROUP and/or vars.AZURE_LOCATION" + exit 1 + fi az group create \ --name ${{ vars.AZURE_RESOURCE_GROUP }} \ --location ${{ vars.AZURE_LOCATION }} \ --tags Environment=${{ needs.determine-environment.outputs.environment }} ManagedBy=GitHub
197-209: Alert rules deployment gating (prod +ALERT_EMAIL) is good; consider a stable deployment name to reduce RG deployment clutter.
Since it’s production-only, a fixed--name "alert-rules"is typically sufficient unless you rely on historical deployment records.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
.azure/alert-rules.bicep.github/workflows/deploy-azure-functions.yml
🚧 Files skipped from review as they are similar to previous changes (1)
- .azure/alert-rules.bicep
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build-and-deploy
- GitHub Check: Analyze (csharp)
🔇 Additional comments (3)
.github/workflows/deploy-azure-functions.yml (3)
12-24: Good: workflow now triggers on solution/props changes that affect build output.
141-150:vars.*migration here looks consistent.
If you see intermittent creation attempts, consider capturing and checking the exact exit code instead of relying on2>/dev/null(but current behavior is likely fine).
253-262: Good: Function URL lookup now consistently usesvars.AZURE_RESOURCE_GROUP.
| branches: | ||
| - master | ||
| - develop | ||
| - "feature/**" | ||
| - "feat*/**" | ||
| paths: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
cat -n .github/workflows/deploy-azure-functions.yml | head -20Repository: moconnell/yolo
Length of output: 567
🌐 Web query:
GitHub Actions workflow branch filtering glob pattern syntax feat*/**
💡 Result:
Short answer: feat*/** matches branch names that start with "feat" plus zero-or-more non-/ characters, followed by a slash, then anything (including additional slashes). In other words it matches branches like:
- feat/one
- feature/one/two
- featsomething/anything/more
It does NOT match a branch with no slash after the "feat..." part (e.g. featbranch with no /). This follows GitHub Actions' filter rules: * does not match /, while ** matches any characters including /. [1][2]
Sources:
- GitHub Actions workflow syntax (filter pattern cheat sheet). [1]
- Triggering a workflow / branches examples. [2]
🏁 Script executed:
# Check for branch naming conventions in repo docs
fd -t f -e md -e txt | xargs grep -l "branch" | head -5Repository: moconnell/yolo
Length of output: 124
🏁 Script executed:
cat -n docs/DEPLOYMENT.md | head -100Repository: moconnell/yolo
Length of output: 3995
🏁 Script executed:
cat -n docs/DEPLOYMENT.md | sed -n '19,30p'Repository: moconnell/yolo
Length of output: 918
Branch glob feat*/** is overly broad and contradicts documented deployment strategy.
The pattern feat*/** matches any branch starting with "feat" followed by a slash (e.g., feather/..., featsomething/...), but the deployment documentation (DEPLOYMENT.md line 28) explicitly specifies that only feature/* branches should trigger feature deployments. Narrow the pattern to match the documented intent.
Proposed diff
branches:
- master
- develop
- - "feat*/**"
+ - "feature/**"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| branches: | |
| - master | |
| - develop | |
| - "feature/**" | |
| - "feat*/**" | |
| paths: | |
| branches: | |
| - master | |
| - develop | |
| - "feature/**" | |
| paths: |
🤖 Prompt for AI Agents
In @.github/workflows/deploy-azure-functions.yml around lines 8 - 12, Replace
the overly-broad branch glob 'feat*/**' in the workflow's branches list with the
documented pattern 'feature/*' so only branches named feature/<name> trigger
feature deployments; update the branches array entry in the
deploy-azure-functions.yml workflow (where 'branches:' contains 'master',
'develop', and 'feat*/**') to use 'feature/*' instead.
Summary by CodeRabbit
New Features
Documentation
Configuration
Chores
✏️ Tip: You can customize this high-level summary in your review settings.