]> git.8kb.co.uk Git - postgresql/dblt/blob - dblt/src/dblt/Program.cs
Alter to allow running against either PostgreSQL or SQL Server
[postgresql/dblt] / dblt / src / dblt / Program.cs
1 //Copyright (c) 2010-2011 Glyn Astill <glyn@8kb.co.uk>\r
2 //Copyright Notice: GPL\r
3 \r
4 using System;\r
5 using System.Collections.Generic;\r
6 using System.Xml;\r
7 using System.Text;\r
8 using System.IO;\r
9 using System.Threading;\r
10 using System.Data;\r
11 using System.Data.SqlClient;\r
12 using Npgsql;\r
13 using System.Configuration;\r
14 using System.Diagnostics;\r
15 \r
16 namespace dblt\r
17 {\r
18     class dblt\r
19     {\r
20         public static string sServerDescription = (string)ConfigurationManager.AppSettings["ServerDescription"];\r
21         public static string sMode = (string)ConfigurationManager.AppSettings["Mode"];\r
22         public static int iClients = Convert.ToInt32(ConfigurationManager.AppSettings["Clients"]);\r
23         public static int iClientsScale = Convert.ToInt32(ConfigurationManager.AppSettings["ClientsScale"]);\r
24         public static int iClientsMax = Convert.ToInt32(ConfigurationManager.AppSettings["ClientsMax"]);\r
25         public static int iIterations = Convert.ToInt32(ConfigurationManager.AppSettings["Iterations"]);\r
26         public static string sLogFile = (string)ConfigurationManager.AppSettings["LogFile"];\r
27         public static string sCsvLogFile = (string)ConfigurationManager.AppSettings["CsvLogFile"];\r
28         public static int iLogLevel = Convert.ToInt32(ConfigurationManager.AppSettings["LogLevel"]);\r
29         public static bool bVerboseScreen = Convert.ToBoolean(ConfigurationManager.AppSettings["VerboseScreen"]);\r
30         public static bool bOnFailureRetry = Convert.ToBoolean(ConfigurationManager.AppSettings["ConnectionRetry"]);\r
31         public static bool bConnPerIteration = Convert.ToBoolean(ConfigurationManager.AppSettings["ConnectionPerIteration"]);\r
32         public static string sConn = (string)ConfigurationManager.AppSettings["ConnectionString"];\r
33         public static string sTransactionsFile = (string)ConfigurationManager.AppSettings["TransactionsFile"];\r
34         public static int iSleepTime = Convert.ToInt32(ConfigurationManager.AppSettings["SleepTime"]);\r
35         private static List<string> lsValidModes = new List<string> { "pgsql", "mssql" };\r
36 \r
37         public static Object oTransCounterLock = new Object();\r
38         public static Object oIterationCounterLock = new Object();\r
39         public static Object oTransDurationLock = new Object();\r
40         public static Object oLogLock = new Object();\r
41 \r
42         public static XmlDocument xmlTransactions = readTransactionsFile(sTransactionsFile);\r
43 \r
44         private static PerformanceCounter oCpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");\r
45         private static PerformanceCounter oSysCpuCounter = new PerformanceCounter("Processor", "% Privileged Time", "_Total");\r
46         private static PerformanceCounter oUseCpuCounter = new PerformanceCounter("Processor", "% User Time", "_Total");\r
47 \r
48         public static string timeStamp = "dd/MM/yyyy HH:mm";\r
49         public static string[] aLogArray = new string[10000000];\r
50         public static double[] aTransactionTimeArray = new double[iClientsMax * iIterations * xmlTransactions.SelectNodes("//transaction").Count];        \r
51         \r
52         public static int iLogIndex, iRunningAtMax, iRunningAtMin, iMaxRunning, iCompletedIterations, iCompletedTransactions;\r
53         public static int iCompletedQueries, iRunningClients, iRunningTransactions, iConnectionTimeouts;\r
54         public static int iConnectionCeilingHit, iConnectionFailure, iConnectionRetries, iFailure, iTransactionTimeIndex;\r
55         public static double iMaxTransDuration, iMinTransDuration;\r
56         public static bool bRunning = false;\r
57         \r
58         static void Main(string[] args)\r
59         {\r
60             if (!lsValidModes.Contains(sMode))\r
61             {\r
62                 Console.WriteLine("Invalid operating mode '{0}': Supported modes are 'mssql' or 'pgsql'", sMode);\r
63                 Environment.Exit(1);\r
64             }\r
65             if (iClients != 0)\r
66             {\r
67                 MainWorker(iClients);\r
68             }\r
69             else if (iClientsScale != 0) \r
70             {\r
71                 if (iClientsMax == 0)\r
72                 {\r
73                     iClientsMax = iClientsScale;\r
74                 }\r
75                 for (int i = iClientsScale; i <= iClientsMax; i= i+iClientsScale)\r
76                 {\r
77                     MainWorker(i);\r
78                 }\r
79             }\r
80         }\r
81 \r
82         public static void MainWorker(int iClientsRun)\r
83         {\r
84             iClients = iClientsRun;\r
85 \r
86             Array.Clear(aLogArray, 0, iLogIndex);\r
87             iLogIndex = 0;\r
88             Array.Clear(aTransactionTimeArray, 0, iTransactionTimeIndex);\r
89             iTransactionTimeIndex = 0;\r
90             iMaxTransDuration = 0;\r
91             iMinTransDuration = 100000000000000000;\r
92             iRunningAtMax = 0;\r
93             iRunningAtMin = 0;\r
94             iMaxRunning = 0;\r
95             iCompletedIterations = 0;\r
96             iCompletedTransactions = 0;\r
97             iCompletedQueries = 0;\r
98             iRunningClients = 0;\r
99             iRunningTransactions = 0;\r
100             iConnectionTimeouts = 0;\r
101             iConnectionCeilingHit = 0;\r
102             iConnectionFailure = 0;\r
103             iConnectionRetries = 0;\r
104             iFailure = 0;\r
105             bRunning = false;\r
106 \r
107             Console.Clear();\r
108 \r
109             Info("-------------------- Test Start --------------------", iLogLevel, false);\r
110             Info("Server Description: " + sServerDescription, iLogLevel, false);\r
111             Info("Database load tester.", iLogLevel, true);\r
112             Info("Iterations per client = " + iIterations, iLogLevel, true);\r
113             Info("launching " + iClients + " clients...", iLogLevel, true);\r
114 \r
115             Thread[] workerThreads = new Thread[iClients];\r
116             \r
117             bRunning = true;\r
118             Thread infoThread = new Thread(new ThreadStart(InfoScreen));\r
119             infoThread.Start();\r
120 \r
121             for (int i = 0; i < workerThreads.Length; i++)\r
122             {\r
123                 workerThreads[i] = new Thread(new ParameterizedThreadStart(ClientWorker));\r
124                 workerThreads[i].Start(i);\r
125                 iRunningClients++;\r
126             }\r
127 \r
128             for (int i = 0; i < workerThreads.Length; i++)\r
129             {\r
130                 workerThreads[i].Join();\r
131                 iRunningClients--;\r
132             }\r
133 \r
134             bRunning = false;\r
135             infoThread.Join();\r
136 \r
137             Info("-------------------- Test Complete --------------------", iLogLevel, false);\r
138             LogWriter();\r
139         }\r
140 \r
141         public static void InfoScreen()\r
142         {\r
143             DateTime startTime = DateTime.Now;\r
144             DateTime currTime = DateTime.Now;\r
145             TimeSpan duration = currTime - startTime;\r
146 \r
147             double iMeanTransactionDuration = 0;\r
148             double iStandatdDeviation = 0;\r
149 \r
150             float fCpuAll = 0;\r
151             float fCpuSys = 0;\r
152             float fCpuUse = 0;\r
153             int iSamples = 0;\r
154 \r
155             if (!bVerboseScreen)\r
156             {\r
157                 while (bRunning)\r
158                 {\r
159                     fCpuAll = fCpuAll + oCpuCounter.NextValue();\r
160                     fCpuSys = fCpuSys + oSysCpuCounter.NextValue();\r
161                     fCpuUse = fCpuUse + oUseCpuCounter.NextValue();\r
162                     iSamples++;\r
163 \r
164                     currTime = DateTime.Now;\r
165                     duration = currTime - startTime;\r
166 \r
167                     Console.SetCursorPosition(0, 4);\r
168                     Console.WriteLine("Running Clients                        {0}                            ", iRunningClients);\r
169                     Console.SetCursorPosition(0, 5);\r
170                     Console.WriteLine("Running Transactions                   {0} : {1} max                  ", iRunningTransactions, iMaxRunning);\r
171 \r
172                     Console.SetCursorPosition(0, 7);\r
173                     Console.WriteLine("Completed Queries                      {0} : {1} qps                  ", iCompletedQueries, (iCompletedQueries / (Convert.ToInt32(duration.TotalSeconds) + 1)));\r
174                     Console.SetCursorPosition(0, 8);\r
175                     Console.WriteLine("Completed Transactions                 {0} : {1} tps                  ", iCompletedTransactions, (iCompletedTransactions / (Convert.ToInt32(duration.TotalSeconds) + 1)));\r
176                     Console.SetCursorPosition(0, 9);\r
177                     Console.WriteLine("Completed Iterations                   {0} / {1}                      ", iCompletedIterations, (iIterations * iClients));\r
178                     \r
179                     Console.SetCursorPosition(0, 11);\r
180                     Console.WriteLine("Maximum Transaction+Read Time          {0} ms : {1} Running           ", iMaxTransDuration, iRunningAtMax);\r
181                     Console.SetCursorPosition(0, 12);\r
182                     Console.WriteLine("Minimum Transaction+Read Time          {0} ms : {1} Running           ", iMinTransDuration, iRunningAtMin);\r
183 \r
184                     Console.SetCursorPosition(0, 14);\r
185                     Console.WriteLine("Connection Timeout/Ceiling Hit/Failure {0} / {1} / {2}                ", iConnectionTimeouts, iConnectionCeilingHit, iConnectionFailure);\r
186                     Console.SetCursorPosition(0, 15);\r
187                     Console.WriteLine("Other Failure                          {0}                            ", iFailure);\r
188                     Console.SetCursorPosition(0, 16);\r
189                     Console.WriteLine("Connection Retries                     {0}                            ", iConnectionRetries);\r
190                     Console.SetCursorPosition(0, 17);\r
191                     Console.WriteLine("Average Client CPU All/User/Sys        {0}% / {1}% / {2}%             ", Math.Round((fCpuAll / iSamples), 2), Math.Round((fCpuUse / iSamples), 2), Math.Round((fCpuSys / iSamples), 2));\r
192 \r
193                     Console.SetCursorPosition(0, 23);\r
194                     Console.WriteLine("{0} s                                                                 ", (Convert.ToInt32(duration.TotalSeconds) + 1));\r
195                     Thread.Sleep(500);\r
196                 }\r
197             }\r
198 \r
199             if (!bRunning)\r
200             {\r
201                 Thread.Sleep(500);\r
202 \r
203                 Console.SetCursorPosition(0, 4);\r
204                 Console.WriteLine("Running Clients                        {0}                            ", iRunningClients);\r
205                 Console.SetCursorPosition(0, 5);\r
206                 Console.WriteLine("Running Transactions                   {0} : {1} max                  ", iRunningTransactions, iMaxRunning);\r
207 \r
208                 Console.SetCursorPosition(0, 7);\r
209                 Console.WriteLine("Completed Queries                      {0} : {1} qps                  ", iCompletedQueries, (iCompletedQueries / (Convert.ToInt32(duration.TotalSeconds) + 1)));\r
210                 Console.SetCursorPosition(0, 8);\r
211                 Console.WriteLine("Completed Transactions                 {0} : {1} tps                  ", iCompletedTransactions, (iCompletedTransactions / (Convert.ToInt32(duration.TotalSeconds) + 1)));\r
212                 Console.SetCursorPosition(0, 9);\r
213                 Console.WriteLine("Completed Iterations                   {0} / {1}                      ", iCompletedIterations, (iIterations * iClients));\r
214 \r
215                 Console.SetCursorPosition(0, 11);\r
216                 Console.WriteLine("Maximum Transaction+Read Time          {0} ms : {1} Running           ", iMaxTransDuration, iRunningAtMax);\r
217                 Console.SetCursorPosition(0, 12);\r
218                 Console.WriteLine("Minimum Transaction+Read Time          {0} ms : {1} Running           ", iMinTransDuration, iRunningAtMin);\r
219 \r
220                 Console.SetCursorPosition(0, 14);\r
221                 Console.WriteLine("Connection Timeout/Ceiling Hit/Failure {0} / {1} / {2}                ", iConnectionTimeouts, iConnectionCeilingHit, iConnectionFailure);\r
222                 Console.SetCursorPosition(0, 15);\r
223                 Console.WriteLine("Other Failure                          {0}                            ", iFailure);\r
224                 Console.SetCursorPosition(0, 16);\r
225                 Console.WriteLine("Connection Retries                     {0}                            ", iConnectionRetries);\r
226                 Console.SetCursorPosition(0, 17);\r
227                 Console.WriteLine("Average Client CPU All/User/Sys        {0}% / {1}% / {2}%             ", Math.Round((fCpuAll / iSamples),2), Math.Round((fCpuUse / iSamples),2), Math.Round((fCpuSys / iSamples),2));\r
228 \r
229                 Console.SetCursorPosition(0, 23);\r
230                 Console.WriteLine("{0} s                                                                 ", (Convert.ToInt32(duration.TotalSeconds) + 1));\r
231 \r
232                 Info("==========================================================", iLogLevel, bVerboseScreen);\r
233                 Info("     Running Clients                        " + iRunningClients, iLogLevel, bVerboseScreen);\r
234                 Info("     Running Transactions                   " + iRunningTransactions, iLogLevel, bVerboseScreen);\r
235                 Info("     Completed Queries                      " + iCompletedQueries + " : " + (iCompletedQueries / (Convert.ToInt32(duration.TotalSeconds) + 1)) + " qps", iLogLevel, bVerboseScreen);\r
236                 Info("     Completed Transactions                 " + iCompletedTransactions + " : " + (iCompletedTransactions / (Convert.ToInt32(duration.TotalSeconds) + 1)) + " tps", iLogLevel, bVerboseScreen);\r
237                 Info("     Completed Iterations                   " + iCompletedIterations + " / " + (iIterations * iClients), iLogLevel, bVerboseScreen);\r
238                 Info("     Maximum Transaction+Read Time          " + iMaxTransDuration + " ms", iLogLevel, bVerboseScreen);\r
239                 Info("     Minimum Transaction+Read Time          " + iMinTransDuration + " ms", iLogLevel, bVerboseScreen);\r
240                 Info("     Connection Timeout/Ceiling Hit/Failure " + iConnectionTimeouts + " / " + iConnectionCeilingHit + " / " + iConnectionFailure, iLogLevel, bVerboseScreen);\r
241                 Info("     Other Failure                          " + iFailure, iLogLevel, bVerboseScreen);\r
242                 Info("     Connection Retries                     " + iConnectionRetries, iLogLevel, bVerboseScreen);\r
243                 Info("     Total Time                             " + Convert.ToInt32(duration.TotalSeconds) + 1, iLogLevel, bVerboseScreen);\r
244                 Info("     Max Concurrent Transactions            " + iMaxRunning, iLogLevel, bVerboseScreen);\r
245                 Info("     Average Client CPU All/User/Sys        " + Math.Round((fCpuAll / iSamples), 2) + "% " + Math.Round((fCpuUse / iSamples), 2) + "% " + Math.Round((fCpuSys / iSamples), 2) + "%", iLogLevel, bVerboseScreen);\r
246                 Info("==========================================================", iLogLevel, bVerboseScreen);\r
247 \r
248                 iMeanTransactionDuration = 0;\r
249                 iStandatdDeviation = 0;\r
250 \r
251                 for (int i = 0; i < iTransactionTimeIndex; i++)\r
252                 {\r
253                     iMeanTransactionDuration = (aTransactionTimeArray[i] + iMeanTransactionDuration);\r
254                 }\r
255                 iMeanTransactionDuration = (iMeanTransactionDuration / iTransactionTimeIndex);\r
256 \r
257                 for (int i = 0; i < iTransactionTimeIndex; i++)\r
258                 {\r
259 \r
260                     iStandatdDeviation = (Math.Pow((aTransactionTimeArray[i] - iMeanTransactionDuration), 2) + iStandatdDeviation);\r
261                 }\r
262                 iStandatdDeviation = Math.Sqrt(iStandatdDeviation / iTransactionTimeIndex);\r
263 \r
264                 CsvLogWriter("\"" + sServerDescription + "\"," + iClients + "," + iIterations + "," + iMaxTransDuration + "," + iMinTransDuration + "," + iRunningAtMax + "," + iRunningAtMin + "," + iMeanTransactionDuration + "," + iStandatdDeviation + "," + (iCompletedTransactions / (Convert.ToInt32(duration.TotalSeconds) + 1)) + "," + (iCompletedQueries / (Convert.ToInt32(duration.TotalSeconds) + 1)) + "," + iMaxRunning + "," + (Convert.ToInt32(duration.TotalSeconds) + 1) + "," + (fCpuAll / iSamples));\r
265             }\r
266         }\r
267 \r
268         public static void ClientWorker(object iThread)\r
269         {\r
270             \r
271                 Info("Starting client thread " + iThread.ToString(), iLogLevel, bVerboseScreen);\r
272 \r
273                 Random random = new Random();\r
274                 int iTransOn = 0;\r
275                 int iSqlOn = 0;\r
276                 string sSql = "";\r
277                 int iRandomStmt = 0;\r
278                 int iRandomTran = 0;\r
279                 SqlConnection msconn = null;\r
280                 NpgsqlConnection conn = null;\r
281                 if (!bConnPerIteration)\r
282                 {\r
283                     if (sMode == "pgsql") {\r
284                         conn = new NpgsqlConnection(sConn);\r
285                         conn.Open();\r
286                     }\r
287                     else if (sMode == "mssql")\r
288                     {\r
289                         msconn = new SqlConnection(sConn);\r
290                         msconn.Open();\r
291                     }\r
292                 }\r
293 \r
294                 for (int i = 0; i < iIterations; i++)\r
295                 {\r
296                     try\r
297                     {\r
298                             DateTime startTime = DateTime.Now;\r
299                             if (bConnPerIteration)\r
300                             {\r
301                                 if (sMode == "pgsql")\r
302                                 {\r
303                                     conn = new NpgsqlConnection(sConn);\r
304                                     conn.Open();\r
305                                 }\r
306                                 else if (sMode == "mssql")\r
307                                 {\r
308                                     msconn = new SqlConnection(sConn);\r
309                                     msconn.Open();\r
310                                 }\r
311                             }\r
312 \r
313                             iTransOn = 0;\r
314                             foreach (XmlNode node in xmlTransactions.SelectNodes("//transaction"))\r
315                             {\r
316                                 iTransOn++;\r
317                                 XmlNode randomtransaction = node.Attributes["random"];\r
318                                 if (randomtransaction != null && node.Attributes["random"].Value.Trim().ToLower() == "true")\r
319                                 {\r
320                                     iRandomTran = random.Next(0, 2);\r
321                                 }\r
322 \r
323                             if (iRandomTran == 0)\r
324                             {\r
325                                     NpgsqlTransaction tran = null;\r
326                                     SqlTransaction mstran = null;\r
327 \r
328                                     if (sMode == "pgsql")\r
329                                     {\r
330                                         tran = conn.BeginTransaction();\r
331                                     }\r
332                                     else if (sMode == "mssql")\r
333                                     {\r
334                                          mstran = msconn.BeginTransaction();\r
335                                     }\r
336 \r
337                                     DateTime beginTime = DateTime.Now;\r
338 \r
339                                     lock (oTransCounterLock)\r
340                                     {\r
341                                         iRunningTransactions++;\r
342                                     }\r
343 \r
344                                     iSqlOn = 0;\r
345                                     foreach (XmlNode subnode in node.SelectNodes("//sql"))\r
346                                     {\r
347                                         iSqlOn++;\r
348                                         XmlNode randomsql = subnode.Attributes["random"];\r
349                                         if (randomsql != null && subnode.Attributes["random"].Value.Trim().ToLower() == "true")\r
350                                         {\r
351                                             iRandomStmt = random.Next(0, 2);\r
352                                         }\r
353 \r
354                                         if (iRandomStmt == 0)\r
355                                         {\r
356                                             sSql = subnode.InnerText;\r
357 \r
358                                             if (sMode == "pgsql")\r
359                                             {\r
360                                                 NpgsqlCommand command = new NpgsqlCommand(sSql.Replace("#client_id#", iThread.ToString()), conn, tran);\r
361                                                 NpgsqlDataReader dr = command.ExecuteReader();\r
362 \r
363                                                 iCompletedQueries++;\r
364                                                 while (dr.Read())\r
365                                                 {\r
366                                                     //Just pull the data back into our dataset (but we don't care about it)\r
367                                                 }\r
368 \r
369                                                 dr.Close();\r
370                                             }\r
371                                             else if (sMode == "mssql")\r
372                                             {\r
373                                                 SqlCommand command = new SqlCommand(sSql.Replace("#client_id#", iThread.ToString()), msconn, mstran);\r
374                                                 SqlDataReader dr = command.ExecuteReader();\r
375 \r
376                                                 iCompletedQueries++;\r
377                                                 while (dr.Read())\r
378                                                 {\r
379                                                     //Just pull the data back into our dataset (but we don't care about it)\r
380                                                 }\r
381 \r
382                                                 dr.Close();\r
383                                             }\r
384 \r
385                                             if (iLogLevel > 1)\r
386                                             {\r
387                                                 Info("Client " + iThread.ToString() + " Transaction = " + iTransOn + " Statement = " + iSqlOn + " SQL = \"" + sSql + "\" Running", iLogLevel, bVerboseScreen);\r
388                                             }\r
389                                         }\r
390                                         else\r
391                                         {\r
392                                             if (iLogLevel > 1)\r
393                                             {\r
394                                                 Info("Client " + iThread.ToString() + " Transaction = " + iTransOn + " Statement = " + iSqlOn + " Skipping as random statement = true", iLogLevel, bVerboseScreen);\r
395                                             }\r
396                                         }\r
397                                     }\r
398 \r
399 \r
400                                     if (sMode == "pgsql")\r
401                                     {\r
402                                         tran.Commit();\r
403                                     }\r
404                                     else if (sMode == "mssql")\r
405                                     {\r
406                                         mstran.Commit();\r
407                                     }\r
408 \r
409                                     DateTime commitTime = DateTime.Now;\r
410                                     TimeSpan transactionDuration = commitTime - beginTime;\r
411 \r
412                                     if (iRunningClients == iClients)\r
413                                     {\r
414 \r
415                                         if (transactionDuration.TotalMilliseconds > iMaxTransDuration)\r
416                                         {\r
417                                             lock (oTransDurationLock)\r
418                                             {\r
419                                                 iMaxTransDuration = transactionDuration.TotalMilliseconds;\r
420                                                 iRunningAtMax = iRunningTransactions;\r
421                                             }\r
422                                         }\r
423                                         if (transactionDuration.TotalMilliseconds < iMinTransDuration)\r
424                                         {\r
425                                             lock (oTransDurationLock)\r
426                                             {\r
427                                                 iMinTransDuration = transactionDuration.TotalMilliseconds;\r
428                                                 iRunningAtMin = iRunningTransactions;\r
429                                             }\r
430                                         }\r
431                                     }\r
432                                     lock (oTransCounterLock)\r
433                                     {\r
434                                         if (iRunningTransactions > iMaxRunning)\r
435                                         {\r
436                                             iMaxRunning = iRunningTransactions;\r
437                                         }\r
438                                         iCompletedTransactions++;\r
439                                         aTransactionTimeArray[iTransactionTimeIndex] = transactionDuration.TotalMilliseconds;\r
440                                         iTransactionTimeIndex++;\r
441                                         iRunningTransactions--;\r
442                                     }\r
443                                 }\r
444                                 else\r
445                                 {\r
446                                     if (iLogLevel > 1)\r
447                                     {\r
448                                         Info("Client " + iThread.ToString() + " Transaction = " + iTransOn + " Skipping as random transaction = true", iLogLevel, bVerboseScreen);\r
449                                     }\r
450                                 }\r
451                             }\r
452 \r
453                             lock (oIterationCounterLock)\r
454                             {\r
455                                 iCompletedIterations++;\r
456                             }\r
457 \r
458                             if (bConnPerIteration)\r
459                             {\r
460                                 if (sMode == "pgsql")\r
461                                 {\r
462                                     conn.Close();\r
463                                 }\r
464                                 else if (sMode == "mssql")\r
465                                 {\r
466                                     msconn.Close();\r
467                                 }\r
468                             }\r
469                             \r
470                             DateTime stopTime = DateTime.Now;\r
471                             TimeSpan duration = stopTime - startTime;\r
472                             Info("Client " + iThread.ToString() + " Iteration " + i.ToString() + " Iteration Time " + duration.TotalMilliseconds + " ms (including application read)", iLogLevel, bVerboseScreen);\r
473 \r
474                     }\r
475                     catch (Exception e)\r
476                     {\r
477                         if (String.Compare(e.Message, 0, "A timeout has occured", 0, 21) == 0)\r
478                         {\r
479                             iConnectionTimeouts++;\r
480                         }\r
481                         else if (String.Compare(e.Message, 0, "Failed to establish a connection", 0, 32) == 0)\r
482                         {\r
483                             iConnectionFailure++;\r
484                         }\r
485                         else if ((e.Message == "ERROR: 08P01: no more connections allowed") || (e.Message == "FATAL: 53300: connection limit exceeded for non-superusers") || (e.Message == "FATAL: 53300: sorry, too many clients already"))\r
486                         {\r
487                             iConnectionCeilingHit++;\r
488                         }\r
489                         else\r
490                         {\r
491                             iFailure++;\r
492                         }\r
493                         Info("Client " + iThread.ToString() + " Iteration " + i.ToString() + " FAILURE " + e.Message + " TARGET " + e.TargetSite + " INFO = " + e.ToString(), iLogLevel, bVerboseScreen);\r
494                         if (bOnFailureRetry)\r
495                         {\r
496                             i--;\r
497                             iConnectionRetries++;\r
498                             continue;\r
499                         }\r
500 \r
501                     }\r
502                     if (iSleepTime > 0)\r
503                     {\r
504                         Thread.Sleep(iSleepTime);\r
505                     }\r
506                 }\r
507                 if (!bConnPerIteration)\r
508                 {\r
509                     conn.Close();\r
510                 }\r
511         }\r
512 \r
513         public static void Info(string sInfoText, int iInfoLevel, bool bScreen)\r
514         {\r
515             if (iInfoLevel >= 1)\r
516             {\r
517                 AddLog(sInfoText);      \r
518             }\r
519             if (bScreen)\r
520             {\r
521                 Console.WriteLine(sInfoText);\r
522             }\r
523         }\r
524 \r
525         public static void AddLog(string sLogText)\r
526         {\r
527             DateTime currTime = DateTime.Now;\r
528 \r
529             if (sLogText.Length != 0)\r
530             {\r
531                 lock (oLogLock)\r
532                 {\r
533                     aLogArray[iLogIndex] = currTime.ToString(timeStamp) + " : " + sLogText;\r
534                     iLogIndex++;\r
535                 }\r
536             }\r
537         }\r
538 \r
539         public static void LogWriter()\r
540         {\r
541             if ((sLogFile != "") && (iLogLevel >=1))\r
542             {\r
543                 FileStream fs = new FileStream(sLogFile, FileMode.OpenOrCreate, FileAccess.Write);\r
544                 StreamWriter m_streamWriter = new StreamWriter(fs);\r
545                 m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);\r
546 \r
547                 for (int i = 0; i < iLogIndex; i++)\r
548                 {\r
549                     m_streamWriter.WriteLine(aLogArray[i]);\r
550                 }\r
551 \r
552                 m_streamWriter.Flush();\r
553                 m_streamWriter.Close();\r
554             }\r
555         }\r
556 \r
557         public static void CsvLogWriter(string sLogText)\r
558         {\r
559             bool bWriteHeader = false;\r
560 \r
561             if (sCsvLogFile != "")\r
562             {\r
563                 if (!File.Exists(sCsvLogFile))\r
564                 {\r
565                     bWriteHeader = true;\r
566                 }\r
567 \r
568                 FileStream fs = new FileStream(sCsvLogFile, FileMode.OpenOrCreate, FileAccess.Write);\r
569                 StreamWriter m_streamWriter = new StreamWriter(fs);\r
570                 m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);\r
571 \r
572                 if (bWriteHeader)\r
573                 {\r
574                     m_streamWriter.WriteLine("Server name, Clients, Iterations/client, Max transaction duration (ms), Min transaction duration (ms), Concurrent transactions at max duration, Concurrent transactions at min duration, Mean transaction duration (ms), Transaction duration standard deviation (ms), tps, qps, Max concurrent transactions, Total time (s), Avg CPU Time %");\r
575                 }\r
576                 m_streamWriter.WriteLine(sLogText);\r
577 \r
578                 m_streamWriter.Flush();\r
579                 m_streamWriter.Close();\r
580             }\r
581         }\r
582 \r
583         public static XmlDocument readTransactionsFile(string sTransactionsFile)\r
584         {\r
585             DataSet ds = new DataSet();\r
586             XmlDocument transfile = new XmlDocument();\r
587             try\r
588             {\r
589                 transfile.Load(sTransactionsFile);\r
590             }\r
591             catch (Exception e)\r
592             {\r
593                 Info("Error reading transaction file " + e.ToString(), iLogLevel, bVerboseScreen);\r
594             }\r
595             return transfile;\r
596         }\r
597     }\r
598        \r
599 }\r