我正在寻找一种更好的解决方案来在数据库中记录使用情况事件,然后将其用于生成报告和一些花式图表。
我们当前执行此操作的方式如下:
我们有MVC / API操作筛选器,该筛选器侦听每个请求并调用服务,该服务将提取所有元数据并将其存储在数据库中。您可能会在下面的代码中看到,当前的实现存在错误,并且无法维护和扩展。 (为简便起见,我删除了不重要的代码)
public class LogActivityAttribute : ActionFilterAttribute{
// more code here...
public override void OnActionExecuted(ActionExecutedContext filterContext){
_eventLogService.LogMvcEventLog(filterContext);
}
}
public class EventLogService : IEventLogService
{
// more code here...
public EventLogSummaryModel LogMvcEventLog(ActionExecutedContext filterContext){
try
{
if (filterContext.Controller is ViewerController)
{
switch (filterContext.ActionDescriptor.ActionName)
{
case ReviewApproveDocumentActionName:
return LogEventLogForWorkflow(filterContext);
case ExternalDocumentActionName:
case DocumentActionName:
return HandlePossibleEventsForDocument(filterContext);
}
}
else if (filterContext.Controller is AppController
&& filterContext.ActionDescriptor.ActionName.Equals(AppExternalDocumentActionName))
return HandlePossibleEventsForDocument(filterContext);
else if (filterContext.Controller is Areas.Viewer.Controllers.HomeController
&& filterContext.ActionDescriptor.ActionName.Equals(HomeActionName))
return LogEventLogForWelcomePage(filterContext);
else if (filterContext.Controller is Areas.Viewer.Controllers.HomeController
&& filterContext.ActionDescriptor.ActionName.Equals(LegacySearchActionName))
return LogEventLogForLegacySearch(filterContext);
else if (filterContext.Controller is ApiSearchController
&& filterContext.ActionDescriptor.ActionName.Equals(LegacyApiSearchActionName))
return LogEventLogForLegacyApiSearch(filterContext);
else if (filterContext.Controller is Areas.Viewer.Controllers.FeedbackController)
{
if (filterContext.ActionDescriptor.ActionName.Equals(FeedbackCreateActionViewer))
LogEventsForAddFeedback(filterContext);
}
}
catch (Exception e)
{
ViewerLogger.Instance.Log.Error($"LogMvcEventLog:{e.Message}");
}
return new EventLogSummaryModel();
}
// more code here...
}
我知道,如果尝试解决任何现有问题,最终可能会引入更多错误。所以我正在考虑以一种更好的方式重做整个事情。
我能够想到两种解决方案。
(请注意,它不完整)
// event context metadata from mvc/api actions
public class EventContext
{
public ModeTypes ModeType { get; set; }
public string Instance { get; set; }
public string HttpVerb { get; set; }
public int HttpResponseCode { get; set; }
public int UserId { get; set; }
public ICollection<int> UserRoles { get; set; }
public DateTime Timestamp => DateTime.UtcNow;
}
internal class ApiEventContextDataExtractor
: IApiEventContextDataExtractor
{
private readonly IHttpContextService _httpContextService;
public ApiEventContextDataExtractor(IHttpContextService httpContextService)
{
_httpContextService = httpContextService;
}
public EventContext GetContext(HttpActionExecutedContext filterContext)
{
var userRole = _httpContextService.GetCurrentUserRoles();
var host = _httpContextService.GetHost();
var area = filterContext.ActionContext.RequestContext.RouteData.Values[Constants.EventLogService.AreaName]?.ToString() ?? "";
var mode = area.Equals(AnalyticConstants.EventLogService.AuthorArea, StringComparison.InvariantCultureIgnoreCase)
? ModeTypes.Editor
: ModeTypes.Display;
return new EventContext
{
HttpVerb = filterContext.Request.Method.Method,
HttpResponseCode = (int)filterContext.Response.StatusCode,
Instance = host,
UserId = userRole.Id,
ModeType = mode
};
}
}
internal class MvcEventContextDataExtractor : IMvcEventContextDataExtractor{
// implementation
}
internal class MvcEventReferrerDataExtractor
{
// implementation
}
internal class MvcEventModelDataExtractor
{
// implementation
}
然后,我将获得一个公共服务,该服务将获取EventContext
以及引荐来源数据和模型数据,并将它们记录在数据库中。
所以我想我的问题是,我应该走哪条路? 如果我按照自己的方式去做(第二个),那么我是在正确的轨道上吗?