Base solution for your next web application
Open Closed

Saving operation logs with requests over 1024 characters #9525


User avatar
0
ESTeam created

Hi,

i'm using ASP.NET Zero (with .NET Core 3.1 and Angular 9). In the AbpAuditLogs table, i changed the size of the Parameters field from nvarchar (1024) to nvarchar (max), however service requests continue to be cut at position 1024 - example: {"input":{"memId":"001000012600","product":1,"state":2,"paymentMethod":1,"paymentMethodChanged":false,"referenceEntity":null,"amount":90.00,"dueDate":null,"payday":"2020-08-17T00:00:00+00:00","invoiceNumber":"JMS|FT|2020|63","invoiceDate":null,"invoiceDocType":"application/pdf","invoiceDocName":"JMS_FT_2020_63.pdf","invoiceDocContent":"JVBERi0xLjMgCiXi48/TIAoxIDAgb2JqIAo8PCAKL1R5cGUgL0NhdGFsb2cgCi9QYWdlcyAyIDAgUiAKL1BhZ2VNb2RlIC9Vc2VOb25lIAovVmlld2VyUHJlZmVyZW5jZXMgPDwgCi9GaXRXaW5kb3cgdHJ1ZSAKL1BhZ2VMYXlvdXQgL1NpbmdsZVBhZ2UgCi9Ob25GdWxsU2NyZWVuUGFnZU1vZGUgL1VzZU5vbmUgCj4+IAo+PiAKZW5kb2JqIAo1IDAgb2JqIAo8PCAKL0xlbmd0aCAxNjMwIAovRmlsdGVyIFsgL0ZsYXRlRGVjb2RlIF0gCj4+IApzdHJlYW0KeJyFVj1v3EYQ7e9XTBNAAY7U7vLb3UU6CedEliKelcbNmqQUBkdSJnmyEaTw73KbIj8gXbogRaAArtKlyptdUkedFASCJO7uzOzMmzczK0ngR+I39qWbBJRVZkdQezOzH5enMxmTg98gSFwvICcWAYu2xey7WT1T9HIm3NiDkcnfLpv5ClpR6EYBKRGRoySrXM88EbkhlkKYoyDmf06S8D8j8NRaeoTNgN7DpqsC1pVGUVlFZRRTc6MnfTYUKN9KDpcOip4vcOTBsWC4jrVcHycILsSZcuOA/VautMfvZgyQIwdcsmr21XomB9ycEPcEUPA9tr+uBtAQ/mFCodm...

What needs to be changed in addition to the table, in order to be able to save service requests with more than 1024 characters?

best regards, Dirceu


4 Answer(s)
  • User Avatar
    0
    zony created
    Support Team

    Hi ESTeam, I think you need to reimplement the IAuditingStore interface.Because in the default implementation, TruncateWithPostfix() is used to process strings, it will intercept the part exceeding 1024. The reason:

        [Table("AbpAuditLogs")]
        public class AuditLog : Entity<long>, IMayHaveTenant
        {
            // ... Other Code
    
            public static AuditLog CreateFromAuditInfo(AuditInfo auditInfo)
            {
                var exceptionMessage = GetAbpClearException(auditInfo.Exception);
                return new AuditLog
                       {
                           TenantId = auditInfo.TenantId,
                           UserId = auditInfo.UserId,
                           ServiceName = auditInfo.ServiceName.TruncateWithPostfix(MaxServiceNameLength),
                           MethodName = auditInfo.MethodName.TruncateWithPostfix(MaxMethodNameLength),
                           // The problem is here .
                           Parameters = auditInfo.Parameters.TruncateWithPostfix(MaxParametersLength),
                           ReturnValue = auditInfo.ReturnValue.TruncateWithPostfix(MaxReturnValueLength),
                           ExecutionTime = auditInfo.ExecutionTime,
                           ExecutionDuration = auditInfo.ExecutionDuration,
                           ClientIpAddress = auditInfo.ClientIpAddress.TruncateWithPostfix(MaxClientIpAddressLength),
                           ClientName = auditInfo.ClientName.TruncateWithPostfix(MaxClientNameLength),
                           BrowserInfo = auditInfo.BrowserInfo.TruncateWithPostfix(MaxBrowserInfoLength),
                           Exception = exceptionMessage.TruncateWithPostfix(MaxExceptionLength),
                           ImpersonatorUserId = auditInfo.ImpersonatorUserId,
                           ImpersonatorTenantId = auditInfo.ImpersonatorTenantId,
                           CustomData = auditInfo.CustomData.TruncateWithPostfix(MaxCustomDataLength)
                       };
            }
    
            // ...Other Code
    }
    

    StringExtensions.cs

    public static class StringExtensions
    {
        // Other Code ...
        public static string TruncateWithPostfix(this string str, int maxLength)
        {
            return TruncateWithPostfix(str, maxLength, "...");
        }
    
        // Other Code ...
        public static string TruncateWithPostfix(this string str, int maxLength, string postfix)
        {
            if (str == null)
            {
                return null;
            }
    
            if (string.IsNullOrEmpty(str) || maxLength == 0)
            {
                return string.Empty;
            }
    
            if (str.Length <= maxLength)
            {
                return str;
            }
    
            if (maxLength <= postfix.Length)
            {
                return postfix.Left(maxLength);
            }
    
            return str.Left(maxLength - postfix.Length) + postfix;
        }
    }
    
  • User Avatar
    0
    ESTeam created

    Hi again,

    so i create the class ExtendedAuditStore and now i'm lost, can you tell me what to do now? I just want to remove the cuts from the fields in the AbpAuditLogs table - I will modify all fields to nvarchar(max) and then i want to save exactly what am i receiving in the service.

    public class ExtendedAuditStore : AuditingStore { public ExtendedAuditStore(IRepository<AuditLog, long> auditLogRepository) : base(auditLogRepository) {

        }
    
        public override Task SaveAsync(AuditInfo auditInfo)
        {                       
            var result = base.SaveAsync(auditInfo);
    
            return result;
        }
    }
    
    best regards,
    Dirceu
    
  • User Avatar
    0
    zony created
    Support Team

    Hi ESTeam, Because CreateFromAuditInfo is a static method, you cannot override it. So you need to construct an AuditLog entity yourself, copy a copy of the code, and change its character limit.

        public class CustomAuditingStore : IAuditingStore
        {
            private readonly IRepository<AuditLog, long> _auditLogRepository;
    
            public CustomAuditingStore(IRepository<AuditLog, long> auditLogRepository)
            {
                _auditLogRepository = auditLogRepository;
            }
    
            public Task SaveAsync(AuditInfo auditInfo)
            {
                return _auditLogRepository.InsertAsync(CreateAuditLogEntity(auditInfo));
            }
    
            public void Save(AuditInfo auditInfo)
            {
                _auditLogRepository.Insert(CreateAuditLogEntity(auditInfo));
            }
    
            protected virtual AuditLog CreateAuditLogEntity(AuditInfo auditInfo)
            {
                var exceptionMessage = AuditLog.GetAbpClearException(auditInfo.Exception);
                return new AuditLog
                {
                    TenantId = auditInfo.TenantId,
                    UserId = auditInfo.UserId,
                    ServiceName = auditInfo.ServiceName.TruncateWithPostfix(AuditLog.MaxServiceNameLength),
                    MethodName = auditInfo.MethodName.TruncateWithPostfix(AuditLog.MaxMethodNameLength),
                    // Change to 4096.
                    Parameters = auditInfo.Parameters.TruncateWithPostfix(4096),
                    ReturnValue = auditInfo.ReturnValue.TruncateWithPostfix(AuditLog.MaxReturnValueLength),
                    ExecutionTime = auditInfo.ExecutionTime,
                    ExecutionDuration = auditInfo.ExecutionDuration,
                    ClientIpAddress = auditInfo.ClientIpAddress.TruncateWithPostfix(AuditLog.MaxClientIpAddressLength),
                    ClientName = auditInfo.ClientName.TruncateWithPostfix(AuditLog.MaxClientNameLength),
                    BrowserInfo = auditInfo.BrowserInfo.TruncateWithPostfix(AuditLog.MaxBrowserInfoLength),
                    Exception = exceptionMessage.TruncateWithPostfix(AuditLog.MaxExceptionLength),
                    ImpersonatorUserId = auditInfo.ImpersonatorUserId,
                    ImpersonatorTenantId = auditInfo.ImpersonatorTenantId,
                    CustomData = auditInfo.CustomData.TruncateWithPostfix(AuditLog.MaxCustomDataLength)
                };
            }
        }
    
  • User Avatar
    0
    ESTeam created

    Thanks,

    i've already figured it out, your answer also helped by i was trying to use the custom class - i had to add the following lines of code in the method PreInitialize from class CufHealthCareCoreModule: Configuration.ReplaceService(typeof(IAuditingStore), () => { IocManager.Register<IAuditingStore, ExtendedAuditStore>(DependencyLifeStyle.Transient); });