Merge pull request 'feat: Serilog 기반 실시간 텔레그램 에러 알림 연동' (#6) from feature/telegram-logging into master
TaxBaik CI/CD / build-and-deploy (push) Successful in 54s
TaxBaik CI/CD / build-and-deploy (push) Successful in 54s
Reviewed-on: http://178.104.200.7/kjh2064/taxbaik/pulls/6
This commit was merged in pull request #6.
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Serilog.Core;
|
||||
using Serilog.Events;
|
||||
|
||||
namespace TaxBaik.Web.Logging;
|
||||
|
||||
public class TelegramSink : ILogEventSink
|
||||
{
|
||||
private readonly string _botToken;
|
||||
private readonly string _chatId;
|
||||
private readonly HttpClient _httpClient;
|
||||
|
||||
public TelegramSink(string botToken, string chatId)
|
||||
{
|
||||
_botToken = botToken;
|
||||
_chatId = chatId;
|
||||
_httpClient = new HttpClient();
|
||||
}
|
||||
|
||||
public void Emit(LogEvent logEvent)
|
||||
{
|
||||
if (logEvent.Level < LogEventLevel.Error)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Emit is a synchronous method, so we dispatch the network call asynchronously
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
var timestamp = logEvent.Timestamp.ToString("yyyy-MM-dd HH:mm:ss.fff zzz");
|
||||
var level = logEvent.Level.ToString().ToUpper();
|
||||
var message = logEvent.RenderMessage();
|
||||
var exceptionDetails = logEvent.Exception?.ToString();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine($"<b>🚨 [{level}] 에러 발생</b>");
|
||||
sb.AppendLine($"<b>시간:</b> {timestamp}");
|
||||
sb.AppendLine($"<b>메시지:</b> {EscapeHtml(message)}");
|
||||
|
||||
if (!string.IsNullOrEmpty(exceptionDetails))
|
||||
{
|
||||
var escapedException = EscapeHtml(exceptionDetails);
|
||||
if (escapedException.Length > 3000)
|
||||
{
|
||||
escapedException = escapedException.Substring(0, 3000) + "\n[이하 생략]";
|
||||
}
|
||||
sb.AppendLine($"<b>Exception 상세:</b>\n<pre>{escapedException}</pre>");
|
||||
}
|
||||
|
||||
var url = $"https://api.telegram.org/bot{_botToken}/sendMessage";
|
||||
var payload = new
|
||||
{
|
||||
chat_id = _chatId,
|
||||
text = sb.ToString(),
|
||||
parse_mode = "HTML"
|
||||
};
|
||||
|
||||
var response = await _httpClient.PostAsJsonAsync(url, payload);
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
var errorResponse = await response.Content.ReadAsStringAsync();
|
||||
Console.WriteLine($"[TelegramSink] Failed to send log to Telegram: {response.StatusCode} - {errorResponse}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[TelegramSink] Error in TelegramSink: {ex.Message}");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static string EscapeHtml(string text)
|
||||
{
|
||||
if (string.IsNullOrEmpty(text)) return text;
|
||||
return text.Replace("&", "&")
|
||||
.Replace("<", "<")
|
||||
.Replace(">", ">");
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,13 @@ builder.Host.UseSerilog((context, config) =>
|
||||
outputTemplate: "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz}] [{Level:u3}] {Message:lj}{NewLine}{Exception}")
|
||||
.Enrich.FromLogContext()
|
||||
.Enrich.WithProperty("Environment", context.HostingEnvironment.EnvironmentName);
|
||||
|
||||
var botToken = context.Configuration["Telegram:BotToken"];
|
||||
var systemChatId = context.Configuration["Telegram:SystemChatId"] ?? context.Configuration["Telegram:ChatId"];
|
||||
if (!string.IsNullOrEmpty(botToken) && !string.IsNullOrEmpty(systemChatId))
|
||||
{
|
||||
config.WriteTo.Sink(new TaxBaik.Web.Logging.TelegramSink(botToken, systemChatId), Serilog.Events.LogEventLevel.Error);
|
||||
}
|
||||
});
|
||||
|
||||
// Controllers (API)
|
||||
|
||||
Reference in New Issue
Block a user