Skip to main content
Foveus can be used in .NET Worker Service and BackgroundService applications. Worker services do not have an ASP.NET HTTP middleware pipeline, so setup is slightly different from an HTTP API. Use Foveus in worker services to capture:
  • ILogger logs
  • logged exceptions
  • outbound HTTP telemetry
  • metrics
  • trace propagation
  • SDK shutdown flushing
  • supported messaging instrumentation hooks
Full automatic per-job execution capture for arbitrary BackgroundService loops is not yet implemented. Foveus can capture worker telemetry today, but it does not automatically wrap every worker loop, queue message, or scheduled job as a separate execution unless supported instrumentation is used or the app records lifecycle events.

Install the SDK

Install the Foveus SDK package.
dotnet add package Foveus.SDK
If your worker uses Serilog, also install the Serilog integration.
dotnet add package Foveus.Serilog
During private beta, your package names or package source may be different. Use the package names and feed URL provided during onboarding.

Basic setup

Add Foveus to your worker host.
var builder = Host.CreateApplicationBuilder(args);

builder.Services.AddFoveus(builder.Configuration);

builder.Services.AddHostedService<Worker>();

var host = builder.Build();

await host.RunAsync();
Do not call app.UseFoveus() in a worker service. app.UseFoveus() is ASP.NET Core middleware and only applies to HTTP applications.

Configure the worker

Add a Foveus section to your configuration.
{
  "Foveus": {
    "ApiKey": "fov_test_...",
    "ServiceName": "billing-worker",
    "Source": "worker"
  }
}
Foveus uses Test mode by default. For production, use a live key and set Mode to live.
{
  "Foveus": {
    "ApiKey": "fov_live_...",
    "ServiceName": "billing-worker",
    "Environment": "production",
    "Mode": "live",
    "Source": "worker"
  }
}

What works today

In worker services, Foveus can capture:
CapabilityStatus
ILogger logsSupported
Logged exceptionsSupported
Outbound HttpClient telemetry through IHttpClientFactorySupported
Trace and execution header propagation on outbound HTTPSupported
SDK shutdown flushingSupported
Source classification as workerSupported
MassTransit instrumentation hooksSupported when configured
Automatic per-job execution capture for arbitrary worker loopsNot fully supported yet

Logging from workers

If your worker uses ILogger, Foveus can capture logs through the SDK logger provider.
public sealed class Worker : BackgroundService
{
    private readonly ILogger<Worker> _logger;

    public Worker(ILogger<Worker> logger)
    {
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            _logger.LogInformation("Billing worker heartbeat at {Timestamp}", DateTimeOffset.UtcNow);

            await Task.Delay(TimeSpan.FromSeconds(30), stoppingToken);
        }
    }
}
Log meaningful lifecycle events so Foveus can show what happened. Examples:
_logger.LogInformation("Started processing invoice {InvoiceId}", invoiceId);
_logger.LogInformation("Completed invoice {InvoiceId}", invoiceId);
_logger.LogError(ex, "Failed to process invoice {InvoiceId}", invoiceId);

Exceptions

Logged exceptions can be sent to Foveus.
try
{
    await ProcessInvoiceAsync(invoiceId, stoppingToken);
}
catch (Exception ex)
{
    _logger.LogError(ex, "Failed to process invoice {InvoiceId}", invoiceId);
}
Foveus can capture:
  • exception type
  • exception message
  • stack trace
  • structured log properties
  • service name
  • environment
  • source

Outbound HTTP telemetry

Foveus can instrument outbound HttpClient calls created through IHttpClientFactory.
builder.Services.AddHttpClient("billing-provider");
Then use the client in your worker:
public sealed class Worker : BackgroundService
{
    private readonly IHttpClientFactory _httpClientFactory;
    private readonly ILogger<Worker> _logger;

    public Worker(IHttpClientFactory httpClientFactory, ILogger<Worker> logger)
    {
        _httpClientFactory = httpClientFactory;
        _logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        var client = _httpClientFactory.CreateClient("billing-provider");

        var response = await client.GetAsync("/invoices/pending", stoppingToken);

        _logger.LogInformation("Billing provider returned {StatusCode}", response.StatusCode);
    }
}
Foveus can propagate trace and execution headers on outbound HTTP calls where supported.

MassTransit instrumentation

Foveus has MassTransit integration hooks. When configuring MassTransit, call:
cfg.AddFoveusInstrumentation(context);
Example:
builder.Services.AddMassTransit(x =>
{
    x.UsingRabbitMq((context, cfg) =>
    {
        cfg.AddFoveusInstrumentation(context);

        cfg.ConfigureEndpoints(context);
    });
});
This helps Foveus attach telemetry to supported message-processing flows.
MassTransit instrumentation requires the application to call cfg.AddFoveusInstrumentation(context). It is not automatic unless configured.

Serilog workers

If your worker uses Serilog, use Foveus.Serilog. Install:
dotnet add package Foveus.SDK
dotnet add package Foveus.Serilog
Configure Foveus:
{
  "Foveus": {
    "ApiKey": "fov_test_...",
    "ServiceName": "billing-worker",
    "Source": "worker",
    "EnableFoveusLoggerProvider": false
  }
}
Then configure the Serilog sink:
using Foveus.Serilog;
using Serilog;

var builder = Host.CreateApplicationBuilder(args);

builder.Services.AddFoveus(builder.Configuration);

builder.Services.AddSerilog((services, loggerConfiguration) =>
{
    loggerConfiguration
        .ReadFrom.Configuration(builder.Configuration)
        .ReadFrom.Services(services)
        .WriteTo.Foveus(services);
});

builder.Services.AddHostedService<Worker>();

var host = builder.Build();

await host.RunAsync();
Set EnableFoveusLoggerProvider to false in Serilog-first apps to avoid duplicate logs. See Serilog integration.

Job lifecycle logging

Because automatic per-job execution capture is not fully implemented for arbitrary workers yet, log the lifecycle of important jobs. Use structured logs.
_logger.LogInformation("Started job {JobType} for {ReferenceId}", "InvoiceSync", referenceId);

try
{
    await SyncInvoiceAsync(referenceId, stoppingToken);

    _logger.LogInformation("Completed job {JobType} for {ReferenceId}", "InvoiceSync", referenceId);
}
catch (Exception ex)
{
    _logger.LogError(ex, "Failed job {JobType} for {ReferenceId}", "InvoiceSync", referenceId);
}
This gives Foveus useful evidence even before full worker execution boundaries are available.

What does not work yet

Worker service support is still evolving. Foveus does not yet automatically:
  • wrap every BackgroundService loop as a separate execution
  • know when an arbitrary worker job starts, succeeds, fails, or completes
  • capture inbound request or response bodies in pure workers
  • capture queue or job context for every queue library automatically
  • create full job execution boundaries for arbitrary worker code
Use logs, structured properties, outbound HTTP instrumentation, and supported messaging hooks to give Foveus useful worker telemetry. For a production worker:
{
  "Foveus": {
    "ApiKey": "fov_live_...",
    "ServiceName": "billing-worker",
    "Environment": "production",
    "Mode": "live",
    "Source": "worker",
    "CaptureProfile": "Balanced",
    "EnableSelfMonitoring": true
  }
}
If the worker uses Serilog:
{
  "Foveus": {
    "ApiKey": "fov_live_...",
    "ServiceName": "billing-worker",
    "Environment": "production",
    "Mode": "live",
    "Source": "worker",
    "EnableFoveusLoggerProvider": false
  }
}

Troubleshooting

Logs do not appear

Check that:
  • AddFoveus(builder.Configuration) is called
  • the API key is valid
  • the dashboard is showing the right mode
  • the worker is actually writing logs
  • the log level allows the event
  • the service can reach Foveus

Logs are duplicated

If the worker uses Serilog, disable the built-in Foveus logger provider.
{
  "Foveus": {
    "EnableFoveusLoggerProvider": false
  }
}

Outbound HTTP is not captured

Check that:
  • the worker uses IHttpClientFactory
  • Foveus is registered before clients are used
  • the call is not excluded by configuration
  • the service can reach the outbound target
  • the SDK version supports outbound HTTP instrumentation

Worker jobs do not show as separate executions

That is expected for arbitrary BackgroundService loops today. Full automatic per-job execution capture is not yet implemented. Log job lifecycle events or use supported instrumentation hooks such as MassTransit where available.

What to do next