5

我正在开展一个审计跟踪项目,我们被告知要遵循该项目。

就像 Hibernate Envers 一样,使用影子表跟踪我们数据库中的所有表(200+)。因此,我们为涉及 CUD 的每个事务创建了快照。

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

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

2 回答 2

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;


      }



    }
于 2012-12-19T16:35:54.870 回答
0

NoSQL 数据库的一种选择是RavenDB,使用它的“版本控制包”。

虽然现在可能还为时过早,但我最近听了一个有趣的 Herding code 插曲,他们与 Eric Sink 谈论 Veracity。据我了解,Veracity部分是分布式版本控制系统,部分是 NoSQL 数据库。它被设计为从源代码控制系统到 wiki 的任何东西的后端。它已经开发了几年,但实际上仍处于测试前阶段(截至 2010 年 11 月)。

于 2010-11-08T05:31:08.750 回答