Created
December 23, 2025 20:32
-
-
Save pedroinfo/5e5456f8b7a340e9a34fb9a61cd59af9 to your computer and use it in GitHub Desktop.
Simple Heartbeat
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "Heartbeat": { | |
| "Enabled": true, | |
| "IntervalSeconds": 60, | |
| "LogFile": "C:\\logs\\heartbeat.log", | |
| "HealthUrl": "https://localhost/health", | |
| "ConnectionString": "Server=localhost;Database=AppDb;Trusted_Connection=True;" | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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(); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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; } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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