24e94436e2
TaxBaik CI/CD / build-and-deploy (push) Successful in 2m24s
Problem: Client JavaScript/Blazor WebAssembly errors were logged but NOT sent to Telegram because ClientLogsController used LogWarning instead of LogError. Solution: ClientLogsController now checks entry.Level: - level='error' → LogError → Telegram alert ✓ - level='warning'/'info' → LogWarning → Log file only Result: Browser console errors now trigger Telegram notifications: - Blazor WebAssembly init failures - JavaScript exceptions - Unhandled promise rejections - Custom client errors This closes the monitoring gap for client-side issues. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
74 lines
2.4 KiB
C#
74 lines
2.4 KiB
C#
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.RateLimiting;
|
|
|
|
namespace TaxBaik.Web.Controllers;
|
|
|
|
[ApiController]
|
|
[Route("api/client-logs")]
|
|
[AllowAnonymous]
|
|
[EnableRateLimiting("client-logs")]
|
|
public class ClientLogsController(ILogger<ClientLogsController> logger) : ControllerBase
|
|
{
|
|
[HttpPost]
|
|
public IActionResult Post([FromBody] ClientLogEntry entry)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(entry.Message))
|
|
{
|
|
return BadRequest();
|
|
}
|
|
|
|
var logMessage = "ClientLog {Level} {Source} {Message} Url={Url} Route={Route} Screen={Screen} Feature={Feature} Action={Action} Step={Step} Entity={Entity} EntityId={EntityId} DataKey={DataKey} BuildVersion={BuildVersion} UserAgent={UserAgent} Stack={Stack}";
|
|
var args = new object?[]
|
|
{
|
|
entry.Level ?? "error",
|
|
entry.Source ?? "unknown",
|
|
entry.Message,
|
|
entry.Url ?? string.Empty,
|
|
entry.Route ?? string.Empty,
|
|
entry.Screen ?? string.Empty,
|
|
entry.Feature ?? string.Empty,
|
|
entry.Action ?? string.Empty,
|
|
entry.Step ?? string.Empty,
|
|
entry.Entity ?? string.Empty,
|
|
entry.EntityId ?? string.Empty,
|
|
entry.DataKey ?? string.Empty,
|
|
entry.BuildVersion ?? string.Empty,
|
|
entry.UserAgent ?? string.Empty,
|
|
entry.Stack ?? string.Empty
|
|
};
|
|
|
|
// Client errors (level: error) → Telegram alert
|
|
// Client warnings (level: warning/info) → Log file only
|
|
if (entry.Level?.Equals("error", StringComparison.OrdinalIgnoreCase) ?? true)
|
|
{
|
|
logger.LogError(logMessage, args);
|
|
}
|
|
else
|
|
{
|
|
logger.LogWarning(logMessage, args);
|
|
}
|
|
|
|
return Ok();
|
|
}
|
|
}
|
|
|
|
public sealed class ClientLogEntry
|
|
{
|
|
public string? Level { get; set; }
|
|
public string? Source { get; set; }
|
|
public string? Message { get; set; }
|
|
public string? Url { get; set; }
|
|
public string? Route { get; set; }
|
|
public string? Screen { get; set; }
|
|
public string? Feature { get; set; }
|
|
public string? Action { get; set; }
|
|
public string? Step { get; set; }
|
|
public string? Entity { get; set; }
|
|
public string? EntityId { get; set; }
|
|
public string? DataKey { get; set; }
|
|
public string? BuildVersion { get; set; }
|
|
public string? UserAgent { get; set; }
|
|
public string? Stack { get; set; }
|
|
}
|