EventLog access is not supported on this platform when calling dependency from Azure Function - azure

I am trying to create an azure function (v2) but it needs to reference an existing class library which is built for .netframework and is currently used for a .net web project. In the referenced library a lot of code is wrapped in try / catches where we log the exception to the EventLog.
My question is, how can I make it so that the referenced library handles the EventLog code or is this something that is not possible?
I have tried calling event log directly from a simple function (i.e. EventLog.WriteEntry(...) but that causes the same error: EventLog access is not supported on this platform. I take it, this is because its expecting me to use the built in ILogger instance to perform the logging...
I've read that we can add the Nuget package for compatibility and also one for EventLog. Tried both and still no luck...

Related

Logging in Azure and Console app from NuGet library

looking for some advice here on developing a common logging environment for a NuGet package.
I've currently got a private NuGet package created from a C# library that works perfectly for local console apps and as such was written to log to the Windows event log.
Now I want to be able to use that package in an Azure function but of course Azure uses a different logging mechanism.
Any advice on how to create a logging overlay that allows the library to be compiled on my local PC in Visual Studio but also support logging in Azure if the package is used there?
Cheers,
Dave
I believe you are looking for the Microsoft.Extensions.Logging namespace and interface. This interface is used extensively across azure services, .Net 4+ and .Net Core. If you look for related nuget packages you will find multiple implementations for different logging scenarios and tools, including native sinks like event logs, functions, console as well as custom sinks like Splunk and Serilog.
If you separate your logging implementation from your application/package code and implement Microsoft.Extensions.Logging and adhere to the interface, then your logging interface can be easily plumbed in to many supported sinks, including functions.
A previous answer of mine provides an earlier, more manual approach to this problem. See here.

Azure Function gives error: System.Drawing is not supported on this platform

(If this question is poorly worded, could someone please help me clear it up?)
I have an Azure Function (2.0) which relies on some System.Drawing code. I've added a NuGet reference to System.Drawing.Common (4.5.0).
After publishing the app, however, when the function is called, it produces the error:
System.Private.CoreLib: Exception while executing function:
[MyFunctionName]. System.Drawing.Common: System.Drawing is not
supported on this platform.
As far as I'm aware, System.Drawing.Common is supported on .NET Core now, which I believe is the environment in which my Azure Function is running. The actual project is a .NET Standard 2.0 project, though.
I am confused as to how to resolve this. I've tried converting the project to a .NET Core 2.1 project but that led to bizarre errors related to "Metadata generation failed" and an inability to find System.Runtime.
My project references Microsoft.Azure.WebJobs.Extensions.EventGrid (2.0.0-beta2) if that's relevant.
It's not about the CLR, it's about the sandbox.
System.Drawing relies heavily on GDI/GDI+ to do its thing. Because of the somewhat risky nature of those APIs (large attack surface) they are restricted in the App Service sandbox.
Win32k.sys (User32/GDI32) Restrictions
For the sake of radical attack surface area reduction, the sandbox prevents almost all of the Win32k.sys APIs from being called, which practically means that most of User32/GDI32 system calls are blocked. For most applications this is not an issue since most Azure Web Apps do not require access to Windows UI functionality (they are web applications after all).
Try to find an different library that doesn't rely on System.Drawing/GDI, like ImageSharp.
A little update can help a lot of people.
Now you can switch your Azure Function to v3:
in Function app settings panel -> Runtime version ~3
With this setup, your code run in a sandbox that support Core 3, (you don't need to rebuild your dll to Core3, i run my .net core 2.1 dll without errors), and surprise... you don't get this exception anymore:
System.Drawing.Common: System.Drawing is not supported on this platform.
Because the CLI can found GDI/GDI+ that need in the subsystem.
Now i can convert html to pdf without go crazy.

Custom TelemetryInitializers in AzureFunctions

Short: Is there any way to add a custom ITelemetryInitializer to an AzureFunction application?
Long:
After successfully integrating our AzureFunction application with ApplicationInsights and thoroughly instrumenting our code, it became evident really quickly that we'd need to correlate the various Trace and Request telemetry together. To do this we wanted to reuse a custom property we write to all trace logs called a SessionId.
A quick search yielded this SO post and this Docs article. The problem is that these articles assume I have access to some startup event or to the ApplicationInsights.config file on the server. I could be wrong but I don't believe I have access to either one of these.
So my question is, how do I do this with AzureFunctions?
No, it's not possible to customize that. There is work in progress to allow that, but it's not there yet.
You can see more details on these Github issues
application insights integration - ITelemetryInitializer doesn't have any effects #1416
Unable to access TelemetryConfiguration in DefaultTelemetryClientFactory (App Insights) #1556
EDIT:
It's possible in azure function v2.
There was a question on stackoverflow with problem here:
Custom Application Insight TelemetryInitializer using Azure Function v2
The problem was solved and from version Microsoft.Net.Sdk.Functions 1.0.25 all works fine, more here:
https://github.com/Azure/azure-functions-host/issues/3731#issuecomment-465252591
One abhorrent solution I came up with is to reflect into the ILogger that gets passed to the function to get at the ILogger array it hides inside. Then find the ApplicationInsightsLogger ILogger and reflect harder to pull out the TelemetryClient it uses. Once you get this you can merely set the SessionId property on the client's Context.
This works "great" however not only do I now have reflection in my code I had to downgrade the version of ApplicationInsights package I was using to get the type casting to stick.
Looking forward to better support in the future.

Azure Functions dll version mismatch

We have an Azure function which references an external assembly via a private Nuget feed.
The problem we're having is that we have two different versions of Microsoft.Azure.WebJobs.dll - one which is a dependency of our nuget package and another which I'm assuming is being provided by the runtime.
error CS1503: Argument 2: cannot convert from 'Microsoft.Azure.WebJobs.ICollector<Microsoft.WindowsAzure.Storage.Table.ITableEntity> [D:\Program Files (x86)\SiteExtensions\Functions\1.0.10635\bin\Microsoft.Azure.WebJobs.dll]' to 'Microsoft.Azure.WebJobs.ICollector<Microsoft.WindowsAzure.Storage.Table.ITableEntity>
I found this question which says that binding redirects are not supported:
Azure Functions binding redirect
We could try to remove our dependency on that library, or we could match the version used by Azure Functions, but I think we're going to have the same problem with using Microsoft.WindowsAzure.Storage anyway.
Please advise!
You are correct that binding redirects are not supported. The runtime has its own dependencies on the WebJobs SDK and Storage libraries so objects passed into your functions will be from those versions. I recommend removing your dependencies on other versions and snapping to ours. Note that for these libraries, you don't have to add your own package reference, you can reference ours in your function code via:
#r "WindowsAzure.Storage"
You don't need to add explicit #r references for WebJobs SDK types (e.g. ICollector<T>) - the runtime adds that assembly implicitly. Of course this only applies for function code we're compiling for you, not code coming from your external packages.
In the future we might improve things in this area, but for now you'll be swimming up stream if you try to use conflicting versions.

Execute pre-compiled .NET code as Azure Function

How do I upload a pre-compiled .NET assembly(-ies) and execute my code as Azure Functions?
I'm looking for a way to run some complex domain logic, which is contained inside custom assemblies and is covered by unit tests etc.
What kind of limitations for this code are there? E.g. access remote data stores, networking etc.
Update: The below answer is still correct (still works), however there is now also first class support for precompiled functions. See the wiki page for more information on that.
The documentation (link here) describes how you can reference external libraries and Nuget packages from a C# Function using the #r syntax, e.g:
#r "System.Web.Http"
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
public static Task<HttpResponseMessage> Run(HttpRequestMessage req)
Additional details on this can be seen in this SO post.
You can also deploy custom executables and call them from your Azure Functions. For example, if you start from the Windows BAT template, you can use that to call out to an exe. Here's a sample of this in our repo, showing an image resize example. In this sample, we have a BAT script that is triggered whenever a new image is uploaded to a blob container, and the script calls out to a Resizer.exe tool to do the resize:
.\Resizer\Resizer.exe %original% %resized% 200
Regarding limitations, all Azure Functions code runs in the App Service sandbox whose limitations are described here.
To run a pre-compiled .NET assembly in an Azure Function, it's possible to upload a custom dll by FTP in the function root folder (within a bin folder) and then use #r to reference it from the azure function code.
Here is an example, a dll named "WorkOnImages.dll" is uploaded in an azure in azure function folder :
Then the dll is referenced in the azure function :
Here is the source blog post
Discouraged by the lack of Azure Function tooling support for VS2017, incompatibility with Azure SDK 3.0, I was about to throw in the towel for Functions and fallback to an approach using VS2017 and WebJobs SDK.
Then announced on March 16th, 2017, the easiest approach is documented here in an excellent blog post by Microsoft's Donna Malayeri.
It does everything I could want - true intellisense, debugging capabilities. It's been great and I wouldn't look back.

Resources