I have some trouble adding logs from an azure function app to application insigths. I am using this code:
import azure.functions as func
import datetime
import logging
import requests
from settings import settings
from services.exchangerate_service import ExchangeRateService
from azure.identity import DefaultAzureCredential
from azure.monitor.opentelemetry import configure_azure_monitor
from opentelemetry import metrics
credential = DefaultAzureCredential()
configure_azure_monitor(
connection_string="InstrumentationKey=xx-xx-xx-xx-xx;IngestionEndpoint=https://westeurope-5.in.applicationinsights.azure.com/;LiveEndpoint=https://westeurope.livediagnostics.monitor.azure.com/;ApplicationId=xx-xx-xx-xx-xx",
credential=credential
)
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
app = func.FunctionApp()
@app.timer_trigger(schedule=settings.IBAN_CRON, arg_name="myTimer", run_on_startup=True,
use_monitor=False)
def timer_trigger(myTimer: func.TimerRequest) -> None:
if myTimer.past_due:
logging.info('The timer is past du3e!')
logger.info("Segato5", extra={"custom_dimension": "Kam_value","test1": "val1"})
meter = metrics.get_meter_provider().get_meter(__name__)
counter = meter.create_counter("segato2")
counter.add(8)
I modified your code by moving the meter and counter outside the function and configuring the MeterProvider globally instead of creating a new meter inside the function on each invocation. This ensures that metrics persist across function executions and correctly send custom dimensions.
Code :
import azure.functions as func
import logging
from settings import settings
from azure.monitor.opentelemetry import configure_azure_monitor
from opentelemetry import metrics
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
from azure.monitor.opentelemetry.exporter import AzureMonitorMetricExporter
from opentelemetry.instrumentation.logging import LoggingInstrumentor
configure_azure_monitor(
connection_string=settings.APPLICATION_INSIGHTS_CONNECTION_STRING
)
LoggingInstrumentor().instrument(set_logging_format=True)
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
reader = PeriodicExportingMetricReader(AzureMonitorMetricExporter(
connection_string=settings.APPLICATION_INSIGHTS_CONNECTION_STRING
))
provider = MeterProvider(metric_readers=[reader])
metrics.set_meter_provider(provider)
meter = metrics.get_meter_provider().get_meter("my_function_metrics")
counter = meter.create_counter("segato2")
app = func.FunctionApp()
@app.timer_trigger(schedule=settings.IBAN_CRON, arg_name="myTimer", run_on_startup=True, use_monitor=False)
def timer_trigger(myTimer: func.TimerRequest) -> None:
if myTimer.past_due:
logger.warning("Timer is past due!")
logger.info("Segato5", extra={"custom_dimension": "Kam_value", "test1": "val1"})
counter.add(1, {"custom_dimension": "Kam_value"})
I successfully retrieved the traces, metrics, and custom dimensions by running the following queries in Azure Application Insights Logs.
traces :
traces
| where timestamp >= ago(30m)
| where message contains "Segato5"
| extend customDimensions = todynamic(customDimensions)
| project timestamp, message, customDimensions
| order by timestamp desc
output :
metrics :
customMetrics
| where timestamp >= ago(30m)
| where name == "segato2"
| extend customDimensions = todynamic(customDimensions)
| project timestamp, name, value, customDimensions
| order by timestamp desc
output :
customdeminsions :
customMetrics
| where timestamp >= ago(30m)
| where name == "segato2"
| extend customDimensions = todynamic(customDimensions)
| where tostring(customDimensions.custom_dimension) == "Kam_value"
| project timestamp, name, value, customDimensions
| order by timestamp desc
output :
Traces in Transaction Search :