簡體   English   中英

在數據庫中記錄 Hangfire RecurringJob 的執行情況?

[英]Logging the execution of a Hangfire RecurringJob in database?

我已經建立了遲發型我的ASP.NET項目,即11代遲發型表在我的數據庫中創建成功。 我在項目的Global.asaxApplication_Start()中嘗試了以下命令:

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

到目前為止一切順利,這意味着該工作確實已建立。

但是,如何每次執行 RecurringJob 時登錄我的數據庫 我是否正確地假設 Hangfire 沒有開箱即用,我必須自己在箭頭函數中記錄它? 或者有更優雅的方式嗎?

附帶問題:為什么我的重復作業中看不到System.Diagnostics.Debug.WriteLine任何輸出?

參考

Hangfire 包含一個作業過濾器的概念(類似於 ASP.NET MVC 的操作過濾器)。 對於您的用例,您將定義一個將寫入您的數據庫(根據您的需要進行調整):

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

您可以開箱即用地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));

因此, cron 設置為在從 Monday 到 Friday 的每一天的每 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
        }
    }

啟動文件

    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);
            }
        }
    }

實際問題是一個非常微不足道的問題,實際后台服務器的初始化缺少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
    }
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM