Base solution for your next web application
Open Closed

Extend auditlog #1180


User avatar
0
patrickglaudemans created

Hi,

What's the most efficient way to change auditlog entity with some extra fields? Tried to add a partial class but the initial class is not partial.

Should I extend it?

Thanks again,


4 Answer(s)
  • User Avatar
    0
    patrickglaudemans created

    I alway answer my own questions, it seems.. :mrgreen:

    I came across this post concerning the same issue [ #143@9631572b-914f-48a0-b397-5fc4249f15fb ])

  • User Avatar
    0
    hikalkan created
    Support Team

    Hi,

    One possible way is that:

    You can replace WebAuditInfoProvider with your own IAuditInfoProvider implementation and set AuditInfo.CustomData property. How to replace: <a class="postlink" href="http://www.aspnetboilerplate.com/Pages/Documents/Startup-Configuration#replacing-built-in-services">http://www.aspnetboilerplate.com/Pages/ ... n-services</a>

    See WebAuditInfoProvider: <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/blob/master/src/Abp.Web/Auditing/WebAuditInfoProvider.cs">https://github.com/aspnetboilerplate/as ... rovider.cs</a> You can start with copying and modifying it. Currently, you can not inherit from it since Fill method was not virtual on last release, but it will be virtual in the next release.

  • User Avatar
    0
    patrickglaudemans created

    Hi,

    I extended entity AuditLog:

    public  class ExtendedAuditLog : AuditLog, 
      {
          public string Entity { get; set; }
          public int EntityId { get; set; }
          public Guid EntityGuid { get;}
      }
    

    This wil cause an inheritance situation in EF with discriminator field - works ok. But the AuditLogAppService is now broken :? with dep error: Can't create component 'Intertek.BI.Auditing.AuditLogAppService' as it has dependencies to be satisfied.

    'Intertek.BI.Auditing.AuditLogAppService' is waiting for the following dependencies:

    • Service 'Abp.Domain.Repositories.IRepository`2[[Abp.Auditing.ExtendedAuditLog, Intertek.BI.Core, Version=1.4.1.0, Culture=neutral, PublicKeyToken=null],[System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' which was not registered.

    appservice code (only with changed entity auditlog > extendedauditlog)

    [DisableAuditing]
        [AbpAuthorize(AppPermissions.Pages_Administration_AuditLogs)]
        public class AuditLogAppService : BIAppServiceBase, IAuditLogAppService
        {
            private readonly IRepository&lt;ExtendedAuditLog, long&gt; _auditLogRepository;
            private readonly IRepository&lt;User, long&gt; _userRepository;
            private readonly IAuditLogListExcelExporter _auditLogListExcelExporter;
    
            public AuditLogAppService(IRepository&lt;ExtendedAuditLog, long&gt; auditLogRepository, IRepository&lt;User, long&gt; userRepository, IAuditLogListExcelExporter auditLogListExcelExporter)
            {
                _auditLogRepository = auditLogRepository;
                _userRepository = userRepository;
                _auditLogListExcelExporter = auditLogListExcelExporter;
            }
    
            
            
            public async Task&lt;PagedResultOutput&lt;AuditLogListDto&gt;> GetAuditLogs(GetAuditLogsInput input)
            {
                var query = CreateAuditLogAndUsersQuery(input);
    
                var resultCount = await query.CountAsync();
                var results = await query
                    .AsNoTracking()
                    .OrderBy(input.Sorting)
                    .PageBy(input)
                    .ToListAsync();
    
                var auditLogListDtos = ConvertToAuditLogListDtos(results);
    
                return new PagedResultOutput&lt;AuditLogListDto&gt;(resultCount, auditLogListDtos);
            }
    
            public async Task&lt;FileDto&gt; GetAuditLogsToExcel(GetAuditLogsInput input)
            {
                var auditLogs = await CreateAuditLogAndUsersQuery(input)
                            .AsNoTracking()
                            .OrderByDescending(al => al.AuditLog.ExecutionTime)
                            .ToListAsync();
    
                var auditLogListDtos = ConvertToAuditLogListDtos(auditLogs);
    
                return _auditLogListExcelExporter.ExportToFile(auditLogListDtos);
            }
    
            private static List&lt;AuditLogListDto&gt; ConvertToAuditLogListDtos(List&lt;AuditLogAndUser&gt; results)
            {
                return results.Select(
                    result =>
                    {
                        var auditLogListDto = result.AuditLog.MapTo&lt;AuditLogListDto&gt;();
                        auditLogListDto.UserName = result.User == null ? null : result.User.UserName;
                        auditLogListDto.ServiceName = StripNameSpace(auditLogListDto.ServiceName);
                        return auditLogListDto;
                    }).ToList();
            }
    
            private IQueryable&lt;AuditLogAndUser&gt; CreateAuditLogAndUsersQuery(GetAuditLogsInput input)
            {
                var query = from auditLog in _auditLogRepository.GetAll()
                    join user in _userRepository.GetAll() on auditLog.UserId equals user.Id into userJoin
                    from joinedUser in userJoin.DefaultIfEmpty()
                    where auditLog.ExecutionTime >= input.StartDate && auditLog.ExecutionTime &lt; input.EndDate
                    select new AuditLogAndUser {AuditLog = auditLog, User = joinedUser};
    
                query = query
                    .WhereIf(!input.UserName.IsNullOrWhiteSpace(), item =&gt; item.User.UserName.Contains(input.UserName))
                    .WhereIf(!input.ServiceName.IsNullOrWhiteSpace(), item => item.AuditLog.ServiceName.Contains(input.ServiceName))
                    .WhereIf(!input.MethodName.IsNullOrWhiteSpace(), item => item.AuditLog.MethodName.Contains(input.MethodName))
                    .WhereIf(!input.BrowserInfo.IsNullOrWhiteSpace(), item => item.AuditLog.BrowserInfo.Contains(input.BrowserInfo))
                    .WhereIf(input.MinExecutionDuration.HasValue && input.MinExecutionDuration > 0, item => item.AuditLog.ExecutionDuration >= input.MinExecutionDuration.Value)
                    .WhereIf(input.MaxExecutionDuration.HasValue && input.MaxExecutionDuration &lt; int.MaxValue, item =&gt; item.AuditLog.ExecutionDuration &lt;= input.MaxExecutionDuration.Value)
                    .WhereIf(input.HasException == true, item =&gt; item.AuditLog.Exception != null && item.AuditLog.Exception != "")
                    .WhereIf(input.HasException == false, item => item.AuditLog.Exception == null || item.AuditLog.Exception == "");
                return query;
            }
    
            private static string StripNameSpace(string serviceName)
            {
                if (serviceName.IsNullOrEmpty() || !serviceName.Contains("."))
                {
                    return serviceName;
                }
    
                var lastDotIndex = serviceName.LastIndexOf('.');
                return serviceName.Substring(lastDotIndex + 1);
            }
    
            public void SaveEventExcecutionResult(AuditLogEditDto input)
            {
                var auditLog = input.MapTo&lt;ExtendedAuditLog&gt;();
    
                _auditLogRepository.Insert(auditLog);
            }
        }
    

    Can I do something about that? Or should I reverse this and trying to change AuditlogProvider instead (which is nog quitte obvious to me yet).

  • User Avatar
    0
    patrickglaudemans created

    Former error got solved by adding ExtendedAuditLog to BIDbContext

    I'm now capable of logging custommade errors in the same table without having to create new entity and appservice etc.

    Thanks,