diff --git a/src/KArtSell.Host/Infrastructure/TelegramSink.cs b/src/KArtSell.Host/Infrastructure/TelegramSink.cs
new file mode 100644
index 00000000..d6476e62
--- /dev/null
+++ b/src/KArtSell.Host/Infrastructure/TelegramSink.cs
@@ -0,0 +1,106 @@
+using System.Net.Http;
+using Serilog;
+using Serilog.Configuration;
+using Serilog.Core;
+using Serilog.Events;
+
+namespace KArtSell.Host.Infrastructure;
+
+///
+/// Serilog sink for sending critical logs to Telegram
+/// Triggers on ERROR and FATAL events
+///
+public sealed class TelegramSink : ILogEventSink
+{
+ private readonly string _telegramBotToken;
+ private readonly string _telegramChatId;
+ private readonly HttpClient _httpClient;
+ private readonly object _syncRoot = new();
+
+ public TelegramSink(string telegramBotToken, string telegramChatId, HttpClient? httpClient = null)
+ {
+ _telegramBotToken = telegramBotToken;
+ _telegramChatId = telegramChatId;
+ _httpClient = httpClient ?? new HttpClient();
+ }
+
+ public void Emit(LogEvent logEvent)
+ {
+ // Only send critical logs (Error and Fatal)
+ if (logEvent.Level < LogEventLevel.Error)
+ return;
+
+ try
+ {
+ lock (_syncRoot)
+ {
+ SendTelegramMessage(logEvent);
+ }
+ }
+ catch
+ {
+ // Silently ignore Telegram errors to prevent logging loops
+ }
+ }
+
+ private void SendTelegramMessage(LogEvent logEvent)
+ {
+ var emoji = logEvent.Level == LogEventLevel.Fatal ? "🔴" : "⚠️";
+ var levelName = logEvent.Level.ToString().ToUpperInvariant();
+
+ var message = $@"{emoji} *{levelName}* - K-ArtSell Aegis
+
+{logEvent.MessageTemplate.Render(logEvent.Properties)}
+
+_Timestamp: {logEvent.Timestamp:O}_";
+
+ if (logEvent.Exception != null)
+ {
+ message += $@"
+
+```
+{logEvent.Exception.GetType().Name}: {logEvent.Exception.Message}
+```";
+ }
+
+ SendMessage(message);
+ }
+
+ private void SendMessage(string message)
+ {
+ var url = $"https://api.telegram.org/bot{_telegramBotToken}/sendMessage";
+
+ var content = new FormUrlEncodedContent(new Dictionary
+ {
+ { "chat_id", _telegramChatId },
+ { "text", message },
+ { "parse_mode", "Markdown" }
+ });
+
+ try
+ {
+ var response = _httpClient.PostAsync(url, content).GetAwaiter().GetResult();
+ response.EnsureSuccessStatusCode();
+ }
+ catch
+ {
+ // Silently fail - don't want logging to break application
+ }
+ }
+}
+
+///
+/// Serilog extension for adding Telegram sink
+///
+public static class TelegramSinkExtensions
+{
+ public static LoggerConfiguration Telegram(
+ this LoggerSinkConfiguration loggerConfiguration,
+ string telegramBotToken,
+ string telegramChatId,
+ HttpClient? httpClient = null)
+ {
+ return loggerConfiguration.Sink(
+ new TelegramSink(telegramBotToken, telegramChatId, httpClient));
+ }
+}
diff --git a/src/KArtSell.Host/Program.cs b/src/KArtSell.Host/Program.cs
index 991559fb..07419836 100644
--- a/src/KArtSell.Host/Program.cs
+++ b/src/KArtSell.Host/Program.cs
@@ -5,6 +5,7 @@ using KArtSell.BuildingBlocks.Capabilities;
using Microsoft.Extensions.Caching.Memory;
using KArtSell.Host.Jobs;
using KArtSell.Host.Configuration;
+using KArtSell.Host.Infrastructure;
using KArtSell.BuildingBlocks.Data;
using KArtSell.BuildingBlocks.Reliability;
using KArtSell.BuildingBlocks.Time;
@@ -18,14 +19,28 @@ using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
using Serilog;
+using Serilog.Events;
var builder = WebApplication.CreateBuilder(args);
-builder.Host.UseSerilog((context, services, logger) => logger
- .ReadFrom.Configuration(context.Configuration)
- .ReadFrom.Services(services)
- .Enrich.FromLogContext()
- .WriteTo.Console());
+// Load Telegram secrets for Serilog notifications
+var telegramBotToken = Environment.GetEnvironmentVariable("TELEGRAM_BOT") ?? string.Empty;
+var telegramChatId = Environment.GetEnvironmentVariable("CHAT_ID") ?? string.Empty;
+
+builder.Host.UseSerilog((context, services, logger) =>
+{
+ var config = logger
+ .ReadFrom.Configuration(context.Configuration)
+ .ReadFrom.Services(services)
+ .Enrich.FromLogContext()
+ .WriteTo.Console();
+
+ // Add Telegram sink for ERROR and FATAL logs
+ if (!string.IsNullOrEmpty(telegramBotToken) && !string.IsNullOrEmpty(telegramChatId))
+ {
+ config = config.WriteTo.Sink(new TelegramSink(telegramBotToken, telegramChatId), LogEventLevel.Error);
+ }
+});
// Load secrets from environment variables (set by CI/CD or user-secrets in dev)
var connectionString = ResolveSecret(