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