2010-11-08 78 views
5

我的工作,我们已被告知以下内容的审计跟踪项目。审计线索:Web应用程序

跟踪所有的在我们与就像休眠Envers确实影子表数据库表(200+)。接下来我们为每个涉及CUD的交易创建快照。

在过去,我实现审计解决方案,为有限集的每一个我的客户的重要数据。对于目前的工作,我的问题是:

  1. 是否有意义审计数据库中的每个表?
  2. 它会像Envers那样跟踪数据的价值多少?任何应用程序都希望为特定数据点提供增量。查询大量的数据来发现增量似乎是不现实的。
  3. 的Envers像解决方案需要与交易有效排除触发占用CUD行动。这是因为触发器在自己的事务中运行,因此在应用程序事务回滚的情况下,影子表中的数据可能不同步。我在这里失踪的任何东西?
  4. 有人建议使用NoSQL DB进行审计跟踪吗?

回答

0

NoSQL数据库的一个选项是RavenDB,使用其“versioning bundle”。

虽然在这一点上它可能太早了,我最近听的羊群代码,他们talk with Eric Sink on about Veracity一个有趣的小插曲。据我所知,Veracity是部分分布式版本控制系统,并且是部分NoSQL数据库。它被设计成从源代码管理系统到wiki的后端。它已经开发了几年,但仍然处于预测阶段(截至2010年11月)。

+0

为了准确性,我不确定它是可能的:http://veracity-scm.com/qa/questions/545/how-to-version-database-data -with-veracity – gpasse 2012-01-09 17:55:04

1

完全实现,并且可以更加改善。我希望这可以帮助某人:

public partial class Entity:DbContext 
    { 

     public enum AuditActions {I,U,D} 

     public override int SaveChanges() 
     { 
      ChangeTracker.DetectChanges(); 
      ObjectContext ctx = ((IObjectContextAdapter)this).ObjectContext; 
      // string UserName = WindowsIdentity.GetCurrent().Name; 
      IPrincipal principal = Thread.CurrentPrincipal; 
      IIdentity identity = principal == null ? null : principal.Identity; 
      string name = identity == null ? "" : identity.Name; 

      //Thread.CurrentPrincipal = new GenericPrincipal(new GenericIdentity((userName), roles); 
      List<ObjectStateEntry> objectStateEntryList = 
       ctx.ObjectStateManager.GetObjectStateEntries(EntityState.Added 
                 | EntityState.Modified 
                 | EntityState.Deleted) 
       .ToList(); 

      List<DBAudit> AuditList = new List<DBAudit>(); 

      string Audittable = string.Empty; 
      foreach (ObjectStateEntry entry in objectStateEntryList) 
      { 
       Audittable = entry.EntitySet.ToString(); 

       if (!entry.IsRelationship && Audittable!="Audit table name") 
       { 

        //sIsAuditTble =entry.EntitySet="DBAudit"? true:false; 
        switch (entry.State) 
        { 
         case EntityState.Added: 
         AuditList= LogDetails(entry, name, AuditActions.I); 
          break; 
         case EntityState.Deleted: 
         AuditList= LogDetails(entry, name, AuditActions.D); 
          break; 
         case EntityState.Modified: 
         AuditList= LogDetails(entry, name, AuditActions.U); 
          break; 

        } 
       } 
      } 



       using (var context = new ProjectTrackerEntities()) 
       { 
        for (int i = 0; i < AuditList.Count; i++) 
        { 
         context.DBAudits.Add(AuditList[i]); 
         context.SaveChanges(); 
        } 
       } 

      return base.SaveChanges(); 
     } 

     public List<DBAudit> LogDetails(ObjectStateEntry entry, string UserName, AuditActions action) 
     { 
      List<DBAudit> dbAuditList = new List<DBAudit>(); 

     if (action == AuditActions.I) 
      { 

       var keyValues = new Dictionary<string, object>(); 
       var currentValues = entry.CurrentValues; 

      // entry.Entity key = new EntityKey(); 

        DBAudit audit = new DBAudit(); 
        audit.AuditId = Guid.NewGuid().ToString(); 
        audit.RevisionStamp = DateTime.Now; 
        audit.TableName = entry.EntitySet.Name; 
        audit.UserName = UserName; 
        audit.OldData = ""; 
        audit.Actions = action.ToString(); 
        for (int i = 0; i < currentValues.FieldCount; i++) 
        { 
        audit.ChangedColumns = audit.ChangedColumns + currentValues.GetName(i); 
        audit.NewData = audit.NewData + currentValues.GetValue(i); 
        audit.ChangedColumns = audit.ChangedColumns + ", "; 
        audit.NewData = audit.NewData + ", "; 
        } 
        dbAuditList.Add(audit); 
        //LogSave(audit); 




      } 
      else if (action == AuditActions.D) 
      { 
       var keyValues = new Dictionary<string, object>(); 
       var DeletedValues = entry.OriginalValues; 

       // entry.Entity key = new EntityKey(); 


       DBAudit audit = new DBAudit(); 
       audit.AuditId = Guid.NewGuid().ToString(); 
       audit.RevisionStamp = DateTime.Now; 
       audit.TableName = entry.EntitySet.Name; 
       audit.UserName = UserName; 
       audit.NewData = ""; 

       audit.Actions = action.ToString(); 
       for (int i = 0; i < DeletedValues.FieldCount; i++) 
       { 
        audit.ChangedColumns = audit.ChangedColumns + DeletedValues.GetName(i); 
        audit.OldData = audit.OldData + DeletedValues.GetValue(i); 
        audit.ChangedColumns = audit.ChangedColumns + ", "; 
        audit.OldData = audit.OldData + ", "; 
       } 
       dbAuditList.Add(audit); 
      } 
      else 
      { 

        foreach (string propertyName in entry.GetModifiedProperties()) 
        { 
         DBAudit audit = new DBAudit(); 
         DbDataRecord original = entry.OriginalValues; 
         string oldValue = original.GetValue(original.GetOrdinal(propertyName)).ToString(); 

         CurrentValueRecord current = entry.CurrentValues; 
         string newValue = current.GetValue(current.GetOrdinal(propertyName)).ToString(); 

         audit.AuditId = Guid.NewGuid().ToString(); 
         audit.RevisionStamp = DateTime.Now; 
         audit.TableName = entry.EntitySet.Name; 
         audit.UserName = UserName; 
         audit.ChangedColumns = propertyName; 
         audit.OldData = oldValue; 
         audit.NewData = newValue; 
         audit.Actions = action.ToString(); 
         dbAuditList.Add(audit); 
         //LogSave(audit); 


        } 

      } 

     return dbAuditList; 


     } 



    } 
+0

欢迎来到SO,在这里,解释为什么要使用您的解决方案,而不仅仅是如何,这是一个很好的做法。这会让你的答案更有价值,并有助于读者更好地理解你是如何做到的。我还建议你看看我们的FAQ:http://stackoverflow.com/faq。 – ForceMagic 2012-12-19 16:53:30