Search code examples
pythonazure-functionsazure-application-insights

Applications insights in an azure function app - metrics and custom dimensions missing


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 get traces but not custom dimesions and no metrics: enter image description here

enter image description here


Solution

  • 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 :

    enter image description here

    metrics :

    customMetrics
    | where timestamp >= ago(30m)  
    | where name == "segato2"
    | extend customDimensions = todynamic(customDimensions)
    | project timestamp, name, value, customDimensions
    | order by timestamp desc
    

    output :

    enter image description here

    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 :

    enter image description here

    Traces in Transaction Search :

    enter image description here