Open Closed

AbpAuditLogs and AbpAuditLogActions #218


User avatar
0
lalitChougule created

Check the docs before asking a question: https://docs.abp.io/en/commercial/latest/ Check the samples, to see the basic tasks: https://docs.abp.io/en/commercial/latest/samples/index The exact solution to your question may have been answered before, please use the search on the homepage.

  • ABP Framework version: v2.7.0
  • UI type: Angular
  • Tiered (MVC) or Identity Server Seperated (Angular): no / Yes
  • Exception message and stack trace: N.A
  • Steps to reproduce the issue: N.A

Hi,

I need to know how the record get inserted into AbpAuditLogs and AbpAuditLogActions as I want to implement a bit customized logging of my own. How can I implement the same for my own tables or you can say I just want to insert only few Http Status code related data to my own custom table.

How can I do it ?


7 Answer(s)
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    See https://docs.abp.io/en/abp/latest/Audit-Logging#audit-log-contributors

  • User Avatar
    0
    lalitChougule created

    Hi,

    I have implemented Serilog.Sinks.AwsCloudWatch to log my data to AWS-CloudWatch But the problem is according to the documentations of SeriLog I can log data as per LogEventLevel to the CloudWatch which creates huge amout of unnecessary data

    What if I want to log only the data which get logged into AuditLog and AuditLogAction table from database to AWS-CloudWatch.

    Is this possible and how to implement it ?

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Yes you can.

    You can custom AuditingStore to save auditlog to AWS-CloudWatch.

  • User Avatar
    0
    lalitChougule created

    Thanks @liangshiwei

    It will be very helpfull if u can provide some sample code to demonstrate implementation of custom AudtingStore

  • User Avatar
    0
    lalitChougule created

    Hi,

    As you said I tried implementing AudtingStore. But I was not able to log the data like AbpAuditLog.I think I missed out something I got reference from the source code Below is my code , Please help if something is wrong in the implementation

    [Dependency(TryRegister = true)]
    public class AWSAuditingStore: IAuditingStore, ISingletonDependency
        {
            public ILogger<AWSAuditingStore> Logger { get; set; }
    
            public AWSAuditingStore()
            {
                Logger = NullLogger<AWSAuditingStore>.Instance;
            }
    
            public Task SaveAsync(AuditLogInfo auditInfo)
            {
                Logger.LogInformation("AWSAuditingStore : {0}", auditInfo.ToString());
                return Task.FromResult(0);
            }
        }
    
  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    I create a simple implementation, but I don't know about AWS-CloudWatch, I hope I can help you.

    [Dependency(ReplaceServices = true)]
    [ExposeServices(typeof(IAuditingStore))]
    public class CustomAuditingStore : AuditingStore
    {
        private readonly LogEventBatch _repo = new LogEventBatch();
        private readonly IAmazonCloudWatchLogs _client;
        private int _requestCount = 5;
    
        private static readonly Regex InvalidSequenceTokenRegex = new
            Regex(@"The given sequenceToken is invalid. The next expected sequenceToken is: (\d+)");
    
        public CustomAuditingStore(
            IAuditLogRepository auditLogRepository,
            IGuidGenerator guidGenerator,
            IUnitOfWorkManager unitOfWorkManager,
            IOptions<AbpAuditingOptions> options)
            : base(auditLogRepository, guidGenerator, unitOfWorkManager, options)
        {
            _client = new AmazonCloudWatchLogsClient(..your config);
        }
    
        public override async Task SaveAsync(AuditLogInfo auditInfo)
        {
            AddSingleMessage(JsonConvert.SerializeObject(auditInfo));
            await SendMessages();
            await base.SaveAsync(auditInfo);
        }
    
        private void AddSingleMessage(string message)
        {
            _repo.AddMessage(new InputLogEvent()
            {
                Timestamp = DateTime.Now,
                Message = message,
            });
        }
    
        private async Task SendMessages()
        {
            try
            {
                //Make sure the log events are in the right order.
                _repo._request.LogEvents.Sort((ev1, ev2) => ev1.Timestamp.CompareTo(ev2.Timestamp));
                var response = await _client.PutLogEventsAsync(_repo._request).ConfigureAwait(false);
                _repo.Reset(response.NextSequenceToken);
                _requestCount = 5;
            }
            catch (InvalidSequenceTokenException ex)
            {
                //In case the NextSequenceToken is invalid for the last sent message, a new stream would be
                //created for the said application.
                if (_requestCount > 0)
                {
                    _requestCount--;
                    var regexResult = InvalidSequenceTokenRegex.Match(ex.Message);
                    if (regexResult.Success)
                    {
                        _repo._request.SequenceToken = regexResult.Groups[1].Value;
                        await SendMessages().ConfigureAwait(false);
                    }
                }
            }
        }
    }
    
    /// <summary>
    /// Class to handle PutLogEvent request and associated parameters.
    /// Also has the requisite checks to determine when the object is ready for Transmission.
    /// </summary>
    public class LogEventBatch
    {
        public TimeSpan TimeIntervalBetweenPushes { get; private set; }
        public int MaxBatchSize { get; private set; }
    
        public bool ShouldSendRequest(int maxQueuedEvents)
        {
            if (_request.LogEvents.Count == 0)
            {
                return false;
            }
    
            if (_nextPushTime < DateTime.UtcNow)
            {
                return true;
            }
    
            if (maxQueuedEvents <= _request.LogEvents.Count)
            {
                return true;
            }
    
            return false;
        }
    
        int _totalMessageSize { get; set; }
        DateTime _nextPushTime;
        public PutLogEventsRequest _request = new PutLogEventsRequest();
    
        public LogEventBatch(string logGroupName, string streamName, int timeIntervalBetweenPushes, int maxBatchSize)
        {
            _request.LogGroupName = logGroupName;
            _request.LogStreamName = streamName;
            TimeIntervalBetweenPushes = TimeSpan.FromSeconds(timeIntervalBetweenPushes);
            MaxBatchSize = maxBatchSize;
            Reset(null);
        }
    
        public LogEventBatch()
        {
        }
    
        public int CurrentBatchMessageCount
        {
            get { return this._request.LogEvents.Count; }
        }
    
        public bool IsEmpty => _request.LogEvents.Count == 0;
    
        public bool IsSizeConstraintViolated(string message)
        {
            Encoding unicode = Encoding.Unicode;
            int prospectiveLength = _totalMessageSize + unicode.GetMaxByteCount(message.Length);
            if (MaxBatchSize < prospectiveLength)
                return true;
    
            return false;
        }
    
        public void AddMessage(InputLogEvent ev)
        {
            Encoding unicode = Encoding.Unicode;
            _totalMessageSize += unicode.GetMaxByteCount(ev.Message.Length);
            _request.LogEvents.Add(ev);
        }
    
        public void Reset(string SeqToken)
        {
            _request.LogEvents.Clear();
            _totalMessageSize = 0;
            _request.SequenceToken = SeqToken;
            _nextPushTime = DateTime.UtcNow.Add(TimeIntervalBetweenPushes);
        }
    }
    
  • User Avatar
    0
    lalitChougule created

    Thanks alot @liangshiwei It worked

Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11