Ведение журнала выполнения Hangfire RecurringJob в базе данных? - PullRequest
1 голос
/ 16 января 2020

Я успешно настроил hangfire для моего проекта ASP. NET, т.е. в моей базе данных создано 11 таблиц Hangfire. Я попробовал следующую команду внутри Application_Start() моего проекта Global.asax:

namespace myAPI
{
   public class WebApiApplication : System.Web.HttpApplication
   {
      protected void Application_Start(
      {
         System.Diagnostics.Debug.WriteLine("Recurring job will be set up.");

         RecurringJob.AddOrUpdate(
             "some-id", 
             () => System.Diagnostics.Debug.WriteLine("Job instance started at " +
                                                      DateTime.Now)),
             "*/2 * * * 1-5"); 
      }
   }
}

К сожалению, внутри окна Visual Studio Вывод> Отладка Я вижу только Reccuring job will be set up. и ничего никогда после. Тем не менее, SELECT * FROM [myContext].[HangFire].[Set] показывает мне

Key              Score      Value     ExpireAt
recurring-jobs  1579116240  some-id   NULL

Пока все хорошо, это означает, что задание действительно настроено.

Но как мне войти внутри мой DB каждый раз, когда выполняется RecurringJob? Правильно ли я предполагаю, что Hangfire не делает этого «из коробки», и я должен сам регистрировать его в функции стрелки? Или есть более элегантный способ?

Вопрос на стороне: Почему я не вижу вывод System.Diagnostics.Debug.WriteLine в моей повторяющейся работе?

Ссылки

Ответы [ 4 ]

2 голосов
/ 22 января 2020

Hangfire включает в себя концепцию фильтров работы (аналогично ASP. NET MVC Action Filters). Для вашего случая использования вы должны определить тот, который будет записываться в вашу базу данных (настроить в соответствии с вашими потребностями):

using Hangfire.Common;
using Hangfire.Server;

class LogCompletionAttribute : JobFilterAttribute, IServerFilter
{
    public void OnPerforming(PerformingContext filterContext)
    {
        // Code here if you care when the execution **has begun**
    }

    public void OnPerformed(PerformedContext context)
    {
        // Check that the job completed successfully
        if (!context.Canceled && context.Exception != null)
        {
            // Here you would write to your database.
            // Example with entity framework:
            using (var ctx = new YourDatabaseContext())
            {
                ctx.Something.Add(/**/);
                ctx.SaveChanges();
            }
        }
    }
}

, а затем применить фильтр к методу задания:

namespace myAPI
{
   public class WebApiApplication : System.Web.HttpApplication
   {
      protected void Application_Start(
      {
         System.Diagnostics.Debug.WriteLine("Recurring job will be set up.");

         RecurringJob.AddOrUpdate("some-id", () => MyJob(), "*/2 * * * 1-5"); 
      }

      [LogCompletion]
      public static void MyJob()
      {
          System.Diagnostics.Debug.WriteLine("Job instance started at " + DateTime.Now)
      }
   }
}

Документы: https://docs.hangfire.io/en/latest/extensibility/using-job-filters.html

1 голос
/ 21 января 2020

Вы можете использовать SeriLog с Hangfire из коробки. Serilog поставляется с различными мойками, например Serilog.Sinks.MSSqlServer. Вы можете настроить его в startup.cs:

using Serilog;
using Serilog.Sinks.MSSqlServer;

Log.Logger = new LoggerConfiguration()
                 .WriteTo
                 .MSSqlServer(
                        connectionString: hangfireConnectionString,
                        tableName: "Logs",
                        autoCreateSqlTable: true
                    ).CreateLogger();
               // will display any issues with Serilog config. comment out in prod.
Serilog.Debugging.SelfLog.Enable(msg => Debug.WriteLine(msg));

GlobalConfiguration.Configuration
                   .UseSqlServerStorage(hangfireConnectionString)
                   .UseSerilogLogProvider();

После того, как вы запланировали свою работу, вы можете войти в нее с помощью

Log.Information(string.Format("Hanfire Job Scheduled at {0}", DateTime.Now));
1 голос
/ 16 января 2020

Таким образом, хрон запускается Каждую 2-ю минуту каждого дня недели с понедельника по пятницу . Я предполагаю, что вы ожидаете выполнения задания и оно находится в нужном окне времени.

Большинство ссылок, которые я нашел в Интернете, указали, что вы можете выполнить.

RecurringJob.AddOrUpdate(() => Console.WriteLine("This job will execute once in every minute"), Cron.Minutely);

Может быть, вам нужно расположить точки немного лучше, чтобы записать их в консоль vs.

Существует также административный портал, который можно настроить для просмотра того, что начинается и когда запускается.

У меня есть следующие настройки. Global.asax.cs

    protected void Application_Start()
    {
        HangfireJobsConfig.Register();
    }
    public class HangfireJobsConfig
    {
        public static void Register()
        {
            if (App1Config.RunHangfireService)
            {
                JobStorage.Current = new SqlServerStorage(App1Config.DefaultConnectionStringName.Split('=').Last());
                GlobalConfiguration.Configuration.UseConsole();
                RecurringJob.AddOrUpdate("RunJob1", () => RunJob1(null), Cron.MinuteInterval(App1Config.RunJob1Interval));
                RecurringJob.AddOrUpdate("RunJob2", () => RunJob2(null), Cron.MinuteInterval(App1Config.RunJob2Interval));
            }
        }

        [AutomaticRetry(Attempts = 0, Order = 1)]
        public static void RunJob1(PerformContext context)
        {
            //dostuff
        }

        [AutomaticRetry(Attempts = 0, Order = 2)]
        public static void RunJob2(PerformContext context)
        {
            //do stuff
        }
    }

Startup.cs

    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
            ConfigureHangFire(app);
        }
        public void ConfigureHangFire(IAppBuilder app)
        {
            if (App1Config.RunHangfireService)
            {
                GlobalConfiguration.Configuration.UseSqlServerStorage(
                    AppiConfig.DefaultConnectionStringName.Split('=').Last());

                GlobalConfiguration.Configuration.UseConsole();

                app.UseHangfireServer();
                var options = new DashboardOptions
                {
                    AuthorizationFilters = new[]
                    {
                        new AuthorizationFilter { Roles = "Inventory" }         
                    }
                };
                app.UseHangfireDashboard("/hangfire", options);
            }
        }
    }
0 голосов
/ 27 января 2020

Фактическая проблема была очень тривиальной, инициализация фактического фонового сервера отсутствовала BackgroundJobServer();. Здесь полнофункциональный код:

namespace myAPI 
{
  public class WebApiApplication : System.Web.HttpApplication
  {
    protected void Application_Start()
    {
       string connString = ConfigurationManager.ConnectionStrings["myContext"].ToString();
       Hangfire.GlobalConfiguration.Configuration.UseConsole();
       Hangfire.GlobalConfiguration.Configuration.UseSqlServerStorage(connString,
       new SqlServerStorageOptions {
             CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
             SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
             QueuePollInterval = TimeSpan.Zero,
             UseRecommendedIsolationLevel = true,
             UsePageLocksOnDequeue = true,
             DisableGlobalLocks = true
           });
        var bgndJS = new BackgroundJobServer(); // <--- this is essential!
        RecurringJob.AddOrUpdate("myRecurringJob", () => HangfireRecurringJob(), "*/2 * * * 1-5");
        System.Diagnostics.Debug.WriteLine("---> RecurringJob 'myHangfireJob' initated.");
    }

    public void HangfireRecurringJob() {
       System.Diagnostics.Debug.WriteLine("---> HangfireRecurringJob() executed at" + DateTime.Now);
       Console.Beep(); // <-- I was really happy to hear the beep
    }
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...