forked from ddrilling/AsbCloudServer
RequerstTracker Add nullable
This commit is contained in:
parent
b91093b2e4
commit
8e896a887d
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace AsbCloudApp.Data
|
namespace AsbCloudApp.Data
|
||||||
{
|
{
|
||||||
|
#nullable enable
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// DTO журнала запросов
|
/// DTO журнала запросов
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -10,7 +11,7 @@ namespace AsbCloudApp.Data
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// логин пользователя
|
/// логин пользователя
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string UserLogin { get; set; }
|
public string UserLogin { get; set; } = string.Empty;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Id пользователя
|
/// Id пользователя
|
||||||
@ -20,22 +21,22 @@ namespace AsbCloudApp.Data
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// IP адрес пользователя
|
/// IP адрес пользователя
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string UserIp { get; set; }
|
public string? UserIp { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// метод запроса (GET, POST,..)
|
/// метод запроса (GET, POST,..)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string RequestMethod { get; set; }
|
public string RequestMethod { get; set; } = null!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// url
|
/// url
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string RequestPath { get; set; }
|
public string? RequestPath { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Referer
|
/// Referer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Referer { get; set; }
|
public string Referer { get; set; } = string.Empty;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// продолжительность выполнения
|
/// продолжительность выполнения
|
||||||
@ -47,19 +48,20 @@ namespace AsbCloudApp.Data
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int Status { get; set; }
|
public int Status { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// сообщение об ошибке, если она произошла
|
|
||||||
/// </summary>
|
|
||||||
public string ExceptionMessage { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// метка времени запроса
|
/// метка времени запроса
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime Date { get; set; }
|
public DateTime Date { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// сообщение об ошибке, если она произошла
|
||||||
|
/// </summary>
|
||||||
|
public string? ExceptionMessage { get; set; } = null!;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// стек вызовов
|
/// стек вызовов
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ExceptionStack { get; set; }
|
public string? ExceptionStack { get; set; } = null!;
|
||||||
}
|
}
|
||||||
|
#nullable disable
|
||||||
}
|
}
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace AsbCloudApp.Data
|
namespace AsbCloudApp.Data
|
||||||
{
|
{
|
||||||
|
#nullable enable
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// DTO статистики запросов по пользователю
|
/// DTO статистики запросов по пользователю
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -15,12 +16,12 @@ namespace AsbCloudApp.Data
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// логин
|
/// логин
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Login { get; set; }
|
public string Login { get; set; } = string.Empty;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// IP адрес пользователя
|
/// IP адрес пользователя
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Ip { get; set; }
|
public string? Ip { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// время выполнения запроса
|
/// время выполнения запроса
|
||||||
@ -45,6 +46,7 @@ namespace AsbCloudApp.Data
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// DTO пользователя
|
/// DTO пользователя
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public UserDto User { get; set; }
|
public UserDto User { get; set; } = null!;
|
||||||
}
|
}
|
||||||
|
#nullable disable
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace AsbCloudApp.Services
|
namespace AsbCloudApp.Services
|
||||||
{
|
{
|
||||||
// TODO: make this nullable
|
#nullable enable
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Отслеживание и сбор статистики по запросам
|
/// Отслеживание и сбор статистики по запросам
|
||||||
@ -29,34 +29,35 @@ namespace AsbCloudApp.Services
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="take"></param>
|
/// <param name="take"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
IEnumerable<RequestLogDto> GetAll(int take = -1);
|
IEnumerable<RequestLogDto> GetAll(int? take);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// запросы которые выполнялись быстро
|
/// запросы которые выполнялись быстро
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="take"></param>
|
/// <param name="take"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
IEnumerable<RequestLogDto> GetFast(int take = -1);
|
IEnumerable<RequestLogDto> GetFast(int? take);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// запросы, которые выполнялись медленно
|
/// запросы, которые выполнялись медленно
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="take"></param>
|
/// <param name="take"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
IEnumerable<RequestLogDto> GetSlow(int take = -1);
|
IEnumerable<RequestLogDto> GetSlow(int? take);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// запросы, которые завершились ошибкой
|
/// запросы, которые завершились ошибкой
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="take"></param>
|
/// <param name="take"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
IEnumerable<RequestLogDto> GetError(int take = -1);
|
IEnumerable<RequestLogDto> GetError(int? take);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Статистика посещений пользователей
|
/// Статистика посещений пользователей
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="take"></param>
|
/// <param name="take"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
IEnumerable<RequestLogUserDto> GetUsersStat(int take = -1);
|
IEnumerable<RequestLogUserDto> GetUsersStat(int? take);
|
||||||
}
|
}
|
||||||
|
#nullable disable
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace AsbCloudInfrastructure.Services
|
namespace AsbCloudInfrastructure.Services
|
||||||
{
|
{
|
||||||
|
#nullable enable
|
||||||
public class RequestTrackerService : IRequerstTrackerService
|
public class RequestTrackerService : IRequerstTrackerService
|
||||||
{
|
{
|
||||||
const int fastRequestsCount = 1000;
|
const int fastRequestsCount = 1000;
|
||||||
@ -16,28 +17,28 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
|
|
||||||
const int fastLimitMs = 500;
|
const int fastLimitMs = 500;
|
||||||
static readonly char[] stackTraceSeparators = "\r\n".ToCharArray();
|
static readonly char[] stackTraceSeparators = "\r\n".ToCharArray();
|
||||||
private readonly ConcurrentQueue<RequestLogDto> fastRequests = new ConcurrentQueue<RequestLogDto>();
|
private readonly ConcurrentQueue<RequestLogDto> fastRequests = new ();
|
||||||
private readonly ConcurrentQueue<RequestLogDto> slowRequests = new ConcurrentQueue<RequestLogDto>();
|
private readonly ConcurrentQueue<RequestLogDto> slowRequests = new ();
|
||||||
private readonly ConcurrentQueue<RequestLogDto> errorRequests = new ConcurrentQueue<RequestLogDto>();
|
private readonly ConcurrentQueue<RequestLogDto> errorRequests = new ();
|
||||||
private readonly ConcurrentDictionary<string, RequestLogUserDto> users = new ConcurrentDictionary<string, RequestLogUserDto>();
|
private readonly ConcurrentDictionary<string, RequestLogUserDto> users = new ConcurrentDictionary<string, RequestLogUserDto>();
|
||||||
|
|
||||||
private static IEnumerable<RequestLogDto> Get(IEnumerable<RequestLogDto> list, int take = -1)
|
private static IEnumerable<RequestLogDto> Get(IEnumerable<RequestLogDto> list, int? take)
|
||||||
{
|
{
|
||||||
IEnumerable<RequestLogDto> orderedlist = list.OrderByDescending(r => r.Date);
|
IEnumerable<RequestLogDto> orderedlist = list.OrderByDescending(r => r.Date);
|
||||||
if (take > 0)
|
if (take > 0)
|
||||||
orderedlist = orderedlist.Take(take);
|
orderedlist = orderedlist.Take(take.Value);
|
||||||
return orderedlist;
|
return orderedlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<RequestLogUserDto> GetUsersStat(int take = -1)
|
public IEnumerable<RequestLogUserDto> GetUsersStat(int? take)
|
||||||
{
|
{
|
||||||
IEnumerable<RequestLogUserDto> result = users.Values.OrderByDescending(u => u.LastDate);
|
IEnumerable<RequestLogUserDto> result = users.Values.OrderByDescending(u => u.LastDate);
|
||||||
if (take > 0)
|
if (take > 0)
|
||||||
result = result.Take(take);
|
result = result.Take(take.Value);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<RequestLogDto> GetAll(int take = -1)
|
public IEnumerable<RequestLogDto> GetAll(int? take)
|
||||||
{
|
{
|
||||||
var result = fastRequests
|
var result = fastRequests
|
||||||
.Union(slowRequests)
|
.Union(slowRequests)
|
||||||
@ -46,13 +47,13 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
return Get(result, take);
|
return Get(result, take);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<RequestLogDto> GetFast(int take = -1)
|
public IEnumerable<RequestLogDto> GetFast(int? take)
|
||||||
=> Get(fastRequests, take);
|
=> Get(fastRequests, take);
|
||||||
|
|
||||||
public IEnumerable<RequestLogDto> GetSlow(int take = -1)
|
public IEnumerable<RequestLogDto> GetSlow(int? take)
|
||||||
=> Get(slowRequests, take);
|
=> Get(slowRequests, take);
|
||||||
|
|
||||||
public IEnumerable<RequestLogDto> GetError(int take = -1)
|
public IEnumerable<RequestLogDto> GetError(int? take)
|
||||||
=> Get(errorRequests, take);
|
=> Get(errorRequests, take);
|
||||||
|
|
||||||
public void RegisterRequest(RequestLogDto requestLog)
|
public void RegisterRequest(RequestLogDto requestLog)
|
||||||
@ -103,14 +104,13 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(requestLog.UserLogin))
|
if (!string.IsNullOrEmpty(requestLog.UserLogin))
|
||||||
{
|
{
|
||||||
var key = $"{requestLog?.UserId}>{requestLog?.UserIp}";
|
var key = $"{requestLog.UserId}>{requestLog.UserIp}";
|
||||||
if (!users.ContainsKey(key))
|
if (!users.ContainsKey(key))
|
||||||
users[key] = new RequestLogUserDto
|
users[key] = new RequestLogUserDto
|
||||||
{
|
{
|
||||||
UserId = requestLog.UserId,
|
UserId = requestLog.UserId,
|
||||||
Ip = requestLog.UserIp,
|
Ip = requestLog.UserIp,
|
||||||
Login = requestLog.UserLogin,
|
Login = requestLog.UserLogin,
|
||||||
//User = userService.Get(requestLog.UserId),
|
|
||||||
};
|
};
|
||||||
users[key].ElapsedMs += requestLog.ElapsedMilliseconds;
|
users[key].ElapsedMs += requestLog.ElapsedMilliseconds;
|
||||||
users[key].LastDate = requestLog.Date;
|
users[key].LastDate = requestLog.Date;
|
||||||
@ -128,4 +128,5 @@ namespace AsbCloudInfrastructure.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#nullable disable
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace AsbCloudWebApi.Controllers
|
namespace AsbCloudWebApi.Controllers
|
||||||
{
|
{
|
||||||
|
#nullable enable
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Мониторинг запросов, ошибок, пользователей
|
/// Мониторинг запросов, ошибок, пользователей
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -87,4 +88,5 @@ namespace AsbCloudWebApi.Controllers
|
|||||||
return Ok(result);
|
return Ok(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#nullable disable
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace AsbCloudWebApi.Middlewares
|
namespace AsbCloudWebApi.Middlewares
|
||||||
{
|
{
|
||||||
|
#nullable enable
|
||||||
public class RequerstTrackerMiddleware
|
public class RequerstTrackerMiddleware
|
||||||
{
|
{
|
||||||
private readonly RequestDelegate next;
|
private readonly RequestDelegate next;
|
||||||
@ -18,8 +19,8 @@ namespace AsbCloudWebApi.Middlewares
|
|||||||
var service = context.RequestServices.GetRequiredService<AsbCloudApp.Services.IRequerstTrackerService>();
|
var service = context.RequestServices.GetRequiredService<AsbCloudApp.Services.IRequerstTrackerService>();
|
||||||
var requestLog = new AsbCloudApp.Data.RequestLogDto
|
var requestLog = new AsbCloudApp.Data.RequestLogDto
|
||||||
{
|
{
|
||||||
UserLogin = context.User?.Identity.Name,
|
UserLogin = context.User.Identity?.Name ?? string.Empty,
|
||||||
UserIp = context.Connection.RemoteIpAddress.ToString(),
|
UserIp = context.Connection?.RemoteIpAddress?.ToString(),
|
||||||
RequestMethod = context.Request.Method,
|
RequestMethod = context.Request.Method,
|
||||||
RequestPath = context.Request.Path.Value,
|
RequestPath = context.Request.Path.Value,
|
||||||
Referer = context.Request.Headers["Referer"].ToString(),
|
Referer = context.Request.Headers["Referer"].ToString(),
|
||||||
@ -32,7 +33,7 @@ namespace AsbCloudWebApi.Middlewares
|
|||||||
var sw = System.Diagnostics.Stopwatch.StartNew();
|
var sw = System.Diagnostics.Stopwatch.StartNew();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await next?.Invoke(context);
|
await next.Invoke(context);
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
requestLog.ElapsedMilliseconds = sw.ElapsedMilliseconds;
|
requestLog.ElapsedMilliseconds = sw.ElapsedMilliseconds;
|
||||||
requestLog.Status = context.Response.StatusCode;
|
requestLog.Status = context.Response.StatusCode;
|
||||||
@ -43,10 +44,10 @@ namespace AsbCloudWebApi.Middlewares
|
|||||||
sw.Stop();
|
sw.Stop();
|
||||||
requestLog.ElapsedMilliseconds = sw.ElapsedMilliseconds;
|
requestLog.ElapsedMilliseconds = sw.ElapsedMilliseconds;
|
||||||
requestLog.Status = context.Response.StatusCode;
|
requestLog.Status = context.Response.StatusCode;
|
||||||
// TODO: Add request params and body size.
|
|
||||||
service.RegisterRequestError(requestLog, ex);
|
service.RegisterRequestError(requestLog, ex);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#nullable disable
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user