diff --git a/Foundatio.sln b/Foundatio.sln
index 322e7430..25fd365e 100644
--- a/Foundatio.sln
+++ b/Foundatio.sln
@@ -12,7 +12,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
build\common.props = build\common.props
tests\Directory.Build.props = tests\Directory.Build.props
src\Directory.Build.props = src\Directory.Build.props
- samples\Directory.Build.props = samples\Directory.Build.props
NuGet.config = NuGet.config
README.md = README.md
.github\workflows\build-workflow.yml = .github\workflows\build-workflow.yml
@@ -40,6 +39,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Foundatio.MessagePack", "sr
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Foundatio.DataProtection", "src\Foundatio.DataProtection\Foundatio.DataProtection.csproj", "{BD5CB540-DFF1-4E5F-8532-7B92935F93D4}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Foundatio.AppHost", "samples\Foundatio.AppHost\Foundatio.AppHost.csproj", "{7EABA9A2-C459-4A6A-B5AF-218E6A59E635}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -170,6 +171,18 @@ Global
{BD5CB540-DFF1-4E5F-8532-7B92935F93D4}.Release|x64.Build.0 = Release|Any CPU
{BD5CB540-DFF1-4E5F-8532-7B92935F93D4}.Release|x86.ActiveCfg = Release|Any CPU
{BD5CB540-DFF1-4E5F-8532-7B92935F93D4}.Release|x86.Build.0 = Release|Any CPU
+ {7EABA9A2-C459-4A6A-B5AF-218E6A59E635}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7EABA9A2-C459-4A6A-B5AF-218E6A59E635}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7EABA9A2-C459-4A6A-B5AF-218E6A59E635}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7EABA9A2-C459-4A6A-B5AF-218E6A59E635}.Debug|x64.Build.0 = Debug|Any CPU
+ {7EABA9A2-C459-4A6A-B5AF-218E6A59E635}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7EABA9A2-C459-4A6A-B5AF-218E6A59E635}.Debug|x86.Build.0 = Debug|Any CPU
+ {7EABA9A2-C459-4A6A-B5AF-218E6A59E635}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7EABA9A2-C459-4A6A-B5AF-218E6A59E635}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7EABA9A2-C459-4A6A-B5AF-218E6A59E635}.Release|x64.ActiveCfg = Release|Any CPU
+ {7EABA9A2-C459-4A6A-B5AF-218E6A59E635}.Release|x64.Build.0 = Release|Any CPU
+ {7EABA9A2-C459-4A6A-B5AF-218E6A59E635}.Release|x86.ActiveCfg = Release|Any CPU
+ {7EABA9A2-C459-4A6A-B5AF-218E6A59E635}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -178,6 +191,7 @@ Global
{39AFF0C0-D64A-4D57-871F-17D9BF2E5A93} = {A1DFF80C-113F-4FEC-84BB-1E3790FB410F}
{6A0F1A4B-C0D2-423C-9B9D-7E75B91B41EE} = {70515E66-DAF8-4D18-8F8F-8A2934171AA9}
{99CBF75F-9204-4D7E-A792-4377C0291900} = {70515E66-DAF8-4D18-8F8F-8A2934171AA9}
+ {7EABA9A2-C459-4A6A-B5AF-218E6A59E635} = {A1DFF80C-113F-4FEC-84BB-1E3790FB410F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BD75F5C6-658B-40DF-A8F6-91C3EB76DAAA}
diff --git a/samples/Directory.Build.props b/samples/Directory.Build.props
deleted file mode 100644
index faee085f..00000000
--- a/samples/Directory.Build.props
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
- net8.0
- Exe
- False
-
-
\ No newline at end of file
diff --git a/samples/Foundatio.AppHost/Foundatio.AppHost.csproj b/samples/Foundatio.AppHost/Foundatio.AppHost.csproj
new file mode 100644
index 00000000..91dfcd62
--- /dev/null
+++ b/samples/Foundatio.AppHost/Foundatio.AppHost.csproj
@@ -0,0 +1,23 @@
+
+
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+ true
+ 96cfcbc9-36fb-452f-9b99-0165197e1978
+ False
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/Foundatio.AppHost/Program.cs b/samples/Foundatio.AppHost/Program.cs
new file mode 100644
index 00000000..916e0dfa
--- /dev/null
+++ b/samples/Foundatio.AppHost/Program.cs
@@ -0,0 +1,9 @@
+using Projects;
+
+var builder = DistributedApplication.CreateBuilder(args);
+
+builder.AddProject("HostingSample")
+ .WithExternalHttpEndpoints()
+ .WithArgs("all");
+
+builder.Build().Run();
diff --git a/samples/Foundatio.AppHost/Properties/launchSettings.json b/samples/Foundatio.AppHost/Properties/launchSettings.json
new file mode 100644
index 00000000..75277a87
--- /dev/null
+++ b/samples/Foundatio.AppHost/Properties/launchSettings.json
@@ -0,0 +1,29 @@
+{
+ "$schema": "https://json.schemastore.org/launchsettings.json",
+ "profiles": {
+ "https": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "applicationUrl": "https://localhost:17176;http://localhost:15249",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "DOTNET_ENVIRONMENT": "Development",
+ "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "https://localhost:21196",
+ "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "https://localhost:22113"
+ }
+ },
+ "http": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "applicationUrl": "http://localhost:15249",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development",
+ "DOTNET_ENVIRONMENT": "Development",
+ "DOTNET_DASHBOARD_OTLP_ENDPOINT_URL": "http://localhost:19180",
+ "DOTNET_RESOURCE_SERVICE_ENDPOINT_URL": "http://localhost:20234"
+ }
+ }
+ }
+}
diff --git a/samples/Foundatio.AppHost/appsettings.Development.json b/samples/Foundatio.AppHost/appsettings.Development.json
new file mode 100644
index 00000000..0c208ae9
--- /dev/null
+++ b/samples/Foundatio.AppHost/appsettings.Development.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ }
+}
diff --git a/samples/Foundatio.AppHost/appsettings.json b/samples/Foundatio.AppHost/appsettings.json
new file mode 100644
index 00000000..31c092aa
--- /dev/null
+++ b/samples/Foundatio.AppHost/appsettings.json
@@ -0,0 +1,9 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning",
+ "Aspire.Hosting.Dcp": "Warning"
+ }
+ }
+}
diff --git a/samples/Foundatio.HostingSample/Foundatio.HostingSample.csproj b/samples/Foundatio.HostingSample/Foundatio.HostingSample.csproj
index 87276436..bd1dd06b 100644
--- a/samples/Foundatio.HostingSample/Foundatio.HostingSample.csproj
+++ b/samples/Foundatio.HostingSample/Foundatio.HostingSample.csproj
@@ -1,12 +1,24 @@
-
+
+
+
+ net8.0
+ False
+
+
-
+
+
+
+
+
+
-
\ No newline at end of file
+
+
diff --git a/samples/Foundatio.HostingSample/Program.cs b/samples/Foundatio.HostingSample/Program.cs
index 3e0d0cfd..966e413a 100644
--- a/samples/Foundatio.HostingSample/Program.cs
+++ b/samples/Foundatio.HostingSample/Program.cs
@@ -4,166 +4,150 @@
using System.Threading;
using System.Threading.Tasks;
using Foundatio.Caching;
-using Foundatio.Extensions.Hosting.Jobs;
using Foundatio.Extensions.Hosting.Startup;
+using Foundatio.Extensions.Hosting.Jobs;
+using Foundatio.HostingSample;
using Microsoft.AspNetCore.Builder;
-using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Serilog;
-using Serilog.Events;
-namespace Foundatio.HostingSample;
+Log.Logger = new LoggerConfiguration()
+ .WriteTo.Console()
+ .CreateLogger();
-public class Program
+try
{
- public static int Main(string[] args)
+ Log.Information("Starting web application");
+
+ bool all = args.Contains("all", StringComparer.OrdinalIgnoreCase);
+ bool sample1 = all || args.Contains("sample1", StringComparer.OrdinalIgnoreCase);
+ bool sample2 = all || args.Contains("sample2", StringComparer.OrdinalIgnoreCase);
+ bool everyMinute = all || args.Contains("everyMinute", StringComparer.OrdinalIgnoreCase);
+ bool evenMinutes = all || args.Contains("evenMinutes", StringComparer.OrdinalIgnoreCase);
+
+ var builder = WebApplication.CreateBuilder(args);
+
+ builder.AddServiceDefaults();
+
+ builder.Services.AddSerilog();
+
+ // shutdown the host if no jobs are running
+ builder.Services.AddJobLifetimeService();
+ builder.Services.AddSingleton(_ => new InMemoryCacheClient());
+
+ // inserts a startup action that does not complete until the critical health checks are healthy
+ // gets inserted as 1st startup action so that any other startup actions don't run until the critical resources are available
+ builder.Services.AddStartupActionToWaitForHealthChecks("Critical");
+
+ builder.Services.AddHealthChecks().AddCheck("My Critical Resource", tags: ["Critical"]);
+
+ // add health check that does not return healthy until the startup actions have completed
+ // useful for readiness checks
+ builder.Services.AddHealthChecks().AddCheckForStartupActions("Critical");
+
+ // this gets added automatically by any AddJob call, but we might not be running any jobs and we need it for doing dynamic jobs
+ builder.Services.AddJobScheduler();
+
+ if (everyMinute)
+ builder.Services.AddDistributedCronJob("* * * * *", j => j.Name(nameof(EveryMinuteJob)));
+
+ if (evenMinutes)
+ builder.Services.AddCronJob("EvenMinutes", "*/2 * * * *", async sp =>
+ {
+ var logger = sp.GetRequiredService>();
+ if (logger.IsEnabled(LogLevel.Information))
+ logger.LogInformation("EvenMinuteJob Run Thread={ManagedThreadId}", Thread.CurrentThread.ManagedThreadId);
+
+ await Task.Delay(TimeSpan.FromSeconds(5));
+ });
+
+ if (sample1)
+ builder.Services.AddJob("Sample1", sp => new Sample1Job(sp.GetRequiredService()), o => o.ApplyDefaults().WaitForStartupActions().InitialDelay(TimeSpan.FromSeconds(4)));
+
+ if (sample2)
{
- Log.Logger = new LoggerConfiguration()
- .MinimumLevel.Verbose()
- .MinimumLevel.Override("Microsoft", LogEventLevel.Information)
- .MinimumLevel.Override("Microsoft.AspNetCore.Hosting.Diagnostics", LogEventLevel.Warning)
- .Enrich.FromLogContext()
- .WriteTo.Console()
- .CreateLogger();
-
- try
+ builder.Services.AddHealthChecks().AddCheck("Sample2Job");
+ builder.Services.AddJob(o => o.WaitForStartupActions());
+ }
+
+ // if you don't specify priority, actions will automatically be assigned an incrementing priority starting at 0
+ builder.Services.AddStartupAction("Test1", async sp =>
+ {
+ var logger = sp.GetRequiredService>();
+ logger.LogTrace("Running startup 1 action");
+ for (int i = 0; i < 3; i++)
{
- Log.Information("Starting host");
- CreateHostBuilder(args).Build().Run();
- return 0;
+ await Task.Delay(1000);
+ logger.LogTrace("Running startup 1 action...");
}
- catch (Exception ex)
+
+ logger.LogTrace("Done running startup 1 action");
+ });
+
+ // then these startup actions will run concurrently since they both have the same priority
+ builder.Services.AddStartupAction(priority: 100);
+ builder.Services.AddStartupAction(priority: 100);
+
+ builder.Services.AddStartupAction("Test2", async sp =>
+ {
+ var logger = sp.GetRequiredService>();
+ logger.LogTrace("Running startup 2 action");
+ for (int i = 0; i < 2; i++)
{
- Log.Fatal(ex, "Host terminated unexpectedly");
- return 1;
+ await Task.Delay(1500);
+ logger.LogTrace("Running startup 2 action...");
}
- finally
- {
- Log.CloseAndFlush();
+ //throw new ApplicationException("Boom goes the startup");
+ logger.LogTrace("Done running startup 2 action");
+ });
- if (Debugger.IsAttached)
- Console.ReadKey();
- }
- }
+ //s.AddStartupAction("Boom", () => throw new ApplicationException("Boom goes the startup"));
+
+ var app = builder.Build();
- public static IHostBuilder CreateHostBuilder(string[] args)
+ app.UseSerilogRequestLogging();
+
+ app.MapGet("/", () => "Foundatio!");
+
+ app.MapGet("/jobstatus", httpContext =>
{
- bool all = args.Contains("all", StringComparer.OrdinalIgnoreCase);
- bool sample1 = all || args.Contains("sample1", StringComparer.OrdinalIgnoreCase);
- bool sample2 = all || args.Contains("sample2", StringComparer.OrdinalIgnoreCase);
- bool everyMinute = all || args.Contains("everyMinute", StringComparer.OrdinalIgnoreCase);
- bool evenMinutes = all || args.Contains("evenMinutes", StringComparer.OrdinalIgnoreCase);
-
- var builder = Host.CreateDefaultBuilder(args)
- .UseSerilog()
- .ConfigureWebHostDefaults(webBuilder =>
- {
- webBuilder.Configure(app =>
- {
- app.UseSerilogRequestLogging();
-
- app.UseHealthChecks("/health");
- app.UseReadyHealthChecks("Critical");
- app.UseRouting();
-
- app.UseEndpoints(e =>
- {
- e.MapGet("/jobstatus", httpContext =>
- {
- var jobManager = httpContext.RequestServices.GetRequiredService();
- var status = jobManager.GetJobStatus();
- return httpContext.Response.WriteAsJsonAsync(status);
- });
-
- e.MapGet("/runjob", async httpContext =>
- {
- var jobManager = httpContext.RequestServices.GetRequiredService();
- await jobManager.RunJobAsync("EvenMinutes");
- await jobManager.RunJobAsync();
- });
- });
-
- // this middleware will return Service Unavailable until the startup actions have completed
- app.UseWaitForStartupActionsBeforeServingRequests();
-
- // add mvc or other request middleware after the UseWaitForStartupActionsBeforeServingRequests call
- });
- })
- .ConfigureServices(s =>
- {
- // will shutdown the host if no jobs are running
- s.AddJobLifetimeService();
- s.AddSingleton(_ => new InMemoryCacheClient());
-
- // inserts a startup action that does not complete until the critical health checks are healthy
- // gets inserted as 1st startup action so that any other startup actions dont run until the critical resources are available
- s.AddStartupActionToWaitForHealthChecks("Critical");
-
- s.AddHealthChecks().AddCheck("My Critical Resource", tags: ["Critical"]);
-
- // add health check that does not return healthy until the startup actions have completed
- // useful for readiness checks
- s.AddHealthChecks().AddCheckForStartupActions("Critical");
-
- if (everyMinute)
- s.AddDistributedCronJob("* * * * *");
-
- if (evenMinutes)
- s.AddCronJob("EvenMinutes", "*/2 * * * *", async sp =>
- {
- var logger = sp.GetRequiredService>();
- if (logger.IsEnabled(LogLevel.Information))
- logger.LogInformation("EvenMinuteJob Run Thread={ManagedThreadId}", Thread.CurrentThread.ManagedThreadId);
-
- await Task.Delay(TimeSpan.FromSeconds(5));
- });
-
- if (sample1)
- s.AddJob("Sample1", sp => new Sample1Job(sp.GetRequiredService()), o => o.ApplyDefaults().WaitForStartupActions().InitialDelay(TimeSpan.FromSeconds(4)));
-
- if (sample2)
- {
- s.AddHealthChecks().AddCheck("Sample2Job");
- s.AddJob(o => o.WaitForStartupActions());
- }
-
- // if you don't specify priority, actions will automatically be assigned an incrementing priority starting at 0
- s.AddStartupAction("Test1", async sp =>
- {
- var logger = sp.GetRequiredService>();
- logger.LogTrace("Running startup 1 action");
- for (int i = 0; i < 3; i++)
- {
- await Task.Delay(1000);
- logger.LogTrace("Running startup 1 action...");
- }
-
- logger.LogTrace("Done running startup 1 action");
- });
-
- // then these startup actions will run concurrently since they both have the same priority
- s.AddStartupAction(priority: 100);
- s.AddStartupAction(priority: 100);
-
- s.AddStartupAction("Test2", async sp =>
- {
- var logger = sp.GetRequiredService>();
- logger.LogTrace("Running startup 2 action");
- for (int i = 0; i < 2; i++)
- {
- await Task.Delay(1500);
- logger.LogTrace("Running startup 2 action...");
- }
- //throw new ApplicationException("Boom goes the startup");
- logger.LogTrace("Done running startup 2 action");
- });
-
- //s.AddStartupAction("Boom", () => throw new ApplicationException("Boom goes the startup"));
- });
-
- return builder;
- }
+ var jobManager = httpContext.RequestServices.GetRequiredService();
+ var status = jobManager.GetJobStatus();
+ return httpContext.Response.WriteAsJsonAsync(status);
+ });
+
+ app.MapGet("/runjob", async httpContext =>
+ {
+ var jobManager = httpContext.RequestServices.GetRequiredService();
+ await jobManager.RunJobAsync("EvenMinutes");
+ await jobManager.RunJobAsync();
+ });
+
+ app.UseHealthChecks("/health");
+ app.UseReadyHealthChecks("Critical");
+
+ // this middleware will return Service Unavailable until the startup actions have completed
+ app.UseWaitForStartupActionsBeforeServingRequests();
+
+ // add mvc or other request middleware after the UseWaitForStartupActionsBeforeServingRequests call
+
+ app.Run();
+}
+catch (Exception ex)
+{
+ Log.Fatal(ex, "Application terminated unexpectedly");
+ return 1;
}
+finally
+{
+ Log.CloseAndFlush();
+
+ if (Debugger.IsAttached)
+ Console.ReadKey();
+}
+
+return 0;
+
diff --git a/samples/Foundatio.HostingSample/Properties/launchSettings.json b/samples/Foundatio.HostingSample/Properties/launchSettings.json
index ae82a820..51e58647 100644
--- a/samples/Foundatio.HostingSample/Properties/launchSettings.json
+++ b/samples/Foundatio.HostingSample/Properties/launchSettings.json
@@ -1,8 +1,27 @@
{
- "profiles": {
- "Foundatio.HostingSample": {
- "commandName": "Project",
- "commandLineArgs": "all"
+ "$schema": "https://json.schemastore.org/launchsettings.json",
+ "profiles": {
+ "http": {
+ "commandName": "Project",
+ "commandLineArgs": "all",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "launchUrl": "jobstatus",
+ "applicationUrl": "http://localhost:5324",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "https": {
+ "commandName": "Project",
+ "commandLineArgs": "all",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "launchUrl": "jobstatus",
+ "applicationUrl": "https://localhost:7580;http://localhost:5324",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ }
}
- }
-}
\ No newline at end of file
+}
diff --git a/samples/Foundatio.HostingSample/ServiceDefaults.cs b/samples/Foundatio.HostingSample/ServiceDefaults.cs
new file mode 100644
index 00000000..fbd3284d
--- /dev/null
+++ b/samples/Foundatio.HostingSample/ServiceDefaults.cs
@@ -0,0 +1,57 @@
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using OpenTelemetry;
+using OpenTelemetry.Metrics;
+using OpenTelemetry.Trace;
+
+namespace Microsoft.Extensions.Hosting;
+
+public static class Extensions
+{
+ public static TBuilder AddServiceDefaults(this TBuilder builder) where TBuilder : IHostApplicationBuilder
+ {
+ builder.ConfigureOpenTelemetry();
+
+ return builder;
+ }
+
+ public static TBuilder ConfigureOpenTelemetry(this TBuilder builder) where TBuilder : IHostApplicationBuilder
+ {
+ builder.Logging.AddOpenTelemetry(logging =>
+ {
+ logging.IncludeFormattedMessage = true;
+ logging.IncludeScopes = true;
+ });
+
+ builder.Services.AddOpenTelemetry()
+ .WithMetrics(metrics =>
+ {
+ metrics.AddAspNetCoreInstrumentation()
+ .AddHttpClientInstrumentation()
+ .AddRuntimeInstrumentation()
+ .AddMeter("Foundatio");
+ })
+ .WithTracing(tracing =>
+ {
+ tracing.AddAspNetCoreInstrumentation()
+ .AddHttpClientInstrumentation()
+ .AddSource("Foundatio");
+ });
+
+ builder.AddOpenTelemetryExporters();
+
+ return builder;
+ }
+
+ private static TBuilder AddOpenTelemetryExporters(this TBuilder builder) where TBuilder : IHostApplicationBuilder
+ {
+ var useOtlpExporter = !string.IsNullOrWhiteSpace(builder.Configuration["OTEL_EXPORTER_OTLP_ENDPOINT"]);
+
+ if (useOtlpExporter)
+ {
+ builder.Services.AddOpenTelemetry().UseOtlpExporter();
+ }
+
+ return builder;
+ }
+}
diff --git a/src/Foundatio.Extensions.Hosting/Jobs/HostedJobService.cs b/src/Foundatio.Extensions.Hosting/Jobs/HostedJobService.cs
index 99f5d8c2..7d9eca1a 100644
--- a/src/Foundatio.Extensions.Hosting/Jobs/HostedJobService.cs
+++ b/src/Foundatio.Extensions.Hosting/Jobs/HostedJobService.cs
@@ -52,7 +52,7 @@ private async Task ExecuteAsync(CancellationToken stoppingToken)
try
{
- using var activity = FoundatioDiagnostics.ActivitySource.StartActivity("Job " + _jobOptions.Name);
+ using var activity = FoundatioDiagnostics.ActivitySource.StartActivity("Job: " + _jobOptions.Name);
await runner.RunAsync(stoppingToken).AnyContext();
#if NET8_0_OR_GREATER
diff --git a/src/Foundatio.Extensions.Hosting/Jobs/JobManager.cs b/src/Foundatio.Extensions.Hosting/Jobs/JobManager.cs
index 87d46e78..1ef300d1 100644
--- a/src/Foundatio.Extensions.Hosting/Jobs/JobManager.cs
+++ b/src/Foundatio.Extensions.Hosting/Jobs/JobManager.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
diff --git a/src/Foundatio.Extensions.Hosting/Jobs/ScheduledJobService.cs b/src/Foundatio.Extensions.Hosting/Jobs/ScheduledJobService.cs
index 85d11df3..04441f14 100644
--- a/src/Foundatio.Extensions.Hosting/Jobs/ScheduledJobService.cs
+++ b/src/Foundatio.Extensions.Hosting/Jobs/ScheduledJobService.cs
@@ -37,10 +37,18 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
foreach (var jobToRun in _jobManager.Jobs)
{
- using var activity = FoundatioDiagnostics.ActivitySource.StartActivity("Scheduled Job: " + jobToRun.Options.Name);
+ using var activity = FoundatioDiagnostics.ActivitySource.StartActivity("Job: " + jobToRun.Options.Name);
if (await jobToRun.ShouldRunAsync())
+ {
await jobToRun.StartAsync(stoppingToken).AnyContext();
+ }
+ else
+ {
+ // don't record trace if we didn't run the job and we started the root activity
+ if (activity is { Parent: null })
+ activity.ActivityTraceFlags &= ~ActivityTraceFlags.Recorded;
+ }
}
await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken).AnyContext();
diff --git a/src/Foundatio.Extensions.Hosting/Startup/StartupExtensions.cs b/src/Foundatio.Extensions.Hosting/Startup/StartupExtensions.cs
index ff171865..e18695f1 100644
--- a/src/Foundatio.Extensions.Hosting/Startup/StartupExtensions.cs
+++ b/src/Foundatio.Extensions.Hosting/Startup/StartupExtensions.cs
@@ -54,6 +54,7 @@ await Task.WhenAll(startupActionGroup.Select(async a =>
{
try
{
+ using var activity = FoundatioDiagnostics.ActivitySource.StartActivity("Startup: " + a.Name);
// ReSharper disable once AccessToDisposedClosure
await a.RunAsync(startupActionsScope.ServiceProvider, shutdownToken).AnyContext();
}