Skip to content
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

Access Telemetry Client to add customDimensions for App Insights #960

Open
DannyArr opened this issue Jun 7, 2023 · 3 comments
Open

Access Telemetry Client to add customDimensions for App Insights #960

DannyArr opened this issue Jun 7, 2023 · 3 comments
Assignees
Milestone

Comments

@DannyArr
Copy link

DannyArr commented Jun 7, 2023

Question. Is it possible to access and add customDimensions / properties to the existing telemetry client within the function app? Specifically for a request. I'm able to do so only when creating a new client and invoking trackRequest, like so:

class MyInitializer3 : Extensibility.ITelemetryInitializer {
    <# Define the class. Try constructors, properties, or methods. #>
    [void]Initialize([Channel.ITelemetry]$Telemetry){
        #$requestTelemetry = [DataContracts.RequestTelemetry]::new()
        $requestTelemetry = [DataContracts.RequestTelemetry]$Telemetry

        $requestTelemetry.Properties["test"] = "test value"
    }
}

$requestTelemetry = [DataContracts.RequestTelemetry]::new()

######################

$telemetryConfig = [Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration]::CreateDefault()
$telemetryConfig.ConnectionString = "XXXXXXXX"

$telemetryConfig.TelemetryInitializers.Add( [MyInitializer3]::new() )

$client = [Microsoft.ApplicationInsights.TelemetryClient]::new($telemetryConfig)

$client.TrackRequest("requestTest",$(get-date),100,201,$true)

But of course the function app already logs a request anyway, and I'd like to add to that.

@Francisco-Gamino
Copy link
Contributor

/cc @RohitRanjanMS

@andystaples
Copy link
Contributor

After conferring with Rohit about this, it turns out that this is not possible. Request telemetry is sent using an application insights telemetry client on the host, not the worker, and it is not possible for function code to interact with the host's telemetry client. There is an issue open on the host right now, here that may add the functionality described here, but it is not certain how/if we will address it.

@Francisco-Gamino Francisco-Gamino added this to the Backlog milestone Aug 2, 2023
@juniinacio
Copy link

juniinacio commented Nov 8, 2023

I was also interested in having this possibility in Azure PowerShell functions. I have managed to come so far, but the only thing I'm missing is how to prevent having duplicate log entries when initializing a new application insights telemetry client on my own beside the one used by the host.

using namespace Microsoft.ApplicationInsights
using namespace Microsoft.ApplicationInsights.DataContracts
using namespace Microsoft.ApplicationInsights.Extensibility
using namespace Microsoft.ApplicationInsights.Channel
using namespace Microsoft.ApplicationInsights.Extensibility.Implementation

class CustomPropertyTelemetryInitializer : ITelemetryInitializer {
    [hashtable] $TriggerMetadata
    
    CustomPropertyTelemetryInitializer ([hashtable] $TriggerMetadata) {
        $this.TriggerMetadata = $TriggerMetadata
    }

    [void]Initialize([ITelemetry] $Telemetry) {
        $dependency = $Telemetry -as [DependencyTelemetry]
        if ($null -ne $dependency) {
            $dependency.Context.Cloud.RoleName = $Env:WEBSITE_SITE_NAME
            $dependency.Context.Cloud.RoleInstance = $Env:WEBSITE_INSTANCE_ID
            $dependency.Context.Operation.Id = $this.TriggerMetadata.InvocationId
            $dependency.Context.Operation.Name = $this.TriggerMetadata.FunctionName
            # $dependency.Context.Operation.ParentId = $this.TriggerMetadata.InvocationId            
        }
    }
}

class DependencyTelemetryProcessor : ITelemetryProcessor {
    hidden [ITelemetryProcessor] $Next

    DependencyTelemetryProcessor([ITelemetryProcessor] $next) {
        $this.Next = $next 
    }

    [void] Process([ITelemetry] $item) {
        if (!$this.OKtoSend($item)) { return }

        $this.Next.Process($item)
    }

    [bool] OKtoSend([ITelemetry] $item) {
        $dependency = $item -as [DependencyTelemetry]
        if ($null -eq $dependency) { return $false }
        return $true
    }
}

$telemetryConfig = [TelemetryConfiguration]::CreateDefault()
$telemetryConfig.InstrumentationKey = $Env:APPINSIGHTS_INSTRUMENTATIONKEY
$telemetryConfig.TelemetryInitializers.Add([CustomPropertyTelemetryInitializer]::new($TriggerMetadata))

$null = $telemetryConfig.TelemetryProcessorChainBuilder.Use({param($next) [DependencyTelemetryProcessor]::new($next) })
$telemetryConfig.TelemetryProcessorChainBuilder.Build()

$telemetryClient = [TelemetryClient]::new($telemetryConfig)

$startTime = [DateTime]::UtcNow
$statusCode = 200
$success = $true
Start-Sleep -Seconds 5
$duration = New-TimeSpan -Start $startTime -End ([DateTime]::UtcNow)
$telemetryClient.TrackDependency('MyDependency', "www.example.org", "GET www.example.org", "https://www.example.org", $startTime, $duration, $statusCode, $success)

Initially I thought it was because my logger was also processing the host log messages or the other way around, and that was the reason why I was seeing duplicate log entries, but after adding the above custom dependency telemetry I notice the same behavior was still happening. I added my own dependency telemetry processor because I was only interested in keeping track of some SQL bulk import activities I was executing using Invoke-Sqlcmd.

App Insights traces:

image

Durable Activity monitoring pane:

image

Kind regards,

Juni

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants