I have a very simple function and boiled it down further more to trouble shoot this issue, I read some previous questions on SO about similar issues but they dont apply to my issue I believe.
Function code
[FunctionName("XXXItems")]
public static async System.Threading.Tasks.Task RunAsync([TimerTrigger("0 45 6 * * 1-5")]TimerInfo myTimer, ILogger log)
{
log.LogInformation($"XXXItems --> Timer trigger function executed at: {DateTime.Now}");
}
I have configure the APPINSIGHTS_INSTRUMENTATIONKEY in the function settings
But nothing gets logged and I am a bit lost as how to debug this
Related
I have a console application which I want to convert to an Azure Function Timer Trigger app which will run every hour after some data processing and uploads are done. The data processing and uploads are being done via classes which are injected in the program.cs file of the console application. Somewhere in the classes I have a task.delay by 1hour where it will query new data after the data has been queried and uploaded for the first time. So, I copied the entire code of the console application with its packages to the Azure Function Timer trigger app. What I am trying to do is to run the program.cs file of the console application first in the azure function app in order to do its job (data processing, querying data, uploading data to azure...). and then initiate the timer trigger. Is that doable ? What line of code can I add in the run method of the azure function app to execute the program.cs file first and then initiate the trigger. You can find here the startup code of the azure function time trigger app.
using System;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
namespace ExportServiceFunctionApp
{
public static class ExportServiceFunctionApp
{
[FunctionName("ExportServiceFunctionApp")]
public static void Run([TimerTrigger("0 0 */1 * * * ")]TimerInfo myTimer, ILogger log)
{
log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
}
}
}
There are a few solutions to achieve this.
Solution 1. Temporarily replace the timer trigger with http trigger
While debugging the app we just comment the first line of the original Run function and add an http trigger instead like this:
public static async Task Run([HttpTrigger] Microsoft.AspNetCore.Http.HttpRequest req, ILogger log)
// public static async Task Run([TimerTrigger("0 0 * * * *")] TimerInfo myTimer, ILogger log)
{
// YOUR REGULAR CODE HERE
}
Then when running the app you'll see an endpoint like this:
Just open the endpoint in browser (or postman) and the function will get called.
And right before pushing the code to the repo, just bring back the original Run function and remove the http trigger one.
Solution 2: Add another http trigger that calls the timer function
Add the following function to your app to expose an http trigger.
[FunctionName("Test")]
public static async Task Test([HttpTrigger] Microsoft.AspNetCore.Http.HttpRequest req, ILogger log)
{
Run(null, log);
}
The function basically calls the Run function.
So when you run the app, again you'll get an endpoint from the console that can be used from the browser to trigger the function.
The url will look like this:
http://localhost:7071/api/Test
Azure functions is event driven in nature. If function trigger means the event handled.
Run method of function means that function has triggered and its entry point for it.
If you want any processing or code execution before it you may need to write one more function and perform the steps and then trigger another function of either timer trigger or ant different type.
Is there now a way to set the Trigger Properties(Name/Connection) using the value from Azure App Configuration?.
I added a startup class that reads the data from Azure App Configuration but it seems the trigger set its properties earlier than that, therefore not able to bind the data that came from the app configuration.
I also found this thread about it but im not sure if there is a new update?:
https://github.com/MicrosoftDocs/azure-docs/issues/63419
https://github.com/Azure/AppConfiguration/issues/203
You can do this. The following code gets the name of the queue to monitor from an app setting, and it gets the queue message creation time in the insertionTime parameter:
public static class BindingExpressionsExample
{
[FunctionName("LogQueueMessage")]
public static void Run(
[QueueTrigger("%queueappsetting%")] string myQueueItem,
DateTimeOffset insertionTime,
ILogger log)
{
log.LogInformation($"Message content: {myQueueItem}");
log.LogInformation($"Created at: {insertionTime}");
}
}
Similarly, you can use this approach for other triggers.
Currently I can retrieve ExecutionContext inside the function method, like this:
public async Task <IActionResult> Run ([HttpTrigger (AuthorizationLevel.Anonymous, "post", Route = null)], ILogger log, ExecutionContext context)
Is there any way I can retrieve ExecutionContext from my function startup?
I am sorry that you will not be able to get the ExecutionContext in startup. Because the ExecutionContext enables interaction with the Azure Functions execution environment when a function call is made.
However, in your function startup, your Azure Function is not yet processing an actual function call.
I have an Azure Function written in C# and deployed as pre-compiled using Zip deploy directly from Visual Studio. Although on local everything works the function throws an error upon starting
Function (RunStatsRecalculation) Error: Microsoft.Azure.WebJobs.Host: Error indexing method 'RunStatsRecalculation'. Microsoft.Azure.WebJobs.Host: '%TimerInterval%' does not resolve to a value.
The CRON expression for timer setting is stored in the settings under key TimerInterval with value "0 0 0 * * *"
The function is defined as follows
[FunctionName("RunStatsRecalculation")]
public static async Task Run(
[TimerTrigger("%TimerInterval%")]TimerInfo myTimer,
ILogger logger,
ExecutionContext context,
CancellationToken ct)
{
Any idea what could be wrong?
I can repro your issue. To resolve the issue, please add the key(TimerInterval) and value(0 0 0 * * *) to azure function application settings.
Here is my code:
[FunctionName("Function1")]
public static void Run([TimerTrigger("%TimerSchedule%")]TimerInfo myTimer, ILogger log)
{
log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
log.LogInformation($"this is a test for timer trigger...");
}
And application settings:
I am working on Azure functions timer Job , i need to get the cron expression from the appsettings. Please let me know, how can i get the value from the appsettings in the Azure functions. I want to run my azure function starting from 9:00 AM to 12:00 PM for every 30 minutes\
{
"disabled": false,
"bindings": [
{
"name": "timerInfo",
"type": "timerTrigger",
"direction": "in",
"schedule": "0 * * * * *"
}
]
}
Set your schedule as "schedule": "%EmailScheduleTriggerTime%" and then in the appsetting.json or local.settings.json you can set EmailScheduleTriggerTime value as "0 30 9-12 * * *"
{
"IsEncrypted": false,
"Values": {
"EmailScheduleTriggerTime": "0 30 9-12 * * *", //Run every 30 minutes from 9:00 to 12:00
},
"ConnectionStrings": {
"DefaultConnection": ""
}
}
[FunctionName("TimerfunctionApp")]
public static void Run([TimerTrigger("%EmailScheduleTriggerTime%")] TimerInfo TInfo, TraceWriter log)
If you are using the VS2017 Functions tooling and defining your function in a .NET project (rather than directly in the Azure portal) you can pick up the interval from AppSettings using the % syntax:
[FunctionName("MyTimerFunction")]
public static void Run([TimerTrigger("%TimerInterval%")] TimerInfo myTimer, TraceWriter log, ..
Then in your app settings specify the required CRON format interval eg. in local.settings.json
{
"Values" : {
"TimerInterval" : "0 30 9-12 * * *"
}
}
To add to the previous answers, you can get any value form any field in a config file (appsettings.json) file using % syntax - not only from Values configuration object.
For example:
appsettings.json:
{
"ScheduleConfiguration": {
"FunctionOne": {
"CronExpression": "0 40 2 * * *"
}
}
}
Functions.cs:
/// <summary>
/// %ScheduleConfiguration:FunctionOne:CronExpression%
/// - e.g. "0 40 2 * * *" - executes at 02:40:00am every day
/// </summary>
[FunctionName("FunctionOne")]
public async Task FunctionOne(
[TimerTrigger("%ScheduleConfiguration:FunctionOne:CronExpression%")]
TimerInfo timerInfo)
{
// Azure function code
}
Since this post already has good answers, I want to share my experience here. I was trying to run the app locally by adding the cron expression in the appsettings.json file but then when I ran the function app I always received an error as follows
The 'EmployeeTimerTrigger' function is in error:
Microsoft.Azure.WebJobs.Host: Error indexing method
'EmployeeTimerTrigger'. Microsoft.Azure.WebJobs.Host:
'%EmployeeTimerTrigger%' does not resolve to a value.
So in order to resolve that what we need to do is shift the cron expression from appsettings.json to local.settings.json and it worked just fine and I was able to test it locally.
Edit: Adding notes for deployment
The function app reads the timer trigger settings from the application settings of the function app itself on azure.
When you plan to deploy your function app in azure there's a small change that you need to do in the Application Settings of the function app in the Azure portal.
You can navigate to those settings by selecting the function app in azure portal -> Configuration -> Application setting
The very first setting that you need to add is the time zone in which you want the timer trigger to run here's an example of the same
Note: Please note these values are case sensitive
Now the second setting we will add here is for our timer trigger function, in this image you will see that the timer will run at 10:00 AM and 2:00 PM eastern standard time.
Why eastern standard time you ask? well, remember our first settings were for the website time zone so both settings work hand in hand.
Note: The name of the timer trigger should match the one you have in your function app, please note these values are case sensitive and should match exactly with what you have in your timer trigger function.
Once you have added these settings, don't forget to save your changes and now you are all set to deploy your function app.
I hope this answer helps in the deployment and running the timer function locally.
As mentioned earlier (for Node js) we can use %scheduleValue% in function.json and use scheduleValue as parameter in local.settings.json
and here its mentioned in Microsoft docs - https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-timer?tabs=javascript#configuration
Refer the below Microsoft doc
Timer trigger for Azure Functions
Sample Json Config :
{
"schedule": "0 */5 * * * *",
"name": "myTimer",
"type": "timerTrigger",
"direction": "in"
}
C# code :
public static void Run(TimerInfo myTimer, ILogger log)
{
if (myTimer.IsPastDue)
{
log.LogInformation("Timer is running late!");
}
log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}" );
}
Source of code : Microsoft website