首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >日志审计信息

日志审计信息
EN

Code Review用户
提问于 2014-10-03 19:12:46
回答 1查看 85关注 0票数 6

我必须实现一个审计系统,在这个系统中,用户必须提供执行某个操作所需的理由。当他提供理由时,他可以自由地表演一段时间。操作的每一次执行都需要在某个地方进行记录。

我使用延拓传递方式实现了它,它允许我干净地处理原子权限检查和操作日志记录。

代码语言:javascript
复制
public class AuditLogger
{
   private readonly TimeSpan permissionDuration;
   private readonly IAuditDatabase auditDatabase;

   private DateTime permissionExpiry = DateTime.MinValue;
   private string accessReason;

   public AuditLogger(TimeSpan permissionDuration, IAuditDatabase auditDatabase)
   {
       this.permissionDuration = permissionDuration;
       this.auditDatabase = auditDatabase;
   }

   private bool CheckPermission()
   {
       return DateTime.UTCNow < permissionExpiry;
   }

   public void SetAccessReason(string reason)
   {
       reason = reason;
       permissionExpiry = DateTime.UTCNow.Add(permissionDuration);
   }

   public void LogAccessAndExecuteOperation(Action operation, Action onPermissionExpired, Action<Exception> onError)
   {
       if(CheckPermission())
           onPermissionExpired();
       try
       {
           auditDatabase.Log(reason);
           operation();            
       }
       catch(Exception exception)
       {
           onError(exception);
       }
   }    
}

你觉得那个怎么样?

这里是一些客户端代码,以显示应该如何使用它。

代码语言:javascript
复制
public static void Main(string[] args)
{
    var auditLogger = new AuditLogger(TimeSpan.FromMinutes(15), new AuditingDatabase);
    var reason = args[0]; // Let's assume the user tells us what he needs to do at startup
    auditLogger.SetAccessReason(reason);

    // Now the user keeps doing lots of things    
    while(1)
    {
        auditLogger.LogAccessAndExecuteOperation(
            () => { /* doing nothing here */ Thread.Sleep(1000); },
            () => {
                Console.WriteLine("Time's up. Can you please tell us again what you need to do?");
                reason = Console.ReadLine();
                auditLogger.SetAccessReason(reason);                
            },
            exeption => Console.WriteLine(exception)
            );
    }
}
EN

回答 1

Code Review用户

发布于 2014-10-03 23:18:06

不幸的是,该类违反了单一责任原则,因为它必须处理日志记录和到期的访问。

您可以在这里使用装饰图案并将授权和日志记录拆分为不同的类,如下所示:

代码语言:javascript
复制
public interface IAccessWidget
{
   string AccessReason { get; }
   void SetAccessReason(string reason);
   void ExecuteOperation(Action operation, Action onPermissionExpired, Action<Exception> onError);
}

public class AccessWidget
{
    private readonly TimeSpan _permissionDuration;
    private DateTime _permissionExpiry = DateTime.MinValue;

    public string AccessReason { get; private set; }

    public AccessWidget(TimeSpan permissionDuration)
    {
        _permissionDuration = permissionDuration;
    }

    private bool CheckPermission()
    {
        return DateTime.UtcNow < _permissionExpiry;
    }

    public void SetAccessReason(string reason)
    {
        AccessReason = reason;
        _permissionExpiry = DateTime.UtcNow.Add(_permissionDuration);
    }

    public void ExecuteOperation(Action operation, Action onPermissionExpired, Action<Exception> onError)
    {
        if(CheckPermission())
            onPermissionExpired();
        try
        {
            operation();
        }
        catch(Exception exception)
        {
            onError(exception);
        }
    }
}

public class LoggingAccessWidget : IAccessWidget
{
    private readonly IAuditDatabase _auditDatabase;
    private readonly IAccessWidget _widget;

    public string AccessReason { get { return _widget.AccessReason; } }

    public LoggingAccessWidget(IAccessWidget widget, IAuditDatabase auditDatabase)
    {
        _widget = widget;
        _auditDatabase = auditDatabase;
    }

    public void SetAccessReason(string reason)
    {
       _widget.SetAccessReason(reason);
    }

    public void ExecuteOperation(Action operation, Action onPermissionExpired, Action<Exception> onError)
    {
        _auditDatabase.Log(_widget.AccessReason);
        _widget.ExecuteOperation(operation, onPermissionExpired, onError);
    }
}
票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/64674

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档