Commits

Steve Klee committed 6a807bd

* added support for BsonSql.Audit logger ... for capturing all commands going through the library

Comments (0)

Files changed (2)

BsonSql.Driver/BsonSql.Driver.csproj

     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\Libraries\log4net.dll</HintPath>
+    </Reference>
     <Reference Include="MongoDB.Bson">
       <HintPath>..\Libraries\MongoDB.Bson.dll</HintPath>
     </Reference>

BsonSql.Driver/BsonSqlCollection.cs

 using System.Threading.Tasks;
 using System.Runtime.Caching;
 
+using log4net;
+using log4net.Core;
+
 
 
 namespace BsonSql.Driver
 {
 	public class BsonSqlCollection
 	{
+        private static ILog _logger = LogManager.GetLogger("BsonSql.Audit");
+        private string _logMask;
+
 		private IndexSqlCache _indexCache = null;
 		private BsonSqlServer _server;
 		private string _domainId;
 		private string _name;
+        
 		private DomainConfiguration _configuration;
+        
 
 		private object _sync = new object();
+        private bool _logging = false;
 
 		private static Query _findOneById = QueryBuilder.Where(WhereClauseBuilder.CreateBound("BsonDocumentID", Comparison.Equals)).Compile();
 
 			_name = name;
 			_server = server;
 			_configuration = configuration;
+            _logMask = _domainId + "." + _name;
+
+            if (_logger.IsInfoEnabled)
+                _logging = true;
 
 			server.Dispatcher.Add("configuration.changed", new BsonSqlEventHandler<ConfigurationEvent>(ConfigurationChanged));
 		}
 
 			using (SqlConnection conn = new SqlConnection(_configuration.GetServer(connectionId).ConnectionString))
 			{
+                if (_logging)
+                {
+                    if (current.Contains("_id"))
+                        MDC.Set("auditKey.BsonID", current["_id"].AsGuid.ToString());
+                    MDC.Set("auditKey.Server", conn.DataSource);
+                    MDC.Set("auditKey.Db", conn.Database);
+
+                    foreach (BsonElement e in current)
+                    {
+                        MDC.Set("audit." + e.Name, e.ToJson());
+                    }
+                    _logger.Info(_logMask + ((forDelete) ? "Delete" : "Update"));
+
+                    //have to wipe them out or else another thread gets them and may taint the results
+                    MDC.Set("auditKey.BsonID", "");
+                    foreach (BsonElement e in current)
+                    {
+                        MDC.Set("audit." + e.Name, "");
+                    }
+                }
+
 				if (!startedTransaction)
 				{
 					command.Connection = transaction.Connection;
 			{
 				SqlCommand cmd = query.Command.Clone();
 				cmd.CommandText = sql;
+                
+                if (_logging)
+                {
+                    MDC.Set("auditKey.Server", conn.DataSource);
+                    MDC.Set("auditKey.Db", conn.Database);
+                    MDC.Set("audit.Sql", sql);
+                    MDC.Set("auditKey.QID", Guid.NewGuid().ToString());
 
+                    foreach (SqlParameter p in cmd.Parameters)
+                    {
+                        if (p.Value != null && p.Value != DBNull.Value)
+                        {
+                            try { MDC.Set("audit." + p.ParameterName, p.Value.ToString()); }
+                            catch { }
+                        }
+                    }
+
+                    _logger.Info(_logMask + "Query");
+                    
+                    
+                    MDC.Set("audit.Sql", "");
+
+                    foreach (SqlParameter p in cmd.Parameters)
+                    {
+                        MDC.Set("audit." + p.ParameterName, "");
+                    }
+                }
 
 				if (transaction != null)
 				{
 					else
 						wrapper = new DbReaderWrapper(dr);
 
+                    int logIndex = 0;
+
 					while (dr.Read())
 					{
+                        int logCount = 0;
+
 						//always get it as a document first
 						BsonDocument document = wrapper.GetBsonValue<BsonDocument>("BsonDocument");
 						document.Set("_id", wrapper.GetGuid("BsonDocumentID"));
 
+                        if (_logging)
+                        {
+                            MDC.Set("auditKey.Idx", logIndex++.ToString());
+                            MDC.Set("audit.BsonID", wrapper.GetGuid("BsonDocumentID").ToString());
+                            logCount++;
+                        }
+
 						if (fields != null)
 						{
 							//we arent' grabbing all of the fields
 									{
 										BsonDocument addlDocument = wrapper.GetBsonValue<BsonDocument>("BsonDocument" + joinSuffix);
 										addlDocument.Set("_id", wrapper.GetGuid("BsonDocumentID" + joinSuffix));
+
+                                        if (_logging)
+                                        {
+                                            MDC.Set("audit.BsonID" + logCount++.ToString(), addlDocument["_id"].AsGuid.ToString());
+                                        }
+
 										joinResult.SetResult(joinIndex, BsonSqlSerializer.Deserialize(join.ReturnType, addlDocument, (byte[])wrapper.GetValue("Version" + joinSuffix)));
 									}
 								}
 							//otherwise you return the type
 							documents.Add((TDocument)BsonSqlSerializer.Deserialize<TDocument>(document, (byte[])wrapper.GetValue("Version")));
 
+                        if (_logging)
+                        {
+                            _logger.Info(_logMask + "QueryResult");
+
+                            //clear what we need to
+                            MDC.Set("audit.BsonID", "");
+                            for (int logI = 0; logI < logCount; logI++)
+                            {
+                                MDC.Set("audit.BsonID" + logI.ToString(), "");
+                            }
+                        }
 					}
 
 					dr.Close();
+
+                    if (_logging)
+                    {                        
+                        MDC.Set("auditKey.QID", "");
+                        MDC.Set("auditKey.Idx", "");
+                    }
 				}
 			}
 
 
 			using (SqlConnection conn = new SqlConnection(_configuration.GetServer(connectionId).ConnectionString))
 			{
+                if (_logging)
+                {
+                    
+                    
+                    MDC.Set("auditKey.Server", conn.DataSource);
+                    MDC.Set("auditKey.Db", conn.Database);
+                    MDC.Set("audit.Sql", sql);
+
+                    _logger.Info(_logMask + "Count");
+                    MDC.Set("audit.Sql", "");
+                }
+
 				SqlCommand cmd = query.Command.Clone();
 				cmd.CommandText = sql;