Skip to content

Instantly share code, notes, and snippets.

@pedroinfo
Created December 23, 2025 20:32
Show Gist options
  • Select an option

  • Save pedroinfo/5e5456f8b7a340e9a34fb9a61cd59af9 to your computer and use it in GitHub Desktop.

Select an option

Save pedroinfo/5e5456f8b7a340e9a34fb9a61cd59af9 to your computer and use it in GitHub Desktop.
Simple Heartbeat
{
"Heartbeat": {
"Enabled": true,
"IntervalSeconds": 60,
"LogFile": "C:\\logs\\heartbeat.log",
"HealthUrl": "https://localhost/health",
"ConnectionString": "Server=localhost;Database=AppDb;Trusted_Connection=True;"
}
}
public class HeartbeatService : IDisposable
{
private readonly HeartbeatSettings _cfg;
private Timer _timer;
private bool _running;
public HeartbeatService(HeartbeatSettings cfg)
{
_cfg = cfg;
}
public void Start()
{
if (!_cfg.Enabled)
return;
_timer = new Timer(
async _ => await ExecuteAsync(),
null,
TimeSpan.Zero,
TimeSpan.FromSeconds(_cfg.IntervalSeconds));
}
private async Task ExecuteAsync()
{
if (_running) return;
_running = true;
try
{
await CheckAppAsync();
await CheckDbAsync();
}
finally
{
_running = false;
}
}
private async Task CheckAppAsync()
{
var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
try
{
using var http = new HttpClient
{
Timeout = TimeSpan.FromSeconds(5)
};
var r = await http.GetAsync(_cfg.HealthUrl);
Log($"{time} | APP | UP | {(int)r.StatusCode}");
}
catch (Exception ex)
{
Log($"{time} | APP | DOWN | {ex.Message}");
}
}
private async Task CheckDbAsync()
{
var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
try
{
using var conn = new SqlConnection(_cfg.ConnectionString);
await conn.OpenAsync();
using var cmd = new SqlCommand("SELECT 1", conn);
await cmd.ExecuteScalarAsync();
Log($"{time} | DB | UP");
}
catch (Exception ex)
{
Log($"{time} | DB | DOWN | {ex.Message}");
}
}
private void Log(string msg)
{
Directory.CreateDirectory(Path.GetDirectoryName(_cfg.LogFile));
File.AppendAllText(_cfg.LogFile, msg + Environment.NewLine);
}
public void Dispose()
{
_timer?.Dispose();
}
}
public class HeartbeatSettings
{
public bool Enabled { get; set; }
public int IntervalSeconds { get; set; }
public string LogFile { get; set; }
public string HealthUrl { get; set; }
public string ConnectionString { get; set; }
}
var config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
var settings = config.GetSection("Heartbeat").Get<HeartbeatSettings>();
using var hb = new HeartbeatService(settings);
hb.Start();
Console.ReadLine();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment