Skip to content

devr24/Cloud.Core.Telemetry.AzureAppInsights

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Cloud.Core.Telemetry.AzureAppInsights

Build status Code Coverage Cloud.Core.Telemetry.AzureAppInsights package in Cloud.Core feed in Azure Artifacts

Azure specific implementation of telemetry logging. Uses the ITelemeteryLogger interface from Cloud.Core and can be used in conjunction with the Telemetry Logging Provider classes found in the Cloud.Core.Telemetry.Logging package.

Usage

As the logger follows the base ILogger implementation, it's very flexible in how it can be used. To create an instance, do the following:

var logger = new AppInsightsLogger("insightsKey");

logger.LogInformation("Sample information message");
logger.LogWarning("Sample warning message");
logger.LogDebug("Sample debug message");
logger.LogException("Sample exception message");

Any of the logging methods can also handle exception, such as:

logger.LogWarning(new Exception("Something's gone wrong!"));

Configuring an instance

Inline instance

There are a number of ways to create an instance of the AppInsights logger, the simpliest and most direct way is the following:

var logger = new AppInsightsLogger("instrumentationKey", LogLevel.Debug);

Instance using Dependency Injection

A typical use case is as an instance of the ITelemetryLogger interface and with an IServiceCollection. Therefore, leveraging the extensions methods that have been built for convenience as follows during the Logger configuration is probably easier:

private static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
	WebHost.CreateDefaultBuilder(args)
		.ConfigureAppConfiguration(config => {

			// Import default configurations (env vars, command line args, appSettings.json etc).
			config.UseDefaultConfigs();
		})
		.ConfigureLogging((context, logging) => {
			
			// Add logging configuration and loggers.
			logging.AddConfiguration(context.Configuration)
				.AddConsole()
				.AddDebug()
				.AddAppInsightsLogger(); // automatically resolves instrumentation key and log levels.
		})
		.UseStartup<Startup>();

Here we can see we did not specify the config level or the instrumentation key. The instrumentation key is resolve automatically by pulling one of the following from config:

  1. InstrumentationKey
  2. APPINSIGHTS_INSTRUMENTATIONKEY
  3. Logging:InstrumentationKey
  4. AppInsights:InstrumentationKey

If It cannot find it here, it will throw an invalid argument exception.

public class Startup
{
    public void ConfigureAppConfiguration(IConfigurationBuilder builder)
    {
		// Import default configurations (env vars, command line args, appSettings.json etc).
        builder.UseDefaultConfigs();
    }

    public void ConfigureLogging(IConfiguration config, ILoggingBuilder builder)
    {
        builder.AddConfiguration(config.GetSection("Logging"));

        // Add some default loggers.
        builder.AddConsole();
			   .AddDebug();

        // Explicitly specifying the instrumentation key.
        var instrumentationKey = config.GetValue<string>("InstrumentationKey");
        builder.AddAppInsightsLogger(instrumentationKey);
    }

    public void ConfigureServices(IConfiguration config, ILogger logger, IServiceCollection services)
    {
        // Configure services...
    }
}

The second example (explicit setting of instrumentation key), you pass it an instruementation key you have loaded yourself.

Both examples above will look for log level from config specified in the "Logging:LogLevel:Telemetry" setting. If it cannot find that, it will default to Logging:LogLevel:Default for its setting. Failing that, it falls back to info.

Logging Metrics and Custom Dimensions

ITelemeteryLogger logger = new AppInsightsLogger("instrumentationKey");

// Log metrics stats.
logger.LogMetric("Metric Name", 100);

// Log custom dimensions (as dictionary).
logger.LogInformation("Some log message", new Dictionary<string, string> { 
	{ "dimension1", "someVal" },
	{ "dimension2", "someOtherVal" }
});

// Log custom dimensions (as object). This functionality allows for Pii data masking.
logger.LogInformation("Some log message", new ExampleModel { Property1 = "someval", Property2 = true });

Pii Data Masking

Take this model that has Personal Data (Pii) flagged as an example:

public class ExampleModel {
	public string Id { get; set; }
	[PersonalData]
	public string Name { get; set; }
	public bool IsActive { get; set; }
}

When we log the model, the Name field will be masked:

// Pii data model.
var model = new ExampleModel { 
	Id = "12345", 
	Name = "Robert", 
	IsActive = true 
};

// Logging model allows for Pii data masking.
logger.LogInformation("Some log message", model);

NOTE: Fields that have been marked as Cloud.Core.Attributes.PersonalData, Cloud.Core.Attributes.SensitiveInfo or Microsoft.AspNetCore.Identity.PersonalData are masked automatically when writing custom dimensions. The log message itself and the dicntionary are not checked for personal information - masking can only be used when logging a model (as then the properties can be reflected and inspected for the appropriate attributes).

Further Reading

Read more about logging providers and filters here: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-3.1

Test Coverage

A threshold will be added to this package to ensure the test coverage is above 80% for branches, functions and lines. If it's not above the required threshold (threshold that will be implemented on ALL of the core repositories to gurantee a satisfactory level of testing), then the build will fail.

Compatibility

This package has has been written in .net Standard and can be therefore be referenced from a .net Core or .net Framework application. The advantage of utilising from a .net Core application, is that it can be deployed and run on a number of host operating systems, such as Windows, Linux or OSX. Unlike referencing from the a .net Framework application, which can only run on Windows (or Linux using Mono).

Setup

This package is built using .net Standard 2.1 and requires the .net Core 3.1 SDK, it can be downloaded here: https://www.microsoft.com/net/download/dotnet-core/

IDE of Visual Studio or Visual Studio Code, can be downloaded here: https://visualstudio.microsoft.com/downloads/

How to access this package

All of the Cloud.Core.* packages are published to a public NuGet feed. To consume this on your local development machine, please add the following feed to your feed sources in Visual Studio: https://dev.azure.com/cloudcoreproject/CloudCore/_packaging?_a=feed&feed=Cloud.Core

For help setting up, follow this article: https://docs.microsoft.com/en-us/vsts/package/nuget/consume?view=vsts

About

Azure AppInsights implementation of ITelemetryLogger interface.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages