Mostlylucid.Ephemeral.Patterns.SignalLogWatcher
1.7.1
dotnet add package Mostlylucid.Ephemeral.Patterns.SignalLogWatcher --version 1.7.1
NuGet\Install-Package Mostlylucid.Ephemeral.Patterns.SignalLogWatcher -Version 1.7.1
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Mostlylucid.Ephemeral.Patterns.SignalLogWatcher" Version="1.7.1" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Mostlylucid.Ephemeral.Patterns.SignalLogWatcher" Version="1.7.1" />
<PackageReference Include="Mostlylucid.Ephemeral.Patterns.SignalLogWatcher" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Mostlylucid.Ephemeral.Patterns.SignalLogWatcher --version 1.7.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Mostlylucid.Ephemeral.Patterns.SignalLogWatcher, 1.7.1"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Mostlylucid.Ephemeral.Patterns.SignalLogWatcher@1.7.1
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Mostlylucid.Ephemeral.Patterns.SignalLogWatcher&version=1.7.1
#tool nuget:?package=Mostlylucid.Ephemeral.Patterns.SignalLogWatcher&version=1.7.1
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Mostlylucid.Ephemeral.Patterns.SignalLogWatcher
🚨🚨 WARNING 🚨🚨 - Though in the 1.x range of version THINGS WILL STILL BREAK. This is the lab for developing this concept when stabilized it'll becoe the first styloflow release 🚨🚨🚨
Watches a SignalSink for matching signals and triggers callbacks. Useful for error monitoring and alerting.
dotnet add package mostlylucid.ephemeral.patterns.signallogwatcher
Quick Start
using Mostlylucid.Ephemeral.Patterns.SignalLogWatcher;
var sink = new SignalSink();
await using var watcher = new SignalLogWatcher(
sink,
evt => Console.WriteLine($"Error: {evt.Signal}"),
pattern: "error.*",
pollInterval: TimeSpan.FromMilliseconds(100));
// When any signal matching "error.*" appears, the callback fires
// Automatically deduplicates to avoid repeated callbacks for same signal
All Options
new SignalLogWatcher(
// Required: signal sink to watch
sink: signalSink,
// Required: callback when matching signal found
onMatch: evt => HandleSignal(evt),
// Glob pattern to match signals
// Default: "error.*"
pattern: "error.*",
// How often to poll the sink
// Default: 200ms
pollInterval: TimeSpan.FromMilliseconds(200)
)
API Reference
// Constructor starts watching immediately
var watcher = new SignalLogWatcher(sink, callback, pattern, pollInterval);
// Dispose to stop watching
await watcher.DisposeAsync();
How It Works
SignalSink: [error.db] [info.request] [error.api] [error.api] [warn.memory]
│ │ │
▼ ▼ │
Callback Callback │
▼
(deduplicated)
Poll every 200ms:
- Get all signals from sink
- Match against pattern "error.*"
- Fire callback for NEW matches only
- Track seen signals to prevent duplicates
Example: Error Alerting
var sink = new SignalSink();
await using var watcher = new SignalLogWatcher(
sink,
async evt =>
{
await alertService.SendSlackAlert(
$"Error detected: {evt.Signal}",
$"Operation: {evt.OperationId}, Time: {evt.Timestamp}");
},
pattern: "error.*",
pollInterval: TimeSpan.FromSeconds(1));
// All error signals trigger alerts
sink.Raise("error.database.connection");
sink.Raise("error.api.timeout");
Attribute-driven alert jobs
[EphemeralJobs(SignalPrefix = "error")]
public sealed class ErrorAlertJobs
{
private readonly IAlertService _alerts;
public ErrorAlertJobs(IAlertService alerts) => _alerts = alerts;
[EphemeralJob(".*", Lane = "alerts", MaxConcurrency = 2)]
public Task NotifyAsync(SignalEvent evt, CancellationToken ct)
{
return _alerts.SendAlertAsync(
$"Captured {evt.Signal}",
$"Op {evt.OperationId} @ {evt.Timestamp}",
ct);
}
}
var sink = new SignalSink();
await using var runner = new EphemeralSignalJobRunner(sink, new[] { new ErrorAlertJobs(alertService) });
sink.Raise("error.database.connection");
Handlers created from the attribute package see the same signal stream, but the wiring lives right next to the logic
that responds to error.* patterns.
Example: Multiple Watchers
var sink = new SignalSink();
// Watch for errors
await using var errorWatcher = new SignalLogWatcher(
sink,
evt => logger.LogError("Error signal: {Signal}", evt.Signal),
pattern: "error.*");
// Watch for performance issues
await using var perfWatcher = new SignalLogWatcher(
sink,
evt => metrics.RecordSlowOperation(evt.Signal),
pattern: "perf.slow.*");
// Watch for security events
await using var securityWatcher = new SignalLogWatcher(
sink,
evt => securityLog.Record(evt),
pattern: "security.*",
pollInterval: TimeSpan.FromMilliseconds(50)); // Fast polling for security
Example: With Coordinator
var sink = new SignalSink();
await using var coordinator = new EphemeralWorkCoordinator<Request>(
async (req, ct) =>
{
try
{
await ProcessRequest(req, ct);
}
catch (Exception ex)
{
sink.Raise($"error.request.{ex.GetType().Name}");
throw;
}
},
new EphemeralOptions { Signals = sink });
await using var watcher = new SignalLogWatcher(
sink,
evt => Console.WriteLine($"Request failed: {evt.Signal}"),
pattern: "error.request.*");
// Process requests - errors automatically logged
foreach (var req in requests)
await coordinator.EnqueueAsync(req);
Related Packages
| Package | Description |
|---|---|
| mostlylucid.ephemeral | Core library |
| mostlylucid.ephemeral.patterns.anomalydetector | Anomaly detection |
| mostlylucid.ephemeral.patterns.telemetry | Telemetry integration |
| mostlylucid.ephemeral.complete | All in one DLL |
License
Unlicense (public domain)
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net10.0
- mostlylucid.ephemeral (>= 1.7.1)
-
net6.0
- mostlylucid.ephemeral (>= 1.7.1)
-
net7.0
- mostlylucid.ephemeral (>= 1.7.1)
-
net8.0
- mostlylucid.ephemeral (>= 1.7.1)
-
net9.0
- mostlylucid.ephemeral (>= 1.7.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.