I am trying to create a very simple TimerTriggered function to prevent my app from getting cold.
The issue is that after deploying the app or after restarting it the TimerTriggered function is never executed. After invoking the function manually the timer starts running as expected.
Some info that might be useful:
My app has a mix of different triggers.
The runtime version used is 2.0.11651.0.
The app service plan has a consumption plan and has to stay that way.
In this case I deploy using Visual Studio
My class looks like the following:
public static class KeepAliveTask
{
[FunctionName("KeepAlive")]
public static void Run([TimerTrigger("0 */4 * * * *", RunOnStartup = true)]TimerInfo timer, TraceWriter log)
{
log.Info("Keeping service alive");
}
}
That's all there is to it. I've been searching but has been unable to find anyone with the same problem. Any suggestions is appreciated.
Related
Azure Timer trigger is not working in .net 5 isolated function app with the CRON expression to get triggered for every minute.
This is working fine if we run that in local visual studio.
public static class NotificationScheduler
{
[Function("NotificationScheduler")]
public static void Run([TimerTrigger("1-2 * * * * *")] MyInfo myTimer, FunctionContext context)
{
var logger = context.GetLogger("NotificationScheduler");
logger.LogInformation($"Notification Scheduler trigger function executed at: {DateTime.Now}");
//logger.LogInformation($"Next timer schedule at: {myTimer.ScheduleStatus.Next}");
}
}
As per your ask I have run the function in my local environment and it is working fine for me below is my code for reference make changes accordingly on your environment.
Created Function App in Azure Portal
2. Below is the Code which I have Used in function App
Function1.cs
using System;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
namespace KrishFuncTimerTriggerApp
{
public static class Function1
{
[FunctionName("Function1")]
public static void Run([TimerTrigger("0 * * * * *")]TimerInfo myTimer, TraceWriter log)
{
log.Info($"C# Timer trigger function executed at: {DateTime.Now}");
}
}
Then I went to Code+Integration and when I did a Test Run my function app ran every minute as per my logic
As per the below Image .Net isolated function is not supported for editing in Azure Portal.
Also, try to check your SDK version as per this SO and blog if you are using SDK version "6.0.100-preview.7.21379.14" as it is in Preview could be the reason why your function app is not working, if that is the case then try to downgrade your function app.
Also Check the Cron expression link for further details
I'm testing my Azure Functions and facing a funny problem. I want to see if a function was running and the result. I'm opening the function and then my function called getTokenRefresh. Apparently, this function has never started.
After a couple of hours, I decided to open Application Insights. Surprise! All logs are there.
If I run a function from the portal and open again monitor and click on the Logs tab, I don't see any logs. Again I can find everything only in Application Insights.
Another interesting thing is other functions in this Azure Functions, show me all details (believe me is the same function).
In the code point of view, I'm using dependency injection in all functions like:
public class GetTokenRefreshTimer
{
private ILogger _log;
public GetTokenRefreshTimer(ILogger<GetTokenRefreshTimer> log)
{
_log = log;
}
[FunctionName("getTokenRefreshTimer")]
public async Task Run([TimerTrigger("0 */20 * * * *")]TimerInfo myTimer)
{
_log.LogInformation("GetTokenRefresh starts");
}
}
The logs of azure function is fragile. So sometimes you can not see the logs, but this doesn't mean the azure function is not run.
If you want to know the function is running you need to go to the kudu of your azure function and see the logs file of your function app.(The logs in Application Insights is coming from this place.)
The logs file is in the place:
Open your brower and go to https://yourfunctionappname.scm.azurewebsites.net/DebugConsole, and then click into LogFiles/Application/Functions/Function/yourtriggername . You will find the log file in this place.
I have a web job that needs to run every day at 1am.
My settings.job is configured like this:
{
"schedule": "0 0 1 * * *",
"is_singleton": true
}
I have function declared in the Functions.cs
namespace Dsc.Dmp.SddUpgrade.WebJob
{
using System;
using System.IO;
using Microsoft.Azure.WebJobs;
public class Functions
{
public static void TriggerProcess(TextWriter log)
{
log.Write($"C# Timer trigger function executed at: {DateTime.Now}");
}
}
}
I am getting the following logs:
[09/28/2017 12:02:05 > 9957a4: SYS INFO] Status changed to Running
[09/28/2017 12:02:07 > 9957a4: INFO] No job functions found. Try making your job classes and methods public. 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.).
As I read the documentation, some people are using a function signature like this:
public static void TriggerProcess([TimerTrigger("0 0 1 * * *")] TimerInfo timerInfo, TextWriter log)
However, this does not seem logic to me, because a have already configured my web job to by scheduled in the settings.job.
What am I missing here?
If you use a settings.job file to schedule your WebJob, your logic should go in the Program.cs's Main function. You can ignore the Functions.cs file if you go this route. This is great for migrating a console app into a WebJob and scheduling it.
The TimerTrigger is a WebJob extension. It's useful because it's possible to have multiple methods in Functions.cs, each with a separate TimerTrigger that executes on a different schedule. To use these, your WebJob needs to be continuous.
You need to put your logic in Program.cs.
The runtime will run your WebJob by executing the executable, running the Main method in Program.cs.
You seem to be missing the [FunctionName("TriggerProcess")] attribute in the function definition, that´s why you´re getting the "job not found" error.
Say I have a timetriggered function that should only run in production, or maybe have different schedule in production, how can I do that?
When using CI the the app goes into read-only mode, and timetrigger interval is not configurable.
There's a few options but I'd suggest you define your TimerTrigger to pick up it's schedule from the App Settings of the function app - where you can populate this via your CI process, or manually if need be.
Defining your function in C# in the VS 2017 tooling you need a method signature like this e.g.
[FunctionName("MyTimerFunction")]
public static void Run([TimerTrigger("%TriggerInterval%")] TimerInfo myTimer, TraceWriter log)
And in the function app settings (or local.settings.json to run locally) define the CRON interval for the timer.
{
"Values" : {
"TriggerInterval": "0 0 * * * *" // e.g. hourly
}
}
Additionally, if you need a quick fix, even if your CI process has set the app the read-only mode, you can still set it to read/write and then update the settings - of course that will be overridden the next time the CI deploys to that function app.
My Azure WebJob used to run in the VS2015 Debugger, but I found it gradually became very intermittent and now won't run at all. It works fine it I deploy it to Azure. The job is marked as RunOnStartUp.
public class Program
{
static void Main()
{
var config = new JobHostConfiguration();
config.UseTimers();
var host = new JobHost(config);
host.RunAndBlock();
}
}
public class TestJob : BaseJob
{
public static async Task StartupJob([TimerTrigger("05:00:00", RunOnStartup = true)] TimerInfo timerInfo, TextWriter log)
{
log.WriteLine("StartupJob");
await Jobs.Test(some params);
log.WriteLine("Sorted");
}
}
What do I need to do to get it running in the Debugger?
I'm guessing you use the same storage account for your job in Azure and when you debug it locally? If that's the case - the TimeTrigger runs as a singleton which means it needs to acquire a lock to be able to execute. If your webjob is already running in Azure your local version, which you're trying to debug, is not able to acquire the lock.
To avoid this just use different storage accounts for "live" Azure version and local local development.
I would also recommend to enable "development settings" - config.UseDevelopmentSettings(); - when you debug locally. If you enable it you'll see the messages "unable to acquire lock for function..." (or something similar).
See Jason Haley's comment in this thread:
(total hack but should work) rename the function while debugging so
the lock listener blob name will be different.
This hack worked for me. Maybe to make it less hacky, you could use the Disable-attribute to create a timer-triggered function that would only be enabled in your local environment:
Create "MyFunction", which handles the logic. This is the one that will run in your Azure app. Note RunOnStartup=false as recommended by the docs.
[FunctionName("MyFunction")]
public async Task RunJob(
[TimerTrigger("0 0 0 * * *", RunOnStartup = false)] TimerInfo timer)
{
//logic here
}
Create "MyFunction-Local" with the Disable attribute and a different method name. All this does is call the method above.
[FunctionName("MyFunction-Local")]
[Disable("Disable_MyFunction")]
public async Task RunJobLocal(
[TimerTrigger("0 0 0 * * *", RunOnStartup = true)] TimerInfo timer)
{
RunJob(timer);
}
In your local app configuration, set {"Disable_MyFunction" = false}, whereas for the app running in Azure, set this to true.