Azure Function fails to bind ILogger - azure

My function is referencing an assembly that references Microsoft.Extensions.Logging.Abstractions 2.0.0. If I add a nuget reference to that version to the function's assembly, function execution fails with:
[1/25/2018 11:14:46 PM] Microsoft.Azure.WebJobs.Host: Error indexing
method 'TrainingFunction.Run'. Microsoft.Azure.WebJobs.Host: Cannot
bind parameter 'log' to type ILogger. Make sure the parameter Type is
supported by the binding. If you're using binding extensions (e.g.
ServiceBus, Timers, etc.) make sure you've called the registration
method for the extension(s) in your startup code (e.g.
config.UseServiceBus(), config.UseTimers(), etc.).
Is it possible to use the newer logger in Azure functions ?
(SDK 1.0.7)

What is probably happening is that the SDK is binding to version X of the ILogger assembly and your user code is binding to version Y. The binding engine then doesn't recognize your parameter's type as being the same since they're from different assemblies. (this can happen with any other type too).
Generally the fix is to:
See the nugget references used by the SDK
Use those existing references and don't add the same dll with a different version.

I was somehow also having the same error, but it was the package version for Microsoft.EntityFrameworkCore.SqlServer what is causing the issue.
Downgrading Microsoft.EntityFrameworkCore.SqlServer v2.2.0 to v2.1.4 did the trick.
I assume that there is a version mismatch between logging.abstractions libraries for this package.

For me, the problem was that I needed to explicitly declare the Azure Functions Version in my .csproj file.
I added <AzureFunctionsVersion>v2</AzureFunctionsVersion> after the <TargetFramework> element:
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<AzureFunctionsVersion>v2</AzureFunctionsVersion>
</PropertyGroup>
Hope that helps someone :-)

Also binding-order could cause this failure.
Changing from parameter order ...
[FunctionName("SomeFunction")]
public static async Task Run([BlobTrigger("path", Connection = "conn")]
ILogger logger, ExecutionContext context, Stream stream, string name) {}
... to ...
[FunctionName("SomeFunction")]
public static async Task Run([BlobTrigger("path", Connection = "conn")]
Stream stream, string name, ILogger logger, ExecutionContext context) {}
... fixed my problem. (Microsoft.NET.Sdk.Functions v1.0.24)

For me, I was using NuGet package Microsoft.Extensions.Logging on a project referenced by my Azure function. Uninstalled this package and my error (this exact error) went away.
I didn't actually need the NuGet package to use ILogger in my Azure function.
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
Edit: Also downgrading to Microsoft.Extensions.Http 2.1.0 worked on another occurrence of this error. If you still need the Extensions package (for IHttpClientFactory for example) it's possible to get this logging error because of an SDK version conflict with 3.1.1.

As stated by one of MS employees the cause could be:
we don't quite yet support .NET Core 2.2, but we have the work underway and should ship in January.
https://github.com/Azure/azure-functions-host/issues/3854#issuecomment-449034719

Another reason for the same error...
Somehow I ended up with a using statement referencing Microsoft.Build.Framework which has its own version of ILogger the fix is just to replace this with Microsoft.Extensions.Logging which the functions app is expecting

This will also happen when updating Azure Functions/Durable Functions from v2 to v3. You need to manually edit .csproj to resolve the ILogger reference problem.
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
...
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.2" />
</ItemGroup>
The function will continue to report a run-time module error. Then you have to try to create new Azure Function v3 project in Visual Studio to download the templates for run-time modules. More information on the procedure is provided in the official documentation: Azure Functions runtime versions overview

I had to uninstall Microsoft.Extensions.Logging nuget package from the solution.

I suddenly started getting the ILogger binding error after auto-updating my Nuget packages.
I couldn't find any explict references to ILogger extensions in my solution files. It turned out the culprit was a different extension Microsoft.Extensions.Caching.Memory that updated to v5.00 (.NET 5?). Downgrading that package to the prior version 3.1.15 fixed the error (I was originally at v3.1.4). I wonder if any v5.x extension package would trigger this issue.

What worked for me was downgrading "Microsoft.Extensions.Http" from version 5.x.x.x to "3.1.20", which implicitly downgrades "Microsoft.Extensions.Logging" to "3.1.20"
It looks like there is an implicit dependency with the version 5.x of Http library and "Microsoft.Extensions.Logging" version 5.x , and that version of logging has some issue with it.

Related

How to fix deprecated nuget-package NLog.Config

Just noticed that in my list of Nuget packages, that "NLog.Config" is marked as deprecated:
Is it safe to simply delete the package?
This particular application is for Google Calendar API usage.
I should have looked more closely at my code. I removed the package and now my tool won't compile. I have code like:
Imports NLog
Private m_logger As NLog.Logger = LogManager.GetCurrentClassLogger()
And 10 instances of calls like:
m_logger.Error(ex, "RESULT_FAILED_OAUTH")
How to resolve now that NLog is deprecated?
NLog.config-nuget-package is safe to remove, and one is encouraged to remove it. It became obsolete when Microsoft introduced <packagereference>-syntax.
Now the NLog.config-nuget-package actually causes issues because it can reset the NLog.config-file on application-publish (Same story can also seen on the nuget-package-page)
Just replace it with NLog-nuget-package, if you don't have it installed already.

ImageMagick on Azure Functions cannot load native library

I'm trying to use Magick.NET library to do image processing on Azure Functions.
I have tried the same code in a Console App (.NET Core 3.1) which works without any issues. However when running the same code in an Azure Functions Project, I get the following error.
Code:
var image = new MagickImage(File.ReadAllBytes(#"<My Image Path>"));
Exception:
System.TypeInitializationException: 'The type initializer for 'NativeMagickSettings' threw an exception.'
StackTrace:
at ImageMagick.MagickSettings.NativeMagickSettings..ctor()
at ImageMagick.MagickSettings..ctor()
at ImageMagick.MagickImage..ctor()
at ImageMagick.MagickImage..ctor(Byte[] data)
at FunctionApp2.Function1.Run(TimerInfo myTimer, ILogger log) <-- My Code
Inner Exception:
Unable to load DLL 'Magick.Native-Q8-x64.dll' or one of its dependencies: The specified module could not be found. (0x8007007E)
Inner Exception StackTrace
at ImageMagick.Environment.NativeMethods.X64.Environment_Initialize()
at ImageMagick.Environment.NativeEnvironment.Initialize()
at ImageMagick.Environment.Initialize()
at ImageMagick.MagickSettings.NativeMagickSettings..cctor()
I believe this is due to the way Azure Functions package is organized and the path Magick.NET is looking for its native binary to load. I can confirm that the native binary is written at \bin\Debug\netcoreapp3.1\runtimes\<platform>\native when the Function app is built.
I have traced the apps using ProcessMonitor for each app and can see Function app looks in the wrong location.
It looks in
\bin\Debug\netcoreapp3.1\ bin\ runtimes\[platform]\native
instead of
\bin\Debug\netcoreapp3.1\runtimes\[platform]\native
(Below traces are filtered to only show path contains Magick.Native and process name filtered to the Console app exe and func.exe)
Console App Trace
Function App Trace
I have also tried setting MagickAnyCPU.CacheDirectory to Directory.GetCurrentDirectory() but it hasn't helped.
UPDATE:
After building, if I copy \netcoreapp3.1\runtimes folder to \bin this fixes the problem, but I current don't want to rely on that trick if there's a proper workaround.
UPDATE 2:
This issue appears to happen only when using
<TargetFramework>netcoreapp3.1</TargetFramework>
and Microsoft.NET.Sdk.Functions version 3.0.x
It does not appear when using older versions. I have successfully used
<TargetFramework>netcoreapp2.1</TargetFramework>
and Microsoft.NET.Sdk.Functions version 1.0.x
without this issue.
So, is there a workaround to get ImageMagick to load native lib from the right place?
Potential Workaround is to get msbuild to copy the runtimes folder after the build completes.
Add following to csproj
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="xcopy /Y /E $(OutDir)runtimes\ $(OutDir)bin\runtimes\" />
</Target>
or right click project > properties > Build Events and paste the above command to post build event command line
This will copy all of the runtimes binaries, not just the one we want, increasing the size of final build.
UPDATE:
This may be a bug in Microsoft.NET.Sdk.Functions version 3.0.8.
These issues in the github repo are tracking this.
Version 3.0.8 places the runtimes folder incorrectly
Microsoft.Data.SqlClient is not supported on this platform with Microsoft.NET.Sdk.Functions 3.0.8
This seems to only happen when using Microsoft.NET.Sdk.Functions version 3.0.8 which seems to have only just appeared in nuget on Friday. I will instead downgrade to 3.0.7.
Alternatively if you don't want to downgrade,
You could use MagickNET.SetNativeLibraryDirectory as a work around

Azure Functions V1 linking wrong version of the RestSharp.dll

Guys I know that the azure functions cli has a dependency with RestSharp.dll and I think that is conflicting with one of my Azure Functions.
I am getting a runtime type exception
System.TypeLoadException: 'Could not load type 'RestSharp.IAuthenticator' from assembly 'RestSharp, Version=105.2.3.0, Culture=neutral, PublicKeyToken=null'.'
Now my azure function is dependent on RestSharp nuget Version 104.4.0.0. There is no reference in my project to Version 105.2.3.0. Here is the interesting thing. In my despair I searched my entire computer for the culprit dll version 105.2.3.0 and I found it at AppData\local\Azure.Functions.Cli\1.0.12
Is that it ? Is the Azure functions runtime trying to link with its RestSharp.dll version instead of the dll version of my project ?
Runtime should technically load version 104.4.0.0. However it is still loading the version referred by the runtime (105.2.3.0). I was able to verify this behavior. Have filed a bug for this https://github.com/Azure/azure-functions-host/issues/2832.
In the meantime is it possible to do one of the following:
Update the code to use 105.2.3.0, I see RestSharp.IAuthenticator type is present. It is under a different namespace. There should be another method exposing the same functionality
If the function app is not being used in prod. You could use the beta runtime. You should not encounter this issue in beta runtime (v2.x)

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.

Azure WebJobs ServiceBus returns Exception: found 2 DNS claims in authorization context

I'm trying to read a message from an Azure ServiceBus queue using an Azure WebJob but it's throwing and exception:
Unhandled Exception: System.InvalidOperationException: Found 2 DNS claims in authorization context.
I've set the correct connection strings named "AzureWebJobsServiceBus", "AzureWebJobsDashboard" and "AzureWebJobsStorage"
The WebJob Program code has been updated to use JobHostConfiguration:
class Program
{
static void Main()
{
var config = new JobHostConfiguration();
config.UseServiceBus();
var host = new JobHost(config);
host.RunAndBlock();
}
}
And the actual Job method
public class Functions
{
public async static Task ServiceBusResizeRequest(
[ServiceBusTrigger("blah")] string message,
TextWriter log
)
{
await log.WriteLineAsync("got message " + message);
}
}
I can successfully create and write to the queue via a separate console application.
But when I run the webjob application, it throws that exception.
Any ideas?
EDIT: Using .net 4.6.1
The answer marked as solution, is not the solution, it is a botched job.
The solution to use it in .Net Framework 4.6.1 is to add in the rutime block in App.config:
<AppContextSwitchOverrides value="Switch.System.IdentityModel.DisableMultipleDNSEntriesInSANCertificate=true" />
Read this article Mitigation: X509CertificiateClaimSet.FindClaims Method
Very IMPORTANT for now Azure WebApps / WebJob etc, doesn't support 4.6.1 I will note here when (said at jan 21, 2016).
It means, that you can develop a web job application with 4.6.1, but when you push it to Azure, you can see exceptions like Job failed due to exit code -2146232576
January 29th Microsoft released version 3.1.3 of the NuGet package WindowsAzure.ServiceBus.
From the release notes:
• General: .Net 4.6.1+ compatibility fix. Fixing custom DNS IdentityVerifier so that we honor multiple DNS claims returned by WIF
Upgrading the package solved the problem for us.
As outlined in this answer above, the snippet below does the trick
<runtime>
...
<AppContextSwitchOverrides value="Switch.System.DisableMultipleDNSEntriesInSANCertificate=true" />
...
<runtime>
BUT be carefull to add it to the correct project in your solution! Add it to the project containing the Azure code and Azure references.
Microsoft released a new package (under a new name) to fix this issue. So ...
remove the Microsoft.AspNet.SignalR.ServiceBus package,
install the Microsoft.AspNet.SignalR.ServiceBus3 package instead, and
upgrade the WindowsAzure.ServiceBus package.
More info here: https://github.com/SignalR/SignalR/issues/3548#issuecomment-296326048
Downgrading from .net 4.6.1 to 4.6 seems to prevent the issue from occurring.
Today, I ran into this issue and had no idea about it. Finally, I decided to upgrade all the Azure nuget packages that I am using (including webjobs, servicebus ...) and BOOM! it WORKS. Hopefully, it will help if anyone runs into this issue in the future
For me it started failing after I updated .NET Framework from 4.5.2 to 4.7
All I did to fix it was update the Nuget Package WindowsAzure.ServiceBus to 5.2.0

Resources