Monday 28 November 2011

AppFabric Event Logger Custom SQL Bulk Copy


I recently needed to customize the AppFabric logger to write to a different location apart from a SQL Database. Sadly to say out of the box it only comes with one provider. When configuring AppFabric in IIS Microsoft documentation states that you can provide your own providers.

Sadly to say I was not able to have 2 providers side by side and choose one from the other. Also writing a provider is not a simple task. So what I choose to do was implement my own IBulkCopy implementation. Essentially the three properties and WriteToServer completed the implementation needed for IBulk Copy.

To register my own AppFabricBukCopyProvider I essentially edited the Machine.Config as provided my own implementation dll.

Note: The lockElements of the machine.config forces the subsequent application app.config or web.config not to use bulkCopyProviders so I had little choice but to edit the machine.config.

Here is a sample

Edit Machine.Config

  <microsoft.applicationServer>
    <monitoring lockElements="bulkCopyProviders, collectors">
      <bulkCopyProviders>
        <!-— ORIGINAL ITEM <bulkCopyProvider providerName="System.Data.SqlClient" type="Microsoft.ApplicationServer.Monitoring.EventCollector.SqlServerBulkCopy, Microsoft.ApplicationServer.Monitoring, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> -->
       <!-- Your own implementation -->
      <bulkCopyProvider providerName="System.Data.SqlClient" type="Helper.Provider.AppFabricBulkCopyProvider, Helper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5251f5c14327d259" />
      </bulkCopyProviders>

Here is the AppFabricBulkCopyProvider written in C#.
If you are aware of other ways of implementing this please let me know as I am interested.

Enjoy

    public class AppFabricBulkCopyProvider : IBulkCopy
    {
        public int BatchSize { get; set; }
        public DbConnection Connection { get; set; }
        public string DestinationTableName { get; set; }

        public void WriteToServer(System.Data.IDataReader dataReader)
        {
            System.Diagnostics.Trace.WriteLine("Helper.Provider.WriteToServer");

            try
            {
                AppFabricData appfRequest = new AppFabricData();
                appfRequest.strTable = this.DestinationTableName;
                appfRequest.dtsTable = ConvertDataReadertoDataSet(dataReader);

                appfRequest.dtsTable.WriteXml(string.Format(@"C:\angelol\ MONITORING\{0}-{1}.txt", this.DestinationTableName, Guid.NewGuid().ToString()));

            }
            catch (Exception Exc)
            {
                string strError;

                if (Exc.InnerException == null)
                    strError = string.Format("AppFabric Logging ErrorHandling::Exception:{0}", Exc.ToString());
                else
                    strError = string.Format("AppFabric Logging ErrorHandling::Exception:{0}-InnerException{1}", Exc.ToString(), Exc.InnerException.ToString());

                System.Diagnostics.Trace.WriteLine(strError);
            }
        }


        private DataSet ConvertDataReadertoDataSet(IDataReader reader)
        {
               System.Diagnostics.Trace.WriteLine("Helper.Provider.ConvertDataReadertoDataSet");

            DataSet ds = new DataSet();
            DataTable dataTable = new DataTable(this.DestinationTableName);

            DataTable schemaTable = reader.GetSchemaTable();


            DataRow row;
            string columnName;
            DataColumn column;

            int count = schemaTable.Rows.Count;

            for (int i = 0; i < count; i++)
            {
                row = schemaTable.Rows[i];
                columnName = (string)row["ColumnName"];
                column = new DataColumn(columnName, (Type)row["DataType"]);
                dataTable.Columns.Add(column);
            }
            ds.Tables.Add(dataTable);

            object[] values = new object[count];

            try
            {
                dataTable.BeginLoadData();
                while (reader.Read())
                {
                    reader.GetValues(values);
                    dataTable.LoadDataRow(values, true);
                }

            }
            finally
            {
                dataTable.EndLoadData();
                reader.Close();
            }

            //return dataTable;
            return ds;
        }
    }

No comments:

Post a Comment