TaskCompletedLogger.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using Jellyfin.Data.Entities;
  7. using MediaBrowser.Controller.Events;
  8. using MediaBrowser.Model.Activity;
  9. using MediaBrowser.Model.Globalization;
  10. using MediaBrowser.Model.Notifications;
  11. using MediaBrowser.Model.Tasks;
  12. using Microsoft.Extensions.Logging;
  13. namespace Jellyfin.Server.Implementations.Events.Consumers
  14. {
  15. /// <summary>
  16. /// Creates an activity log entry whenever a task is completed.
  17. /// </summary>
  18. public class TaskCompletedLogger : IEventConsumer<TaskCompletionEventArgs>
  19. {
  20. private readonly ILocalizationManager _localizationManager;
  21. private readonly IActivityManager _activityManager;
  22. public TaskCompletedLogger(ILocalizationManager localizationManager, IActivityManager activityManager)
  23. {
  24. _localizationManager = localizationManager;
  25. _activityManager = activityManager;
  26. }
  27. public async Task OnEvent(TaskCompletionEventArgs e)
  28. {
  29. var result = e.Result;
  30. var task = e.Task;
  31. if (task.ScheduledTask is IConfigurableScheduledTask activityTask
  32. && !activityTask.IsLogged)
  33. {
  34. return;
  35. }
  36. var time = result.EndTimeUtc - result.StartTimeUtc;
  37. var runningTime = string.Format(
  38. CultureInfo.InvariantCulture,
  39. _localizationManager.GetLocalizedString("LabelRunningTimeValue"),
  40. ToUserFriendlyString(time));
  41. if (result.Status == TaskCompletionStatus.Failed)
  42. {
  43. var vals = new List<string>();
  44. if (!string.IsNullOrEmpty(e.Result.ErrorMessage))
  45. {
  46. vals.Add(e.Result.ErrorMessage);
  47. }
  48. if (!string.IsNullOrEmpty(e.Result.LongErrorMessage))
  49. {
  50. vals.Add(e.Result.LongErrorMessage);
  51. }
  52. await _activityManager.CreateAsync(new ActivityLog(
  53. string.Format(CultureInfo.InvariantCulture, _localizationManager.GetLocalizedString("ScheduledTaskFailedWithName"), task.Name),
  54. NotificationType.TaskFailed.ToString(),
  55. Guid.Empty)
  56. {
  57. LogSeverity = LogLevel.Error,
  58. Overview = string.Join(Environment.NewLine, vals),
  59. ShortOverview = runningTime
  60. }).ConfigureAwait(false);
  61. }
  62. }
  63. private static string ToUserFriendlyString(TimeSpan span)
  64. {
  65. const int DaysInYear = 365;
  66. const int DaysInMonth = 30;
  67. // Get each non-zero value from TimeSpan component
  68. var values = new List<string>();
  69. // Number of years
  70. int days = span.Days;
  71. if (days >= DaysInYear)
  72. {
  73. int years = days / DaysInYear;
  74. values.Add(CreateValueString(years, "year"));
  75. days %= DaysInYear;
  76. }
  77. // Number of months
  78. if (days >= DaysInMonth)
  79. {
  80. int months = days / DaysInMonth;
  81. values.Add(CreateValueString(months, "month"));
  82. days = days % DaysInMonth;
  83. }
  84. // Number of days
  85. if (days >= 1)
  86. {
  87. values.Add(CreateValueString(days, "day"));
  88. }
  89. // Number of hours
  90. if (span.Hours >= 1)
  91. {
  92. values.Add(CreateValueString(span.Hours, "hour"));
  93. }
  94. // Number of minutes
  95. if (span.Minutes >= 1)
  96. {
  97. values.Add(CreateValueString(span.Minutes, "minute"));
  98. }
  99. // Number of seconds (include when 0 if no other components included)
  100. if (span.Seconds >= 1 || values.Count == 0)
  101. {
  102. values.Add(CreateValueString(span.Seconds, "second"));
  103. }
  104. // Combine values into string
  105. var builder = new StringBuilder();
  106. for (int i = 0; i < values.Count; i++)
  107. {
  108. if (builder.Length > 0)
  109. {
  110. builder.Append(i == values.Count - 1 ? " and " : ", ");
  111. }
  112. builder.Append(values[i]);
  113. }
  114. // Return result
  115. return builder.ToString();
  116. }
  117. /// <summary>
  118. /// Constructs a string description of a time-span value.
  119. /// </summary>
  120. /// <param name="value">The value of this item.</param>
  121. /// <param name="description">The name of this item (singular form).</param>
  122. private static string CreateValueString(int value, string description)
  123. {
  124. return string.Format(
  125. CultureInfo.InvariantCulture,
  126. "{0:#,##0} {1}",
  127. value,
  128. value == 1 ? description : string.Format(CultureInfo.InvariantCulture, "{0}s", description));
  129. }
  130. }
  131. }