Table of Contents
Introduction
Why Observability Matters in Financial Systems
Enabling Application Insights for Azure Functions
Implementing Custom Structured Logging
Real-World Scenario: Real-Time Payment Fraud Detection
Best Practices for Enterprise-Grade Logging
Conclusion
Introduction
In modern cloud-native architectures, observability isn’t optional—it’s essential. Azure Functions, as a serverless compute service, abstracts infrastructure but not the need for deep visibility into execution behavior, performance, and errors. For enterprise systems—especially in regulated domains like finance—robust logging and telemetry are non-negotiable. This article shows how to enable Application Insights and implement custom structured logging in Azure Functions using a real-world scenario: real-time payment fraud detection in a global fintech platform.
Why Observability Matters in Financial Systems
Imagine a payment processing system handling 10,000 transactions per minute across 50 countries. A subtle anomaly—like a sudden spike in declined transactions from a specific region—could signal either a fraud wave or a failing downstream service. Without granular, contextual logs and telemetry, your incident response time balloons from seconds to hours.
In such environments, Application Insights becomes your central nervous system for monitoring, while custom logging injects business context into every trace.
Enabling Application Insights for Azure Functions
Azure Functions integrates natively with Application Insights. Here’s how to enable it correctly in an enterprise deployment:
Step 1. Infrastructure-as-Code (Bicep)
// main.bicep
param appName string = 'fraud-detection-func'
param location string = 'eastus'
resource appInsights 'Microsoft.Insights/components@2020-02-02' = {
name: '${appName}-ai'
location: location
kind: 'web'
properties: {
Application_Type: 'web'
Request_Source: 'IbizaWebAppExtensionCreate'
}
}
resource functionApp 'Microsoft.Web/sites@2022-03-01' = {
name: appName
location: location
kind: 'functionapp'
properties: {
serverFarmId: appServicePlan.id
siteConfig: {
appSettings: [
{
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
value: appInsights.properties.ConnectionString
}
{
name: 'AzureWebJobsStorage'
value: '...'
}
{
name: 'FUNCTIONS_EXTENSION_VERSION'
value: '~4'
}
{
name: 'FUNCTIONS_WORKER_RUNTIME'
value: 'python' // or 'dotnet', 'node', etc.
}
]
}
}
}Always inject the
APPLICATIONINSIGHTS_CONNECTION_STRINGvia infrastructure—not hardcoded in code.
Step 2. Confirm Auto-Instrumentation
Once deployed, Azure Functions automatically sends:
Function invocations
Duration
Failures
Dependency calls (e.g., to Cosmos DB, Service Bus)
No extra code needed. But this is just the baseline.
Implementing Custom Structured Logging
Auto-telemetry lacks business context. To detect fraud, you need logs like:
“Transaction ID
txn_8a3bfrom userusr_9921(country: NG) scored 0.92—flagged as high risk.”
Python Example (Azure Functions v4)
# __init__.py
import azure.functions as func
import logging
import json
from opencensus.ext.azure.log_exporter import AzureLogHandler
# Add Application Insights handler to root logger
logger = logging.getLogger()
logger.addHandler(AzureLogHandler())
def main(req: func.HttpRequest) -> func.HttpResponse:
transaction = req.get_json()
txn_id = transaction.get("id")
user_id = transaction.get("user_id")
amount = transaction.get("amount")
country = transaction.get("country")
# Business logic: fraud scoring (simplified)
risk_score = calculate_fraud_score(amount, country)
is_fraud = risk_score > 0.85
# Custom structured log
logger.info(
"Fraud analysis completed",
extra={
"custom_dimensions": {
"transaction_id": txn_id,
"user_id": user_id,
"amount": amount,
"country": country,
"risk_score": risk_score,
"is_fraud": is_fraud,
"service": "fraud-detection-engine"
}
}
)
if is_fraud:
return func.HttpResponse(json.dumps({"blocked": True}), status_code=403)
return func.HttpResponse(json.dumps({"approved": True}), status_code=200)
def calculate_fraud_score(amount: float, country: str) -> float:
# Placeholder for ML model or rules engine
high_risk_countries = {"NG", "VE", "SY"}
base_score = 0.2
if country in high_risk_countries:
base_score += 0.5
if amount > 10000:
base_score += 0.3
return min(base_score, 0.99)





Comments
Join the conversation! Your thoughts help the community grow.