I am working through replacing some WebJobs with Azure Functions and appear to have all working OK except for logging of what is going on.
I have tried using the default function created within VS2017 and have run it locally with no problems. When deployed to Azure I cannot see the detail of the log entries anywhere.
Using Kudu to view the logs seemed OK except that I noticed that the log param of a function invocation is always null. This can't be the case as the function does run, and gives the expected output, and would fail if log was really null.
Here's what the function looks like:
public static class Function1
{
[FunctionName("Function1")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
return name != null
? (ActionResult)new OkObjectResult($"Hello, {name}")
: new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}
}
I would have expected to see the output of the log within Kudu by going to https://xxx.scm.azurewebsites.net/azurejobs/#/functions but I can't see the details when I toggle the output - it never loads (and it shows the log param as being null - perhaps is being resolved by DI though).
Whilst this function is simply a test I do have other more complicated functions that I need the logging details for.
I am not keen on investigating Application Insights as this seems way, way overkill for such simple functions that will not be used very heavily.
For v2 functions in runtime 2.x, doc explains
the WebJobs dashboard in the portal, which used the AzureWebJobsDashboard setting is replaced with Azure Application Insights, which uses the APPINSIGHTS_INSTRUMENTATIONKEY setting.
Like what you have seen, with AzureWebJobsDashboard setting, the log param is null and no log there. I am afraid the replaced with was enforced and Dashboard has been deprecated.
As for the usage of Application insights, we could just leverage the basic log monitoring without any further investigation. After creating it and add its instrumentationkey in Application settings, we could see the Monitor view is similar to Dashboard.
If we don't like it anyway, logs in kudu(https://<functionAppName>.scm.azurewebsites.net/DebugConsole) are ready there(D:\home\LogFiles\Application\Functions\function\<functoinName>).
Related
I am a newbie to Azure functions. I am having problem with the below code where CosmosDB binding is not working. If I remove CosmosDB, it works find; I am able to get messages thru eventGridEvent. But as soon as I add CosmosDB, this piece of code fails. I had tried different Collectors (IAsyncCollectory, IReadOnlyCollection, IReadOnlyList, IEnumerable, etc.) some of them compiles fine but when deployed to Azure portal it does nothing (msg: function not found).
I need to retrieve data from CosmosDb and save it to a Queue by using the message coming thru eventGridEvent. I can hardcoded but that is not allowed for my project. Any help will be appreciated team!
[FunctionName("TopicGridTrigger")]
public static void Run([EventGridTrigger()] EventGridEvent eventGridEvent,
[Queue("myqueuetest")] out string queueMessage,
[CosmosDB("MyCarStore", "cars", ConnectionStringSetting = "CosmosDBConnectionString")] IAsyncCollector<MyCar> Items,
ILogger log
)
{
//SOME CODE HERE
}
I'm working on exploring the following 2 features of Azure App Configuration in Azure Function's Http Trigger
Externalizing the App Settings
Feature Flags
Below is how i'm getting the reference of the configuration
So, when I use _configuration["SomeAppSettingKey"], I'm able to retrieve the value. So, I'm able to achieve #1 feature mentioned above.
My Question is, How do we retrieve the Feature Flag information? I have tried the below ways.
I would appreciate if someone could help me in understanding how to retrieve it in Azure Functions (I'm using V3)? A Sample code or any reference to documentation would be helpful.
Thanks.
Update1:
I can deserialize the json content as shown below. But, is this is the right approach?
Where FeatureManager is a class that I have defined as shown below.
all you need is to call UseFeatureFlags() function as part of AddAzureAppConfiguration to let the App Configuration provider know you want to use feature flags. An example can be found following the link below. It uses the FunctionsStartup and dependency injection (DI) of Azure Functions. An instance of a feature manager is put into the DI.
https://github.com/Azure/AppConfiguration/blob/master/examples/DotNetCore/AzureFunction/FunctionApp/Startup.cs
The link below shows how you can obtain the instance of IFeatureManagerSnapshot from DI and use it as part of your Azure Functions call.
https://github.com/Azure/AppConfiguration/blob/master/examples/DotNetCore/AzureFunction/FunctionApp/ShowBetaFeature.cs
Deserialize JSON is not a good idea, every time you will add new key you need to modify your class.
private static IConfiguration Configuration { set; get; }
static Function1()
{
var builder = new ConfigurationBuilder();
builder.AddAzureAppConfiguration(Environment.GetEnvironmentVariable("ConnectionString"));
Configuration = builder.Build();
}
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string keyName = "TestApp:Settings:Message";
string message = Configuration[keyName];
return message != null
? (ActionResult)new OkObjectResult(message)
: new BadRequestObjectResult($"Please create a key-value with the key '{keyName}' in App Configuration.");
}
While using Azure functions, I have a situation where I want a few functions in "disabled" mode for a function app, while others to be enabled. The thing is, I don't want to do it manually using the functions screen where individual functions could be enabled/disabled easily. There is this article that says Functions 2.x supports this (Functions 1.x is not a choice for me).
https://learn.microsoft.com/en-us/azure/azure-functions/disable-function
It is just that the article is a little vague about what needs to be done. It says and I quote >
In Functions 2.x you disable a function by using an app setting. For example, to disable a function named QueueTrigger, you create an app setting named AzureWebJobs.QueueTrigger.Disabled, and set it to true. To enable the function, set the app setting to false.
I tried this, but it doesn't work as documented. I have a function app called foo and a function called bar. I have tried both:
disabled: true in function.json
as well as:
foo: {
bar: {
disabled: true
}
}
After making these changes and redeploying there is no effect on the UI. What am I missing?
The recommended approach is by using app settings, which you can do by going to the portal. [Note: They don't mean function.json when they say app settings.]
Option 1: Using App Settings
In azure portal, navigate to your function app foo -> Confuguration, and you should see Application Settings tab with a few variables already defined. You need to create a new variable by clicking New application setting button. Set name as AzureWebJobs.bar.Disabled and value as true. Note that the function app name foo doesn't figure in the variable name.
Option 2: Using host.json
Because you are looking for disabling a function from code, you can try doing this in host.json. Note that this is intended for local development, and not recommended for prod, but it works.
https://learn.microsoft.com/en-us/azure/azure-functions/functions-host-json#functions
{
"functions": [ "function1", "function2" ] // Don't list function "bar" here, and it would get disabled.
}
Note that the portal will not show this correctly, and list "bar" as enabled, but you will get 404 when hitting that function.
Option 3: Using Disable attribute
If you are using C# You can also use the [Disable] attribute. This is a Functions 1.x construct, but it works in 2.x as well. Similar to above, the portal UI will not show this correctly.
[Disable]
[FunctionName("Function1")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
}
Option 4: By removing FunctionName attribute
Only if you are using C#. This might sound counter-intuitive, but if you remove the FunctionName attribute from your function, it won't be treated as such.
// [FunctionName("Function1")] // Comment this or delete this line to disable this function
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
}
This should work in both runtimes. The function wouldn't show in the azure portal.
I used the [Disable("myAppSetting")], but it did not disable my function at first. Turns out the app settings from the App Config Azure resource do not have an impact on this behavior. It needs to be put directly in the app settings of the Azure Function itself for it to work. The Azure portal however does show correctly that the function is disabled.
I am playing around with Azure functions and trying to setup an intricate construct of pipes and filters (the pattern). I am using Azure functions for this.
My starting point is a HTTP triggered Azure function. That collects some JSON from the body of the request and should pass this message to a Azure Service Bus.
I must be missing something here (I have done this before in RabbitMQ with console apps) but how do I post a message to a service bus from a HTTP triggered Azure function.
I found several references talking about configuring my function.json (what ever that is - im building in Visual Studio).
How does this input/output (trigger/binding) thing work - im guessing that is the problem here...or??
I have my first Azure function in place and is receiving the data from the HTTP - so far so good. But how to proceed?
** Update **
Still cant get it to Work. Got this code and it fails with an http500. (it also says i need to see the og - where is that log?)
public static class EI_WooCommerce_Hub
{
[FunctionName("EI_WooCommerce_Hub")]
[return: ServiceBus("eilogging", Connection = "EIIntegrationServiceBusConnection")]
public async static Task<string> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "EIWooCommerceHub/name/")]HttpRequestMessage req, TraceWriter log)
{
log.Info("Webhook triggered from: ");
return "Hello World to queue";
}
}
** Update 2 **
This seems to be a config problem. In the application settings on the function app I kept getting an authorization error for the servicebus. I added the default "AzureWebJobsServiceBus" setting with the connectionstring, then it worked. It could not pick up my own connection string for some reason.
You should use Service Bus output binding. Since you mentioned Visual Studio, I assume C#. The simplest ever example looks like this:
[FunctionName("ServiceBusOutput")]
[return: ServiceBus("myqueue", Connection = "ServiceBusConnection")]
public static string ServiceBusOutput([HttpTrigger] dynamic input)
{
return input.Text;
}
Then add an application setting called ServiceBusConnection with the connection string to a namespace with queue myqueue (or rename in attribute constructor).
You can find more in Azure Service Bus bindings for Azure Functions - Output.
When you build in Visual Studio, then the function.json is created automatically. All you have to do is to define your triggers and output as attributes of the function parameters (see here: https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-service-bus#output)
A minimalistic example:
[FunctionName("HttpTriggerCSharp")]
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequestMessage req,
[ServiceBus("myqueue")] out string sbMessage,
TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
// parse query parameter
string name = req.GetQueryNameValuePairs()
.FirstOrDefault(q => string.Compare(q.Key, "name", true) == 0)
.Value;
sbMessage = name;
}
I have a series of Azure Functions, and I'd like to keep track of them by the InovcationId. In Application Insights, the InvocationId is called the operation_Id.
What I'm trying to do is set the operation_Id to be the same across several different Azure Functions.
I can read this property inside the Azure Function when I pass in ExecutionContext by following this answer, but I can't seem to alter it. Is there some way to change this value from inside the Azure Function?
public static class TestOperationId
{
[FunctionName("TestOperationId")]
public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequestMessage req,
ILogger log,
ExecutionContext exeCtx
)
{
var input = await req.Content.ReadAsStringAsync();
log.Info(input);
exeCtx.InvocationId = Guid.Parse(input);
return req.CreateResponse(HttpStatusCode.OK);
}
}
The definition for the InvocationId field is defined as
Provides the invocation ID, uniquely identifying the current invocation
Azure Functions doesn't provide changing this, as it would mean that code could override the platform's methods to detect unique invocations of Functions, which would interfere with things like Billing and Metrics for the platform.
It sounds like what you really want is cross-function correlation. There is work being done with the Application Insights team to help support this, but in the meantime, you can see solutions that others are currently utilizing, like here.