Technical · WCF
From WCF on-premise to Azure App Service. Part II
April 17, 2023
In Part I, we discussed the case of moving Windows Communication Foundation (WCF) services to Azure App Services. In Part II, we are discussing the particular requirement of integrating Azure Application Insights using Application settings for the Log Level and Instrumentation Key, a few approaches we tested, and what we finally did considering our Operations Team, support, and the automated pipelines used for deployment.
Integrating Azure Application Insights with a Legacy Windows Communication Foundation (WCF) Service
Azure Application Insights is a service that allows consolidations of traces, logs, analytics, and events on a handy and easy-to-use tool that can be queried using a very common syntax (Similar to SQL)
There are multiple samples of how to integrate Application Insights on .Net Core, .Net 5, and so on. However, if you want to use Application Insights with a Windows Communication Service (WCF), things get more complicated.
Using Log4Net — Application Insights Appender
One option is using the Log4Net Application Insight Appender. That’s easy to use and allows you to have the same type of logging you probably already have. (there are caveats like the operation name not being sent, but that’s for another day)
However, if you want to use only Application Insights, not Log4Net appenders, and if you need to have a different Application Insight target for different environments (Dev, Stage, Production) there are complications on how to have the right Instrumentation Key on the right place.
In our particular case, we want to have the Instrumentation Key as part of the App Settings, so if we ever need to change the Application Insights Target, we can do it without redeployment of the solution (We use automated pipelines and modify files on the Azure App Service is not allowed, and it shouldn’t be. )
Using Azure Application Insights
Setting Azure Application Insights is very simple, Nuget package manager will take care of adding the right libraries and dependencies. We are using:
Microsoft.ApplicationInsights and Microsoft.ApplicationInsights.TraceListener,
both have support for our flavor of the .Net Framework (4.7.2)
Now, what we found difficult to understand is that you will need to inject the logger into the service. Good thing that WCF Services has been around with dependency injection for a long time, so we can create a new service collection and configure the Telemetry we need.
To do that, additional Nuget packages are needed:
Microsoft.Extensions.Configuration
Microsoft.Extensions.Configuration.Abstractions
Microsoft.Extensions.Configuration.Binder
Microsoft.Extensions.DependencyInjection
Microsoft.Extensions.Logging
Microsoft.Extensions.Logging.Abstractions
Microsoft.Extensions.Logging.ApplicationInsights
Let’s see some code. This code runs on the constructor of the class that implements the service Interface (Service Contract and Operation Contract). Therefore, it runs only once on the service creation, and from it, all operations will have the log system in place.
private static ILogger log;
// Class Constructor
myclass()
{
var aiInstrumentationKey = ConfigurationManager.AppSettings["APPINSIGHTS_INSTRUMENTATIONKEY"].ToString().ToUpper().Trim();
var logLevel = ConfigurationManager.AppSettings["APPINSIGHTS_LOG_LEVEL"].ToString();
var channel = new InMemoryChannel();
IServiceCollection services = new ServiceCollection();
services.Configure(config => config.TelemetryChannel = channel);
services.AddLogging(builder =>
{
// Only Application Insights is registered as a logger provider
builder.AddApplicationInsights(
configureTelemetryConfiguration: (config) => config.InstrumentationKey = aiInstrumentationKey,
configureApplicationInsightsLoggerOptions: (options) => { }
);
builder.SetMinimumLevel((LogLevel)Enum.Parse(typeof(LogLevel), logLevel, true));
});
IServiceProvider serviceProvider = services.BuildServiceProvider();
log = serviceProvider.GetRequiredService>();
log.BeginScope(new Dictionary{ ["OperationName"] = ConfigurationManager.AppSettings["MyApplicationName"].Trim() });
log.LogInformation("WCF-MyApp Service is Up and Running - Logger is working...");
log.LogDebug("WCF-MyApp Debug Mode Enabled...");
}
We are getting the instrumentation key and the log level from Application Settings, which is very handy for operations and DevOps to debug any problem with the service on Production. Also, to reduce what we spend on Logging on to healthy applications.
Then, we create the service collection and inject the ApplicationInsights logging provider.
builder.AddApplicationInsights(
configureTelemetryConfiguration: (config) => config.InstrumentationKey = aiInstrumentationKey,
configureApplicationInsightsLoggerOptions: (options) => { }
);
builder.SetMinimumLevel((LogLevel)Enum.Parse(typeof(LogLevel), logLevel, true));
Here is where the magic happens, we are creating and setting up the provider with the instrumentation key and the log level on the first run of the service.
Finally, we have a logger ready to go. 🚀
log = serviceProvider.GetRequiredService>();
log.BeginScope(new Dictionary{ ["OperationName"] = ConfigurationManager.AppSettings["MyApplicationName"].Trim() });
log.LogInformation("WCF-MyApp Service is Up and Running - Logger is working...");
log.LogDebug("WCF-MyApp Debug Mode Enabled...");
We store the log on a “global” scope property and set up a few goodies.
First, we pass the operation name to the logger (so we can do better queries inside Application Insights)
Second, we create a log information record to start logging when our service is up and running, and finally, a log debug record for those cases when the debug mode is on.
Conclusion
In this post, we are using Azure Application Insights with a .Net 4.7.2 Windows Communication Service Running on Azure App Service. After trying to implement Log4Net Application Insights Appender, we choose to use the Microsoft Application Insights package instead.
We are extracting the instrumentation key and the log level from the Application Settings to have better tools for our Operations Team and to integrate better with a multiple environments automated pipeline.
These results, concepts, and ideas were possible with the collaboration of my good friend Jon Magistro. (Great techy, better musician and pepper grower) 🌶
If you found this post helpful in migrating a Windows Communication Foundation Service to Azure App Service, clap. You know the drill.
Do you want to get my latest posts and insights? Follow me here on Medium, or Linkedin (https://www.linkedin.com/in/juancarlospelaez/)
This post has been written by a Human Being.
Originally published on Medium in 3Metas.
Related reading
- From WCF on-premise to Azure App Service. Part I
April 11, 2023 · WCF
- Multicast Message Routing with WCF 3.5
December 5, 2010 · WCF
- Adding Custom SOAP Headers in WCF 3.5
December 5, 2010 · WCF
More in the Digest — a weekly roundup of AI and agents news — or start with AI Strategy.