Skip to content

Commit e9512dd

Browse files
committed
Make event usage a distributed cron job
1 parent 61abb71 commit e9512dd

File tree

3 files changed

+22
-101
lines changed

3 files changed

+22
-101
lines changed

src/Exceptionless.Core/Bootstrapper.cs

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
using Exceptionless.Serializer;
2727
using FluentValidation;
2828
using Foundatio.Caching;
29+
using Foundatio.Extensions.Hosting.Cronos;
2930
using Foundatio.Extensions.Hosting.Jobs;
3031
using Foundatio.Extensions.Hosting.Startup;
3132
using Foundatio.Jobs;
@@ -252,22 +253,22 @@ private static async Task CreateSampleDataAsync(IServiceProvider container)
252253

253254
public static void AddHostedJobs(IServiceCollection services, ILoggerFactory loggerFactory)
254255
{
255-
services.AddJob<CloseInactiveSessionsJob>(o => o.WaitForStartupActions(true));
256-
services.AddJob<DailySummaryJob>(o => o.WaitForStartupActions(true));
257-
services.AddJob<EventNotificationsJob>(o => o.WaitForStartupActions(true));
258-
services.AddJob<EventPostsJob>(o => o.WaitForStartupActions(true));
259-
services.AddJob<EventUserDescriptionsJob>(o => o.WaitForStartupActions(true));
260-
services.AddJob<MailMessageJob>(o => o.WaitForStartupActions(true));
261-
services.AddJob<StackStatusJob>(o => o.WaitForStartupActions(true));
262-
services.AddJob<StackEventCountJob>(o => o.WaitForStartupActions(true));
263-
services.AddJob<WebHooksJob>(o => o.WaitForStartupActions(true));
264-
services.AddJob<WorkItemJob>(o => o.WaitForStartupActions(true));
265-
services.AddJob<EventUsageJob>(o => o.WaitForStartupActions(true));
266-
267-
services.AddCronJob<CleanupDataJob>("30 */4 * * *");
268-
services.AddCronJob<CleanupOrphanedDataJob>("45 */8 * * *");
269-
services.AddCronJob<DownloadGeoIPDatabaseJob>("0 1 * * *");
270-
services.AddCronJob<MaintainIndexesJob>("10 */2 * * *");
256+
services.AddJob<CloseInactiveSessionsJob>(o => o.WaitForStartupActions());
257+
services.AddJob<DailySummaryJob>(o => o.WaitForStartupActions());
258+
services.AddJob<EventNotificationsJob>(o => o.WaitForStartupActions());
259+
services.AddJob<EventPostsJob>(o => o.WaitForStartupActions());
260+
services.AddJob<EventUserDescriptionsJob>(o => o.WaitForStartupActions());
261+
services.AddJob<MailMessageJob>(o => o.WaitForStartupActions());
262+
services.AddJob<StackStatusJob>(o => o.WaitForStartupActions());
263+
services.AddJob<StackEventCountJob>(o => o.WaitForStartupActions());
264+
services.AddJob<WebHooksJob>(o => o.WaitForStartupActions());
265+
services.AddJob<WorkItemJob>(o => o.WaitForStartupActions());
266+
267+
services.AddDistributedCronJob<EventUsageJob>(Cron.Minutely());
268+
services.AddDistributedCronJob<CleanupDataJob>("30 */4 * * *");
269+
services.AddDistributedCronJob<CleanupOrphanedDataJob>("45 */8 * * *");
270+
services.AddDistributedCronJob<DownloadGeoIPDatabaseJob>(Cron.Daily(1));
271+
services.AddDistributedCronJob<MaintainIndexesJob>("10 */2 * * *");
271272

272273
var logger = loggerFactory.CreateLogger<Bootstrapper>();
273274
logger.LogWarning("Jobs running in process");

src/Exceptionless.Core/Services/UsageService.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ private async Task SavePendingOrganizationUsageAsync(DateTime utcNow)
5050
if (lastUsageSaveCache.HasValue)
5151
lastUsageSave = lastUsageSaveCache.Value.Add(_bucketSize);
5252

53+
_logger.LogInformation("Saving organization usage starting from: {LastUsageSave}...", lastUsageSave);
54+
5355
var bucketUtc = lastUsageSave;
5456
var currentBucketUtc = utcNow.Floor(_bucketSize);
5557

@@ -127,6 +129,8 @@ private async Task SavePendingProjectUsageAsync(DateTime utcNow)
127129
if (lastUsageSaveCache.HasValue)
128130
lastUsageSave = lastUsageSaveCache.Value.Add(_bucketSize);
129131

132+
_logger.LogInformation("Saving project usage starting from: {LastUsageSave}...", lastUsageSave);
133+
130134
var bucketUtc = lastUsageSave;
131135
var currentBucketUtc = utcNow.Floor(_bucketSize);
132136

src/Exceptionless.Web/ApmExtensions.cs

Lines changed: 1 addition & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,7 @@ public static IHostBuilder AddApm(this IHostBuilder builder, ApmConfig config)
8484
b.AddConsoleExporter();
8585

8686
if (config.EnableExporter)
87-
b.AddFilteredOtlpExporter(c =>
88-
{
89-
c.Filter = a => a.Duration > TimeSpan.FromMilliseconds(config.MinDurationMs) || a.GetTagItem("db.system") is not null;
90-
});
87+
b.AddOtlpExporter();
9188
});
9289

9390
services.AddOpenTelemetry().WithMetrics(b =>
@@ -177,84 +174,3 @@ public ApmConfig(IConfigurationRoot config, string processName, string? serviceV
177174
public bool Debug => _apmConfig.GetValue("Debug", false);
178175
public bool Console => _apmConfig.GetValue("Console", false);
179176
}
180-
181-
public sealed class CustomFilterProcessor : CompositeProcessor<Activity>
182-
{
183-
private readonly Func<Activity, bool>? _filter;
184-
185-
public CustomFilterProcessor(BaseProcessor<Activity> processor, Func<Activity, bool>? filter) : base(new[] { processor })
186-
{
187-
_filter = filter;
188-
}
189-
190-
public override void OnEnd(Activity activity)
191-
{
192-
if (_filter is null || _filter(activity))
193-
base.OnEnd(activity);
194-
}
195-
}
196-
197-
public static class CustomFilterProcessorExtensions
198-
{
199-
public static TracerProviderBuilder AddFilteredOtlpExporter(this TracerProviderBuilder builder, Action<FilteredOtlpExporterOptions>? configure = null)
200-
{
201-
ArgumentNullException.ThrowIfNull(builder);
202-
203-
if (builder is IDeferredTracerProviderBuilder deferredTracerProviderBuilder)
204-
{
205-
return deferredTracerProviderBuilder.Configure((sp, providerBuilder) =>
206-
{
207-
var oltpOptions = sp.GetService<IOptions<FilteredOtlpExporterOptions>>()?.Value ?? new FilteredOtlpExporterOptions();
208-
AddFilteredOtlpExporter(providerBuilder, oltpOptions, configure, sp);
209-
});
210-
}
211-
212-
return AddFilteredOtlpExporter(builder, new FilteredOtlpExporterOptions(), configure, serviceProvider: null);
213-
}
214-
215-
internal static TracerProviderBuilder AddFilteredOtlpExporter(
216-
TracerProviderBuilder builder,
217-
FilteredOtlpExporterOptions exporterOptions,
218-
Action<FilteredOtlpExporterOptions>? configure,
219-
IServiceProvider? serviceProvider,
220-
Func<BaseExporter<Activity>, BaseExporter<Activity>>? configureExporterInstance = null)
221-
{
222-
223-
configure?.Invoke(exporterOptions);
224-
225-
exporterOptions.TryEnableIHttpClientFactoryIntegration(serviceProvider, "OtlpTraceExporter");
226-
227-
BaseExporter<Activity> otlpExporter = new OtlpTraceExporter(exporterOptions);
228-
229-
if (configureExporterInstance is not null)
230-
otlpExporter = configureExporterInstance(otlpExporter);
231-
232-
if (exporterOptions.ExportProcessorType == ExportProcessorType.Simple)
233-
{
234-
return builder.AddProcessor(new CustomFilterProcessor(new SimpleActivityExportProcessor(otlpExporter), exporterOptions.Filter));
235-
}
236-
237-
var batchOptions = exporterOptions.BatchExportProcessorOptions ?? new();
238-
return builder.AddProcessor(new CustomFilterProcessor(new BatchActivityExportProcessor(
239-
otlpExporter,
240-
batchOptions.MaxQueueSize,
241-
batchOptions.ScheduledDelayMilliseconds,
242-
batchOptions.ExporterTimeoutMilliseconds,
243-
batchOptions.MaxExportBatchSize), exporterOptions.Filter));
244-
}
245-
246-
public static void TryEnableIHttpClientFactoryIntegration(this OtlpExporterOptions options, IServiceProvider? serviceProvider, string httpClientName)
247-
{
248-
// use reflection to call the method
249-
var exporterExtensionsType = typeof(OtlpExporterOptions).Assembly.GetType("OpenTelemetry.Exporter.OtlpExporterOptionsExtensions");
250-
exporterExtensionsType?.GetMethod("TryEnableIHttpClientFactoryIntegration")?.Invoke(null, [options,
251-
serviceProvider!,
252-
httpClientName
253-
]);
254-
}
255-
}
256-
257-
public class FilteredOtlpExporterOptions : OtlpExporterOptions
258-
{
259-
public Func<Activity, bool>? Filter { get; set; }
260-
}

0 commit comments

Comments
 (0)