* Bump up version number

* Fix typos

* Fix a typo

* Uses new license file for nuget package

* Relocating vs tasks

* Add an exmple of enable AI.K8s for Console App

* Fix a typo
This commit is contained in:
Saar Shen 2019-03-13 16:27:24 -07:00 коммит произвёл GitHub
Родитель 5400daa47e
Коммит 93377299ad
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
16 изменённых файлов: 356 добавлений и 33 удалений

Двоичные данные
examples/BasicConsoleApp/.media/TraceResultQuery.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 44 KiB

Просмотреть файл

@ -0,0 +1,125 @@
# Enable Application Insights for Kubernetes in .NET Core Console Application
When running a Console Application inside a Kubernetes managed container, and if you have chosen Application Insights as your telemetry solution, you might want to enrich the telemetry with Kubernetes related information. This is an example of how to do it.
_Note: This is an example that does not follow all best practices, including security-related best practices. E.g. Application Insights instrumentation key is not adequately protected (it should be deployed as a secret)._
## Prerequisites
* .NET Core SDK 2.1.300 or above
Run `dotnet --version` to figure out the dotnet sdk version:
```shell
dotnet --version
```
The result is the SDK version, for example:
> 2.2.101
* A Kubernetes cluster that you can manage with kubectl
* If you don't have one yet, an easy way is to go to [Azure AKS](https://docs.microsoft.com/en-us/azure/aks/) to get a managed cluster.
* Verify that the credential is properly set for `kubectl` to work:
```shell
user@user-pc:~$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
aks-nodepool1-10984277-0 Ready agent 17d v1.9.9
user@user-pc:~$
```
* A container registry
* The image built will be pushed into an image repository. Dockerhub is used in this example.
## Walk-through
### Creates a Console Application
```shell
dotnet new console -n AiK8sConsole
```
__Tips:__ find a complete example in [src](./src).
### Adds the NuGet packages
Add the Application Insights packages:
```shell
dotnet add package Microsoft.ApplicationInsights
dotnet add package Microsoft.ApplicationInsights.Kubernetes
```
In this example, we are planning to put application insights key in the environmental variable, we are adding the following package too:
```shell
dotnet add package Microsoft.Extensions.Configuration.EnvironmentVariables
```
### Write the code to enable Application Insights
Follow the example code in [Program.cs](./src/Program.cs) to enable application insights with Kubernetes information on the telemetries. The key lines are:
Enable application insights by creating the configuration:
```csharp
TelemetryConfiguration configuration = new TelemetryConfiguration(iKey);
```
And then enable the enricher for Kubernetes info:
```csharp
configuration.AddApplicationInsightsKubernetesEnricher(applyOptions: null);
```
Starts build the client and then send the trace every once a while:
```csharp
TelemetryClient client = new TelemetryClient(configuration);
while (true)
{
client.TrackTrace("Hello from AI SDK");
client.Flush();
Thread.Sleep(30000);
}
```
### Build & Publish the container
Once the application is there, we can containerize it. Use [Dockerfile](./src/Dockerfile) as a reference and call the docker CLI to build it:
```shell
docker build -t dockeraccount/aik8sconsole .
```
Publish the image to the registry:
```shell
docker publish dockeraccount/aik8sconsole:latest
```
### Setup the default Service Account for RBAC enabled cluster
If the cluster is RBAC enabled, the service account used will need to bind to proper cluster role so that the application can fetch Kubernetes related properties. In [saRole.yaml](./src/saRole.yaml), a cluster role named appinsights-k8s-property-reader is created and then bind to the default service account. Permissions needed are listed in the resources property. To deploy it, update the value for the namespace and then:
```shell
kubectl create -f saRole.yaml
```
### Deploy the application
Create the Kubernetes spec for the deployment and the service. Referencing [k8s.yaml](src/k8s.yaml). Please update the variable of APPINSIGHTS_INSTRUMENTATIONKEY to your own application insights instrumentation key.
### Deploy the container to the cluster
```shell
kubectl create -f k8s.yaml
```
### Verification
Once properly set up, your telemetry data will all be decorated with Kubernetes properties on it:
![Telemetry with Kubernetes information on it](.media/TraceResultQuery.png)

Просмотреть файл

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.ApplicationInsights" Version="2.9.1" />
<PackageReference Include="Microsoft.ApplicationInsights.Kubernetes" Version="1.0.2" />
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="2.2.0" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,16 @@
FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build-env
WORKDIR /app
# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore
# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out
# Build runtime image
FROM mcr.microsoft.com/dotnet/core/runtime:2.2
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "AiK8sConsole.dll"]

Просмотреть файл

@ -0,0 +1,36 @@
using System;
using System.Threading;
using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace AiK8sConsole
{
class Program
{
static void Main(string[] args)
{
IConfiguration config = new ConfigurationBuilder().AddEnvironmentVariables().Build();
string iKey = config["APPINSIGHTS_INSTRUMENTNATIONKEY"];
if (string.IsNullOrEmpty(iKey))
{
Console.WriteLine("Can't do empty iKey.");
}
using (TelemetryConfiguration configuration = new TelemetryConfiguration(iKey))
{
configuration.AddApplicationInsightsKubernetesEnricher(applyOptions: null);
TelemetryClient client = new TelemetryClient(configuration);
Console.WriteLine("Sending trace telemetry once a while.");
while (true)
{
client.TrackTrace("Hello from AI SDK");
client.Flush();
Thread.Sleep(30000);
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,19 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: ai-k8s-console
spec:
replicas: 1
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: aik8sconsole
image: dockeraccount/aik8sconsole:latest
ports:
- containerPort: 80
env:
- name: APPINSIGHTS_INSTRUMENTATIONKEY
value: your-application-instrumentation-key

Просмотреть файл

@ -0,0 +1,24 @@
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
# "namespace" omitted since ClusterRoles are not namespaced
name: appinsights-k8s-property-reader
rules:
- apiGroups: ["","extensions"]
resources: ["pods","nodes", "replicasets","deployments"]
verbs: ["get", "watch", "list"]
---
# actual binding to the role
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: appinsights-k8s-property-reader-binding
subjects:
- kind: ServiceAccount
name: default
namespace: YOUR-NAMESPACE
roleRef:
kind: ClusterRole
name: appinsights-k8s-property-reader
apiGroup: rbac.authorization.k8s.io

28
src/.vscode/launch.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,28 @@
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/tests/UnitTests/bin/Debug/netcoreapp2.0/Microsoft.ApplicationInsights.Kubernetes.UnitTests.dll",
"args": [],
"cwd": "${workspaceFolder}/tests/UnitTests",
// For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window
"console": "internalConsole",
"stopAtEntry": false,
"internalConsoleOptions": "openOnSessionStart"
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
}
]
}

57
src/.vscode/tasks.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,57 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Build Debug",
"command": "${workspaceFolder}/../build/Build.cmd",
"type": "shell",
"group": "build",
"problemMatcher": "$msCompile"
},
{
"label": "Build Release",
"command": "${workspaceFolder}/../build/Build.cmd",
"type": "shell",
"group": "build",
"args": [
"Release",
],
"problemMatcher": "$msCompile",
},
{
"label": "ReBuild Debug",
"command": "${workspaceFolder}/../build/Build.cmd",
"type": "shell",
"group": "build",
"args": [
"Debug",
"True",
],
"problemMatcher": "$msCompile"
},
{
"label": "ReBuild Release",
"command": "${workspaceFolder}/../build/Build.cmd",
"type": "shell",
"group": "build",
"args": [
"Release",
"True",
],
"problemMatcher": "$msCompile",
},
{
"label": "Run Unit Tests",
"command": "dotnet",
"type": "process",
"group": "test",
"options": {
"cwd": "${workspaceFolder}/../tests/UnitTests"
},
"args": [
"test"
],
"problemMatcher": "$msCompile"
}
]
}

Просмотреть файл

@ -11,14 +11,14 @@ using Microsoft.Extensions.Options;
namespace Microsoft.Extensions.DependencyInjection
{
/// <summary>
/// Extnesion method to inject Kubernetes Telemtry Initializer.
/// Extension method to inject Kubernetes Telemetry Initializer.
/// </summary>
public static partial class ApplicationInsightsExtensions
{
private const string ConfigurationSectionName = "AppInsightsForKubernetes";
/// <summary>
/// Enables Application Insights for Kubernetes on the Default TelemtryConfiguration in the dependency injection system.
/// Enables Application Insights for Kubernetes on the Default TelemetryConfiguration in the dependency injection system.
/// </summary>
/// <param name="services">Collection of service descriptors.</param>
/// <returns>The collection of services descriptors injected into.</returns>
@ -29,7 +29,7 @@ namespace Microsoft.Extensions.DependencyInjection
}
/// <summary>
/// Enables Application Insights for Kubernetes on the Default TelemtryConfiguration in the dependency injection system with custom options.
/// Enables Application Insights for Kubernetes on the Default TelemetryConfiguration in the dependency injection system with custom options.
/// </summary>
/// <param name="services">Collection of service descriptors.</param>
/// <param name="applyOptions">Action to customize the configuration of Application Insights for Kubernetes.</param>
@ -47,7 +47,7 @@ namespace Microsoft.Extensions.DependencyInjection
}
/// <summary>
/// Enables Application Insights for Kubernetes on the Default TelemtryConfiguration in the dependency injection system with custom options and debugging components.
/// Enables Application Insights for Kubernetes on the Default TelemetryConfiguration in the dependency injection system with custom options and debugging components.
/// </summary>
/// <param name="services">Collection of service descriptors.</param>
/// <param name="applyOptions">Action to customize the configuration of Application Insights for Kubernetes.</param>
@ -105,7 +105,7 @@ namespace Microsoft.Extensions.DependencyInjection
}
/// <summary>
/// Enables applicaiton insights for kubernetes.
/// Enables application insights for kubernetes.
/// </summary>
private static IServiceCollection EnableKubernetesImpl(IServiceCollection serviceCollection,
Func<bool> detectKubernetes,
@ -134,7 +134,7 @@ namespace Microsoft.Extensions.DependencyInjection
// Create a default logger when not passed in.
logger = logger ?? serviceProvider.GetService<ILogger<IKubernetesServiceCollectionBuilder>>();
// Apply the conifguraitons ifnot yet.
// Apply the configurations if not yet.
IOptions<AppInsightsForKubernetesOptions> options = serviceProvider.GetService<IOptions<AppInsightsForKubernetesOptions>>();
if (options.Value == null)

Просмотреть файл

@ -12,7 +12,7 @@ namespace Microsoft.Extensions.DependencyInjection
public static partial class ApplicationInsightsExtensions
{
/// <summary>
/// Enables Application Insights for Kubernetes on the Default TelemtryConfiguration in the dependency injection system.
/// Enables Application Insights for Kubernetes on the Default TelemetryConfiguration in the dependency injection system.
/// </summary>
/// <param name="services">Sets the collection of service descriptors.</param>
/// <param name="timeout">Sets the maximum time to wait for spinning up the container.</param>
@ -73,8 +73,8 @@ namespace Microsoft.Extensions.DependencyInjection
}
/// <summary>
/// Please use AddApplicationInsightsKubernetesEnricher() insead.
/// Enables Application Insights Kubernetes for the Default TelemtryConfiguration in the dependency injection system.
/// Please use AddApplicationInsightsKubernetesEnricher() instead.
/// Enables Application Insights Kubernetes for the Default TelemetryConfiguration in the dependency injection system.
/// </summary>
/// <param name="services">Collection of service descriptors.</param>
/// <param name="timeout">Maximum time to wait for spinning up the container.</param>
@ -92,7 +92,7 @@ namespace Microsoft.Extensions.DependencyInjection
}
/// <summary>
/// Please use "AddApplicationInsightsKubernetesEnricher()" insead.
/// Please use "AddApplicationInsightsKubernetesEnricher()" instead.
/// Enables Application Insights Kubernetes for a given
/// TelemetryConfiguration.
/// </summary>

Просмотреть файл

@ -4,19 +4,19 @@ namespace Microsoft.ApplicationInsights.Kubernetes
{
internal class KubeHttpClientFactory
{
public KubeHttpClientFactory(ILogger<KubeHttpClientFactory> logger, ILoggerFactory loggerFactory)
private readonly ILogger _logger;
private readonly ILogger<KubeHttpClient> _httpClientLogger;
public KubeHttpClientFactory(ILogger<KubeHttpClientFactory> logger, ILogger<KubeHttpClient> httpClientLogger)
{
_logger = Arguments.IsNotNull(logger, nameof(logger));
_loggerFactory = Arguments.IsNotNull(loggerFactory, nameof(loggerFactory));
_httpClientLogger = Arguments.IsNotNull(httpClientLogger, nameof(httpClientLogger));
}
public IKubeHttpClient Create(IKubeHttpClientSettingsProvider settingsProvider)
{
_logger.LogTrace($"Creating {nameof(KubeHttpClient)}");
return new KubeHttpClient(settingsProvider, _loggerFactory.CreateLogger<KubeHttpClient>());
return new KubeHttpClient(settingsProvider, _httpClientLogger);
}
private readonly ILogger _logger;
private readonly ILoggerFactory _loggerFactory;
}
}

Просмотреть файл

@ -5,18 +5,18 @@ namespace Microsoft.ApplicationInsights.Kubernetes
internal class K8sQueryClientFactory
{
private readonly ILogger _logger;
private readonly ILoggerFactory _loggerFactory;
private readonly ILogger<K8sQueryClient> _queryClientLogger;
public K8sQueryClientFactory(ILogger<K8sQueryClientFactory> logger, ILoggerFactory loggerFactory)
public K8sQueryClientFactory(ILogger<K8sQueryClientFactory> logger, ILogger<K8sQueryClient> queryClientLogger)
{
_logger = Arguments.IsNotNull(logger, nameof(logger));
_loggerFactory = Arguments.IsNotNull(loggerFactory, nameof(loggerFactory));
_queryClientLogger = Arguments.IsNotNull(queryClientLogger, nameof(queryClientLogger));
}
public K8sQueryClient Create(IKubeHttpClient httpClient)
{
_logger.LogTrace($"Creating {nameof(K8sQueryClient)}");
return new K8sQueryClient(httpClient, _loggerFactory.CreateLogger<K8sQueryClient>());
return new K8sQueryClient(httpClient, _queryClientLogger);
}
}
}

Просмотреть файл

@ -46,7 +46,7 @@ namespace Microsoft.ApplicationInsights.Kubernetes
Debug.Assert(options != null, "Options can't be null.");
_options = Arguments.IsNotNull(options?.Value, nameof(options));
_logger.LogDebug($@"Initialize Application Insihgts for Kubernetes telemetry initializer with Options:
_logger.LogDebug($@"Initialize Application Insights for Kubernetes telemetry initializer with Options:
{JsonConvert.SerializeObject(_options)}");
_sdkVersionUtils = Arguments.IsNotNull(sdkVersionUtils, nameof(sdkVersionUtils));

Просмотреть файл

@ -15,12 +15,13 @@
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)PublicKey.snk</AssemblyOriginatorKeyFile>
<!--Package-->
<VersionSuffix Condition=" '$(VersionSuffix)' == '' ">$([System.DateTime]::Now.ToString(yyyyMMddHHmm))</VersionSuffix>
<Version Condition=" '$(Version)' == '' ">1.0.2-private-$(VersionSuffix)</Version>
<AssemblyVersion Condition=" '$(AssemblyVersion)' == '' " >1.0.2.0</AssemblyVersion>
<Version Condition=" '$(Version)' == '' ">1.0.3-private-$(VersionSuffix)</Version>
<AssemblyVersion Condition=" '$(AssemblyVersion)' == '' " >1.0.3.0</AssemblyVersion>
<Authors>Microsoft</Authors>
<Company>Microsoft</Company>
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
<PackageLicenseUrl>https://github.com/Microsoft/ApplicationInsights-Kubernetes/blob/master/LICENSE</PackageLicenseUrl>
<!-- <PackageLicenseUrl>https://github.com/Microsoft/ApplicationInsights-Kubernetes/blob/master/LICENSE</PackageLicenseUrl> -->
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageProjectUrl>https://github.com/Microsoft/ApplicationInsights-Kubernetes/</PackageProjectUrl>
<PackageIconUrl>http://appanacdn.blob.core.windows.net/cdn/icons/aic.png</PackageIconUrl>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
@ -38,4 +39,7 @@
<StrongName>StrongName</StrongName>
</FilesToSign>
</ItemGroup>
<ItemGroup>
<None Include="$(MSBuildThisFileDirectory)../LICENSE" Pack="true" PackagePath=""/>
</ItemGroup>
</Project>

Просмотреть файл

@ -23,7 +23,7 @@ namespace Microsoft.ApplicationInsights.Netcore.Kubernetes
services = services.AddApplicationInsightsKubernetesEnricher(applyOptions: null, kubernetesServiceCollectionBuilder: null, detectKubernetes: () => true, logger: null);
Assert.NotNull(services.FirstOrDefault(sd => sd.ImplementationType == typeof(KubernetesTelemetryInitializer)));
// Replace the IKubeHttpClientSetingsProvider in case the test is not running inside a container.
// Replace the IKubeHttpClientSettingsProvider in case the test is not running inside a container.
Assert.NotNull(services.FirstOrDefault(s => s.ServiceType == typeof(IKubeHttpClientSettingsProvider)));
Mock<IKubeHttpClientSettingsProvider> mock = new Mock<IKubeHttpClientSettingsProvider>();
services.Remove(new ServiceDescriptor(typeof(IKubeHttpClientSettingsProvider), typeof(KubeHttpClientSettingsProvider), ServiceLifetime.Singleton));
@ -54,7 +54,7 @@ namespace Microsoft.ApplicationInsights.Netcore.Kubernetes
logger: null);
Assert.NotNull(services.FirstOrDefault(sd => sd.ImplementationType == typeof(KubernetesTelemetryInitializer)));
// Replace the IKubeHttpClientSetingsProvider in case the test is not running inside a container.
// Replace the IKubeHttpClientSettingsProvider in case the test is not running inside a container.
Assert.NotNull(services.FirstOrDefault(s => s.ServiceType == typeof(IKubeHttpClientSettingsProvider)));
Mock<IKubeHttpClientSettingsProvider> mock = new Mock<IKubeHttpClientSettingsProvider>();
services.Remove(new ServiceDescriptor(typeof(IKubeHttpClientSettingsProvider), typeof(KubeHttpClientSettingsProvider), ServiceLifetime.Singleton));
@ -69,7 +69,7 @@ namespace Microsoft.ApplicationInsights.Netcore.Kubernetes
}
else
{
Assert.True(false, "Not the target telementry initializer.");
Assert.True(false, "Not the target telemetry initializer.");
}
}
@ -84,7 +84,7 @@ namespace Microsoft.ApplicationInsights.Netcore.Kubernetes
}, kubernetesServiceCollectionBuilder: null, detectKubernetes: () => true, logger: null);
Assert.NotNull(services.FirstOrDefault(sd => sd.ImplementationType == typeof(KubernetesTelemetryInitializer)));
// Replace the IKubeHttpClientSetingsProvider in case the test is not running inside a container.
// Replace the IKubeHttpClientSettingsProvider in case the test is not running inside a container.
Assert.NotNull(services.FirstOrDefault(s => s.ServiceType == typeof(IKubeHttpClientSettingsProvider)));
Mock<IKubeHttpClientSettingsProvider> mock = new Mock<IKubeHttpClientSettingsProvider>();
services.Remove(new ServiceDescriptor(typeof(IKubeHttpClientSettingsProvider), typeof(KubeHttpClientSettingsProvider), ServiceLifetime.Singleton));
@ -99,7 +99,7 @@ namespace Microsoft.ApplicationInsights.Netcore.Kubernetes
}
else
{
Assert.True(false, "Not the target telementry initializer.");
Assert.True(false, "Not the target telemetry initializer.");
}
}
@ -118,7 +118,7 @@ namespace Microsoft.ApplicationInsights.Netcore.Kubernetes
applyOptions: null, kubernetesServiceCollectionBuilder: null, detectKubernetes: () => true, logger: null);
Assert.NotNull(services.FirstOrDefault(sd => sd.ImplementationType == typeof(KubernetesTelemetryInitializer)));
// Replace the IKubeHttpClientSetingsProvider in case the test is not running inside a container.
// Replace the IKubeHttpClientSettingsProvider in case the test is not running inside a container.
Assert.NotNull(services.FirstOrDefault(s => s.ServiceType == typeof(IKubeHttpClientSettingsProvider)));
Mock<IKubeHttpClientSettingsProvider> mock = new Mock<IKubeHttpClientSettingsProvider>();
services.Remove(new ServiceDescriptor(typeof(IKubeHttpClientSettingsProvider), typeof(KubeHttpClientSettingsProvider), ServiceLifetime.Singleton));
@ -133,7 +133,7 @@ namespace Microsoft.ApplicationInsights.Netcore.Kubernetes
}
else
{
Assert.True(false, "Not the target telementry initializer.");
Assert.True(false, "Not the target telemetry initializer.");
}
}
@ -155,7 +155,7 @@ namespace Microsoft.ApplicationInsights.Netcore.Kubernetes
}, kubernetesServiceCollectionBuilder: null, detectKubernetes: () => true, logger: null);
Assert.NotNull(services.FirstOrDefault(sd => sd.ImplementationType == typeof(KubernetesTelemetryInitializer)));
// Replace the IKubeHttpClientSetingsProvider in case the test is not running inside a container.
// Replace the IKubeHttpClientSettingsProvider in case the test is not running inside a container.
Assert.NotNull(services.FirstOrDefault(s => s.ServiceType == typeof(IKubeHttpClientSettingsProvider)));
Mock<IKubeHttpClientSettingsProvider> mock = new Mock<IKubeHttpClientSettingsProvider>();
services.Remove(new ServiceDescriptor(typeof(IKubeHttpClientSettingsProvider), typeof(KubeHttpClientSettingsProvider), ServiceLifetime.Singleton));
@ -170,7 +170,7 @@ namespace Microsoft.ApplicationInsights.Netcore.Kubernetes
}
else
{
Assert.True(false, "Not the target telementry initializer.");
Assert.True(false, "Not the target telemetry initializer.");
}
}