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}")
|
outputTemplate: "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz}] [{Level:u3}] {Message:lj}{NewLine}{Exception}")
|
||||||
.Enrich.FromLogContext()
|
.Enrich.FromLogContext()
|
||||||
.Enrich.WithProperty("Environment", context.HostingEnvironment.EnvironmentName);
|
.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)
|
// Controllers (API)
|
||||||
|
|||||||
Reference in New Issue
Block a user