Skip to content

Commit 8da20ea

Browse files
Updated event config
1 parent 3a702f9 commit 8da20ea

5 files changed

Lines changed: 46 additions & 10 deletions

File tree

content-gen/infra/main.bicep

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,6 @@ module applicationInsights 'br/public:avm/res/insights/component:0.7.1' = if (en
344344
disableIpMasking: false
345345
flowType: 'Bluefield'
346346
workspaceResourceId: logAnalyticsWorkspaceResourceId
347-
diagnosticSettings: [{ workspaceResourceId: logAnalyticsWorkspaceResourceId }]
348347
}
349348
}
350349

content-gen/infra/main.json

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"_generator": {
77
"name": "bicep",
88
"version": "0.40.2.10011",
9-
"templateHash": "14662930066054172114"
9+
"templateHash": "16421359956200067368"
1010
},
1111
"name": "Intelligent Content Generation Accelerator",
1212
"description": "Solution Accelerator for multimodal marketing content generation using Microsoft Agent Framework.\n"
@@ -3562,14 +3562,7 @@
35623562
"flowType": {
35633563
"value": "Bluefield"
35643564
},
3565-
"workspaceResourceId": "[if(variables('useExistingLogAnalytics'), createObject('value', parameters('existingLogAnalyticsWorkspaceId')), if(parameters('enableMonitoring'), createObject('value', reference('logAnalyticsWorkspace').outputs.resourceId.value), createObject('value', '')))]",
3566-
"diagnosticSettings": {
3567-
"value": [
3568-
{
3569-
"workspaceResourceId": "[if(variables('useExistingLogAnalytics'), parameters('existingLogAnalyticsWorkspaceId'), if(parameters('enableMonitoring'), reference('logAnalyticsWorkspace').outputs.resourceId.value, ''))]"
3570-
}
3571-
]
3572-
}
3565+
"workspaceResourceId": "[if(variables('useExistingLogAnalytics'), createObject('value', parameters('existingLogAnalyticsWorkspaceId')), if(parameters('enableMonitoring'), createObject('value', reference('logAnalyticsWorkspace').outputs.resourceId.value), createObject('value', '')))]"
35733566
},
35743567
"template": {
35753568
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
@@ -33364,6 +33357,10 @@
3336433357
{
3336533358
"name": "AZURE_AI_IMAGE_MODEL_DEPLOYMENT",
3336633359
"value": "[variables('imageModelConfig')[parameters('imageModelChoice')].name]"
33360+
},
33361+
{
33362+
"name": "APPLICATIONINSIGHTS_CONNECTION_STRING",
33363+
"value": "[if(parameters('enableMonitoring'), reference('applicationInsights').outputs.connectionString.value, '')]"
3336733364
}
3336833365
]
3336933366
}
@@ -33561,6 +33558,7 @@
3356133558
},
3356233559
"dependsOn": [
3356333560
"aiFoundryAiServicesProject",
33561+
"applicationInsights",
3356433562
"userAssignedIdentity",
3356533563
"virtualNetwork"
3356633564
]

content-gen/src/backend/app.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from api.admin import admin_bp
2828
from azure.monitor.opentelemetry import configure_azure_monitor
2929
from opentelemetry.instrumentation.asgi import OpenTelemetryMiddleware
30+
from event_utils import track_event_if_configured
3031

3132
# In-memory task storage for generation tasks
3233
# In production, this should be replaced with Redis or similar
@@ -59,6 +60,7 @@
5960
logging.getLogger("azure.identity").setLevel(logging.WARNING)
6061
logging.getLogger("azure.cosmos").setLevel(logging.WARNING)
6162
logging.getLogger("api.admin").setLevel(logging.WARNING)
63+
logging.getLogger("httpx").setLevel(logging.WARNING)
6264
# Apply ASGI middleware for request tracing (Quart is not auto-instrumented by configure_azure_monitor)
6365
# Exclude health probes, post-deploy admin calls, and polling endpoints from telemetry
6466
app.asgi_app = OpenTelemetryMiddleware(
@@ -162,8 +164,11 @@ async def chat():
162164
user_id = data.get("user_id", "anonymous")
163165

164166
if not message:
167+
track_event_if_configured("Error_Chat_Message_Empty", {"conversation_id": conversation_id, "user_id": user_id})
165168
return jsonify({"error": "Message is required"}), 400
166169

170+
track_event_if_configured("Chat_Request_Received", {"conversation_id": conversation_id, "user_id": user_id})
171+
167172
orchestrator = get_orchestrator()
168173

169174
# Try to save to CosmosDB but don't fail if it's unavailable
@@ -259,8 +264,11 @@ async def parse_brief():
259264
user_id = data.get("user_id", "anonymous")
260265

261266
if not brief_text:
267+
track_event_if_configured("Error_Brief_Text_Empty", {"conversation_id": conversation_id, "user_id": user_id})
262268
return jsonify({"error": "Brief text is required"}), 400
263269

270+
track_event_if_configured("Brief_Parse_Request", {"conversation_id": conversation_id, "user_id": user_id})
271+
264272
orchestrator = get_orchestrator()
265273
generated_title = None
266274

@@ -294,6 +302,7 @@ async def parse_brief():
294302

295303
# Check if request was blocked due to harmful content
296304
if rai_blocked:
305+
track_event_if_configured("Error_RAI_Check_Failed", {"conversation_id": conversation_id, "user_id": user_id, "status": "Brief parse blocked by RAI"})
297306
# Save the refusal as assistant response
298307
try:
299308
cosmos_service = await get_cosmos_service()
@@ -396,8 +405,11 @@ async def confirm_brief():
396405
try:
397406
brief = CreativeBrief(**brief_data)
398407
except Exception as e:
408+
track_event_if_configured("Error_Brief_Invalid_Format", {"conversation_id": conversation_id, "user_id": user_id, "error": str(e)})
399409
return jsonify({"error": f"Invalid brief format: {str(e)}"}), 400
400410

411+
track_event_if_configured("Brief_Confirmed", {"conversation_id": conversation_id, "user_id": user_id})
412+
401413
# Try to save the confirmed brief to CosmosDB, preserving existing messages
402414
try:
403415
cosmos_service = await get_cosmos_service()
@@ -458,8 +470,11 @@ async def select_products():
458470
user_id = data.get("user_id", "anonymous")
459471

460472
if not request_text:
473+
track_event_if_configured("Error_Product_Request_Empty", {"conversation_id": conversation_id, "user_id": user_id})
461474
return jsonify({"error": "Request text is required"}), 400
462475

476+
track_event_if_configured("Product_Selection_Request", {"conversation_id": conversation_id, "user_id": user_id})
477+
463478
# Save user message
464479
try:
465480
cosmos_service = await get_cosmos_service()
@@ -605,13 +620,15 @@ async def _run_generation_task(task_id: str, brief: CreativeBrief, products_data
605620
_generation_tasks[task_id]["status"] = "completed"
606621
_generation_tasks[task_id]["result"] = response
607622
_generation_tasks[task_id]["completed_at"] = datetime.now(timezone.utc).isoformat()
623+
track_event_if_configured("Generation_Completed", {"task_id": task_id, "conversation_id": conversation_id, "user_id": user_id})
608624
logger.info(f"Task {task_id} marked as completed")
609625

610626
except Exception as e:
611627
logger.exception(f"Generation task {task_id} failed: {e}")
612628
_generation_tasks[task_id]["status"] = "failed"
613629
_generation_tasks[task_id]["error"] = str(e)
614630
_generation_tasks[task_id]["completed_at"] = datetime.now(timezone.utc).isoformat()
631+
track_event_if_configured("Error_Generation_Failed", {"task_id": task_id, "conversation_id": conversation_id, "user_id": user_id, "error": str(e)})
615632

616633

617634
@app.route("/api/generate/start", methods=["POST"])
@@ -647,6 +664,7 @@ async def start_generation():
647664
try:
648665
brief = CreativeBrief(**brief_data)
649666
except Exception as e:
667+
track_event_if_configured("Error_Generation_Invalid_Brief", {"conversation_id": conversation_id, "user_id": user_id, "error": str(e)})
650668
return jsonify({"error": f"Invalid brief format: {str(e)}"}), 400
651669

652670
# Create task ID
@@ -689,6 +707,8 @@ async def start_generation():
689707

690708
logger.info(f"Started generation task {task_id} for conversation {conversation_id}")
691709

710+
track_event_if_configured("Generation_Started", {"task_id": task_id, "conversation_id": conversation_id, "user_id": user_id, "generate_images": str(generate_images)})
711+
692712
return jsonify({
693713
"task_id": task_id,
694714
"status": "pending",
@@ -959,13 +979,17 @@ async def regenerate_content():
959979
user_id = data.get("user_id", "anonymous")
960980

961981
if not modification_request:
982+
track_event_if_configured("Error_Regeneration_Request_Empty", {"conversation_id": conversation_id, "user_id": user_id})
962983
return jsonify({"error": "modification_request is required"}), 400
963984

964985
try:
965986
brief = CreativeBrief(**brief_data)
966987
except Exception as e:
988+
track_event_if_configured("Error_Regeneration_Invalid_Brief", {"conversation_id": conversation_id, "user_id": user_id, "error": str(e)})
967989
return jsonify({"error": f"Invalid brief format: {str(e)}"}), 400
968990

991+
track_event_if_configured("Regeneration_Request", {"conversation_id": conversation_id, "user_id": user_id})
992+
969993
# Save user request for regeneration
970994
try:
971995
cosmos_service = await get_cosmos_service()
@@ -1029,6 +1053,7 @@ async def generate():
10291053

10301054
# Check for RAI block
10311055
if response.get("rai_blocked"):
1056+
track_event_if_configured("Error_RAI_Check_Failed", {"conversation_id": conversation_id, "user_id": user_id, "status": "Regeneration blocked by RAI"})
10321057
yield f"data: {json.dumps({'type': 'error', 'content': response.get('error', 'Request blocked by content safety'), 'rai_blocked': True, 'is_final': True})}\n\n"
10331058
yield "data: [DONE]\n\n"
10341059
return
@@ -1412,6 +1437,7 @@ async def delete_conversation(conversation_id: str):
14121437
try:
14131438
cosmos_service = await get_cosmos_service()
14141439
await cosmos_service.delete_conversation(conversation_id, user_id)
1440+
track_event_if_configured("Conversation_Deleted", {"conversation_id": conversation_id, "user_id": user_id})
14151441
return jsonify({"success": True, "message": "Conversation deleted"})
14161442
except Exception as e:
14171443
logger.warning(f"Failed to delete conversation: {e}")
@@ -1463,6 +1489,7 @@ async def delete_all_conversations():
14631489
try:
14641490
cosmos_service = await get_cosmos_service()
14651491
deleted_count = await cosmos_service.delete_all_conversations(user_id)
1492+
track_event_if_configured("Conversations_All_Deleted", {"user_id": user_id, "deleted_count": str(deleted_count)})
14661493
return jsonify({
14671494
"success": True,
14681495
"message": f"Deleted {deleted_count} conversations",
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import logging
2+
import os
3+
from azure.monitor.events.extension import track_event
4+
5+
6+
def track_event_if_configured(event_name: str, event_data: dict):
7+
connection_string = os.getenv("APPLICATIONINSIGHTS_CONNECTION_STRING")
8+
if connection_string:
9+
track_event(event_name, event_data)
10+
else:
11+
logging.warning(f"Skipping track_event for {event_name} as Application Insights is not configured")

content-gen/src/backend/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ httpx>=0.27.0
2828

2929
# Monitoring / Telemetry
3030
azure-monitor-opentelemetry>=1.6.0
31+
azure-monitor-events-extension>=0.1.0
3132
opentelemetry-instrumentation-asgi>=0.48b0
3233

3334
# Data Validation

0 commit comments

Comments
 (0)