You might get java.lang.OutOfMemory error in IBM HeapAnalyzer while processing heapdumps.
Try increasing the JVM heap size and see whether it fixes your OutOfMemory issue before trying other options.
Following is how you invoke HeapAnalyzer with a heap size parameter in windows.
Finally if your OutOfMemory Issue is fixed, you should able to see the heap dump analysis in HeapAnalyzer.
Friday, October 5, 2012
Thursday, October 4, 2012
Chrome About URL
I was playing around with Chrome's about feature few days ago but forgot the actual URL. Therefore this post is to remind me the actual URL.
The URL is chrome://about/.
There are some useful URLs to know in the list and they are:
- chrome://dns/
- chrome://tracing/
- chrome://profiler/
- chrome://net-internals/
- chrome://memory-redirect/
- chrome://flags/
Tuesday, September 18, 2012
Copying parameters in LoadRunner
Scenario:
You are using same parameter(s) in more than one script and you don't want to manually create them again for each script. So how do you go about copying the parameters from an existing script.
For example:
The following parameters have already been manually created in Script 1 and same parameters are also required for Script 2.
Rather than manually creating them, you can copy these parameters from Script 1 and this is how you do it.
Steps:
1: Navigate to Script 1 folder and open file that ends with "prm" extension. This file defines all the parameters and their attributes.
2: Copy the parameters & their attributes and paste into the parameter file of script 2.
3: Save the parameter file. Now open script 2 and navigate to parameter list. You will now noticed that the parameters have been successfully copied.
You are using same parameter(s) in more than one script and you don't want to manually create them again for each script. So how do you go about copying the parameters from an existing script.
For example:
The following parameters have already been manually created in Script 1 and same parameters are also required for Script 2.
- DateTime
- IterationNo
- RandNo
- VuserID
Rather than manually creating them, you can copy these parameters from Script 1 and this is how you do it.
Steps:
1: Navigate to Script 1 folder and open file that ends with "prm" extension. This file defines all the parameters and their attributes.
2: Copy the parameters & their attributes and paste into the parameter file of script 2.
3: Save the parameter file. Now open script 2 and navigate to parameter list. You will now noticed that the parameters have been successfully copied.
Saturday, September 8, 2012
Generating UUID in Loadrunner
There have been multiple times where I needed to generate UUID (Verion 4) in Loadrunner but there is no inbuild function to do so. Therefore, I had to either create or modify functions to satisfy my need.
NOTE: Loadrunner does have a function(lr_generate_uuid) for UUID but it does not generate your standard UUID.
Below are three different UUID functions that I normally use depending on the requirement.
For example, If only requirement is that UUID be 32 hexadecimal digits then I will use simple LR UUID to generate it. If there are proper checks in place to see the UUID generated is valid then I will use a proper UUID function's. Therefore you can select which one you want to use depending on your requirement.
Simple UUID - this is a simple 32 hexadecimal digits. You can generate hexaadecimal in Loadrunner using %x or %X Random number.
Following screenshot shows how to generate a random Hexadecimal.
Lr UUID - this function generates 32 hexadecimal digits UUID using Version 4(random) variant. This is the most common format I have seen applications use.
Win UUID - this function uses windows inbuild CoCreateGuid function (ole32.dll). The original code is written by Scott Moore and I have modified it a little bit.
Output:
If you have a different function to generate UUID in Loadrunner, I would love to know about it.
NOTE: Loadrunner does have a function(lr_generate_uuid) for UUID but it does not generate your standard UUID.
Below are three different UUID functions that I normally use depending on the requirement.
For example, If only requirement is that UUID be 32 hexadecimal digits then I will use simple LR UUID to generate it. If there are proper checks in place to see the UUID generated is valid then I will use a proper UUID function's. Therefore you can select which one you want to use depending on your requirement.
Simple UUID - this is a simple 32 hexadecimal digits. You can generate hexaadecimal in Loadrunner using %x or %X Random number.
Following screenshot shows how to generate a random Hexadecimal.
Lr UUID - this function generates 32 hexadecimal digits UUID using Version 4(random) variant. This is the most common format I have seen applications use.
Win UUID - this function uses windows inbuild CoCreateGuid function (ole32.dll). The original code is written by Scott Moore and I have modified it a little bit.
NOTE: I have left the deallocation of pointer for you to do in the code.
#define Hexlength 50 //Max length char *lr_guid_gen(); //explicitely declare the function char *lr_uuid_gen(); //explicitely declare the function Action() { char *Win_UUID=0; //declare window function UUID variable char *slr_UUID=0; //declare loadrunner function UUID variable char *lr_uuid; //declare UUID variable Win_UUID=(char *)malloc(sizeof(char)); //allocate dynamic memory slr_UUID=(char *)malloc(sizeof(char)); //allocate dynamic memory Win_UUID=lr_guid_gen(); //execute Window UUID function slr_UUID=lr_uuid_gen(); //execute LR UUID function lr_uuid=lr_generate_uuid(); //assign result generated by loadrunner internal function to lr_uuid /*output a simple UUID*/ lr_output_message("smp_UUID: %s",lr_eval_string("{sHex}{sHex}-{sHex}-{sHex}-{sHex}-{sHex}{sHex}{sHex}")); //you could use something like this as well -> lr_output_message("smp_UUID: %s",lr_eval_string("{sHex}{sHex}-{sHex}-{FourHex}-{sHex}-{sHex}{sHex}{sHex}")); /*output loadrunner UUID*/ lr_output_message("slr_UUID: %s",lr_eval_string(slr_UUID)); /*output window generated UUID*/ lr_output_message("Win_UUID: %s",lr_eval_string(Win_UUID)); /*output base64 UUID*/ lr_output_message("%s",lr_uuid); /*frees uuid created by lr_generarte_uuid*/ lr_generate_uuid_free(lr_uuid); return 0; } /*This function uses windows ole32 CoCreateGuid function to generate UUID*/ char *lr_guid_gen() { typedef struct _GUID { unsigned long Data1; unsigned short Data2; unsigned short Data3; unsigned char Data4[4]; } GUID; char guid[Hexlength]; GUID m_guid; lr_load_dll ("ole32.dll"); CoCreateGuid(&m_guid); sprintf (guid, "%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", m_guid.Data1, m_guid.Data2, m_guid.Data3, m_guid.Data4[0], m_guid.Data4[1], m_guid.Data4[2], m_guid.Data4[3], m_guid.Data4[4], m_guid.Data4[5], m_guid.Data4[6], m_guid.Data4[7]); return guid; } /*This function uses loadrunner random numbers to generate version 4 UUID*/ char *lr_uuid_gen() { char uuid[Hexlength]; switch (atoi(lr_eval_string("{RandNo}"))) { case 1: sprintf(uuid,lr_eval_string("{Hex}{Hex}-{Hex}-{FourHex}-{aHex}-{Hex}{Hex}{Hex}")); break; case 2: sprintf(uuid,lr_eval_string("{Hex}{Hex}-{Hex}-{FourHex}-{bHex}-{Hex}{Hex}{Hex}")); break; case 3: sprintf(uuid,lr_eval_string("{Hex}{Hex}-{Hex}-{FourHex}-{EightHex}-{Hex}{Hex}{Hex}")); break; case 4: sprintf(uuid,lr_eval_string("{Hex}{Hex}-{Hex}-{FourHex}-{NineHex}-{Hex}{Hex}{Hex}")); break; default: break; } return uuid; }
Output:
Action.c(23): smp_UUID: 492ec6db-dcaf-fb6d-1009-72a542e26ee7 Action.c(26): slr_UUID: c4fbde14-4f41-4963-8400-32f77f6e0633 Action.c(29): Win_UUID: cee9f8fd-3715-4183-b367-a4c13b84a7c8 Action.c(32): LBase_64: J3+Lpj2t20KzpBSgg0e5Bg== Action.c(23): smp_UUID: 65ea1bc1-8434-e05b-92f5-7e23a0f7e253 Action.c(26): slr_UUID: 358390f7-2405-4b03-8be4-b8c61b90a2b6 Action.c(29): Win_UUID: 75d74eb9-a2bf-42b4-b114-61d634a2c7db Action.c(32): LBase_64: uzxvhpLXP0ifUjMSqzngCQ== Action.c(23): smp_UUID: 0a86ce02-7413-1da3-bd39-63fc4cb9d60e Action.c(26): slr_UUID: 726546c5-500d-4ef2-a27e-f447bb925143 Action.c(29): Win_UUID: db65a02f-1ca1-4fb3-ab22-0e41088b1633 Action.c(32): LBase_64: IJV65qREQUOe5CVwcE5aVQ== Action.c(23): smp_UUID: 6678a6ac-3356-eb2f-63e6-02fe5a5185f2 Action.c(26): slr_UUID: acddc8f9-746d-4655-838c-7802483e06bb Action.c(29): Win_UUID: e7a7ff1c-4019-4053-a51a-7567582d825c Action.c(32): LBase_64: i+b5VpgA7Ueis8r1bxBTJg== Action.c(23): smp_UUID: 3f8eb05e-9936-b5fc-6be9-454fd8fb9ab5 Action.c(26): slr_UUID: cc835158-9e86-4df5-8a4e-1e3f25808754 Action.c(29): Win_UUID: 3d604abe-046b-43dc-a5c4-e759fb04f960 Action.c(32): LBase_64: Rk2mSYUuOUmU0Yti_W+a5Q==
If you have a different function to generate UUID in Loadrunner, I would love to know about it.
Thursday, June 7, 2012
Plagiarizing someone else experience
Whenever I get a "Join my network on LinkediIn" message from someone on LinkedIn, I always try to view their profile before accepting it. This is because I just like to know a little bit more about them.
Recently, I received a join message from Manish Sinha(works for Accenture(Bengaluru - India) as a performance test lead) and as always, before accepting it, I viewed his profile and what I found was bit of a surprise. He was plagiarizing someone else experience on his profile as his own and guess what, that was my experience he was plagiarizing.
I emailed him couple of times to remove the experience from his profile but so far no luck. Therefore, I thought, I blog about it.
His Experience as ASc Consultant at Capgemini.
Can you see the similarity with my experience.
Recently, I received a join message from Manish Sinha(works for Accenture(Bengaluru - India) as a performance test lead) and as always, before accepting it, I viewed his profile and what I found was bit of a surprise. He was plagiarizing someone else experience on his profile as his own and guess what, that was my experience he was plagiarizing.
I emailed him couple of times to remove the experience from his profile but so far no luck. Therefore, I thought, I blog about it.
His Experience as ASc Consultant at Capgemini.
Can you see the similarity with my experience.
Friday, June 1, 2012
Publishing result in Silkperformer
SilkPerformer reports percentiles in a different section than the main table and it can be time consuming, if you want to publish all the metrics in a single table. Therefore to solve this issue, a colleague (Murray Wardle) of mine wrote a visual basic script that generates a table with all the metrics.
He has kindly allowed me to share it here and below is his description on how to use it.
NOTE: You are allowed to use the code as long as you acknowledge the author.
Example:
1: Save the above code as a visual basic script into a folder. Lets call this script as "ExtractOverviewReportData.vbs".
2: Navigate to you SilkPerformer project and copy OverviewReport.xml into the folder where you have saved vbs script. See the screenshot below.
When you open the xml file, it would look something like this:
4: Now open up the csv file in excel and you should have all the necessary metric. You will see something like this:
He has kindly allowed me to share it here and below is his description on how to use it.
"Publishing results from SilkPerformer can sometimes be very time consuming. Most projects will have requirements involving the 90th or 95th percentiles and for some reason SilkPerformer reports percentiles in a different section of the report and not in the main table I wish to publish.
Generally in my scripts I’ll use Timers for measuring response times (I’m not too keen of the automatic page and form timers) for timers controlled with the MeasureStart() and MeasureStop() functions, Inserting the following into the TInit will enable percentiles to be calculated for the Timers.
MeasureCalculatePercentiles(NULL,MEASURE_TIMER_RESPONSETIME);
Unfortunately percentiles are displayed in a different section of the report to the Min, Avg, Max, StdDev, Count, and it’s a waste of time trying to copy and paste the values into a spreadsheet.
So, here is a simple little script which does the work. Just drag and drop the OverviewReport.xml file onto the script and it will create a csv file with the following:
ScriptName, TimerName, Min, Avg, Max, StDev, Count, 50th Perc, 90th Perc, 95th Perc, 99th Perc"
Generally in my scripts I’ll use Timers for measuring response times (I’m not too keen of the automatic page and form timers) for timers controlled with the MeasureStart() and MeasureStop() functions, Inserting the following into the TInit will enable percentiles to be calculated for the Timers.
MeasureCalculatePercentiles(NULL,MEASURE_TIMER_RESPONSETIME);
Unfortunately percentiles are displayed in a different section of the report to the Min, Avg, Max, StdDev, Count, and it’s a waste of time trying to copy and paste the values into a spreadsheet.
So, here is a simple little script which does the work. Just drag and drop the OverviewReport.xml file onto the script and it will create a csv file with the following:
ScriptName, TimerName, Min, Avg, Max, StDev, Count, 50th Perc, 90th Perc, 95th Perc, 99th Perc"
NOTE: You are allowed to use the code as long as you acknowledge the author.
'Copyright (c) 2012 Murray Wardle, murray.wardle@advancedperformance.com.au 'Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sub license, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 'The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 'THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Option Explicit Dim xmlDoc Dim scriptName, scriptNodes, SNode, TNode, timerNodes, timerName Dim reportFile, outputFile Dim myFSO, fileHandle Dim min, avg, max, stDev, count, p50, p90, p95, p99 Set xmlDoc = CreateObject("Microsoft.XMLDOM") Const ForReading = 1, ForWriting = 2, ForAppending = 8 If Wscript.Arguments.Count = 0 Then msgbox "Please specify the overview Report file to process" Else ' Get report file name & set output filename reportFile = Wscript.Arguments(0) outputFile = Left(reportFile, Len(reportFile)-3) + "csv" xmlDoc.async = false xmlDoc.SetProperty "SelectionLanguage", "XPath" xmlDoc.SetProperty "ServerHTTPRequest", True xmlDoc.validateOnParse = False xmlDoc.resolveExternals = False 'load overview report xmlDoc.load(reportFile) xmlDoc.setProperty "SelectionLanguage", "XPath" 'open csv file to dump results into Set myFSO = CreateObject("Scripting.FileSystemObject") Set fileHandle = myFSO.OpenTextFile(outputFile, ForWriting, True) fileHandle.WriteLine("Script,Timer,Min,Avg,Max,StDev,Count,50th Perc,90th Perc,95th Perc,99th Perc") 'For each script Set scriptNodes = xmlDoc.selectNodes("/Overview_Report_Data/UserGroups/Group") For Each SNode in scriptNodes scriptName = SNode.SelectSingleNode("Name").text 'For each measure of type Timer Set timerNodes = SNode.selectNodes("Measures/Measure") For Each TNode in timerNodes If TNode.SelectSingleNode("Class").text = "Timer" then ' Extract the timer data timerName = TNode.SelectSingleNode("Name").text min = TNode.SelectSingleNode("MinMin").text avg = TNode.SelectSingleNode("Avg").text max = TNode.SelectSingleNode("MaxMax").text stDev = TNode.SelectSingleNode("Stdd").text count = TNode.SelectSingleNode("SumCount2").text p50 = TNode.SelectSingleNode("Percentiles/Values/Value[1]/Value").text p90 = TNode.SelectSingleNode("Percentiles/Values/Value[2]/Value").text p95 = TNode.SelectSingleNode("Percentiles/Values/Value[3]/Value").text p99 = TNode.SelectSingleNode("Percentiles/Values/Value[4]/Value").text 'Write to File fileHandle.WriteLine(scriptName+","+timerName+","+min+","+avg+","+max+","+stDev+","+count+","+p50+","+p90+","+p95+","+p99) end if Next 'TNode in timerNodes Next 'SNode in scriptNodes fileHandle.Close End If
Example:
1: Save the above code as a visual basic script into a folder. Lets call this script as "ExtractOverviewReportData.vbs".
2: Navigate to you SilkPerformer project and copy OverviewReport.xml into the folder where you have saved vbs script. See the screenshot below.
When you open the xml file, it would look something like this:
3:Now drag and drop the OverviewReport.xml file onto the script and it will create a csv file.1.100000000 ABCDEFG ForMyBlog.tsd (D:\Silkperformer_Projects\ABCDEF\) Silk Performance Explorer Monday, 20 April 2012 - 3:00:00 AM 1 ... Header ABCD 8 None 1 28/05/2012 1:00:12 AM 6280.000000000 4 Merged MPPO SVT 23 ... Timer #Overall Response Time# Response time[s] Seconds 0.000000000 0.000000000 3 2 Response time[s] 200.000000000 100.000000000 830.000000000 35000.000000000 0.500000000 60.00000000 6.412345678 11.123456789 0.000000000 00.000000000 00 0 50 1.123456789 90 22.123456789 95 60.00000000 99 60.00000000
4: Now open up the csv file in excel and you should have all the necessary metric. You will see something like this:
Monday, May 21, 2012
Querying and Inserting records into MongoDB using LoadRunner
This simple LR script inserts and retrieves a record from mongoDB. You can modify it to accommodate your own need.
Requirement:
Download Java driver for mongoDB and add it to the classpath in the java script.
mongoDB output:
Requirement:
Download Java driver for mongoDB and add it to the classpath in the java script.
import java.lang.String; import java.net.UnknownHostException; import java.util.Set; import com.mongodb.BasicDBObject; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBCursor; import com.mongodb.DBObject; import com.mongodb.Mongo; import com.mongodb.MongoException; import lrapi.lr; public class Actions { static String HostName ="localhost"; static Integer Port = 27017; static String Username ="Harinder"; static String Password ="Password"; Mongo mDB; DB db; public int init() throws Throwable{ try { mDB= new Mongo( HostName , Port ); //connect to MongoDB using HostName and Port db = mDB.getDB("test"); // get test database from MongoDB boolean auth = db.authenticate(Username, Password.toCharArray()); //authenticate user access to test database if (auth = true) lr.output_message("Successfully Authenticated"); else lr.output_message("Incorrect Username/Password"); }catch (UnknownHostException e) { e.printStackTrace(); } return 0; }//end of init function public int action() throws Throwable { try { InsertInToMongoDB("Harinder1", "Seera1", "ThisIsMongoDB1@gmail.com"); }catch (MongoException e){ e.printStackTrace(); } try { SearchMongoDB("Harinder"); }catch (MongoException e){ e.printStackTrace(); } return 0; }//end of action function public int end() throws Throwable { mDB.close(); return 0; }//end of end function public void InsertInToMongoDB(String FirstName, String LastName, String Email) { // Get collection from mongoDB. // If collection doesn't exist, mongoDB will create it automatically DBCollection collection = db.getCollection("MyCollection"); BasicDBObject document = new BasicDBObject(); // create a document to store key and value document.put("FirstName",FirstName); document.put("LastName", LastName); document.put("Email", Email); collection.insert(document); //save the document into collection } public void SearchMongoDB(String FirstName) { DBCollection collection = db.getCollection("MyCollection"); BasicDBObject srchQuery = new BasicDBObject(); // search query srchQuery.put("FirstName", FirstName); DBCursor cur = collection.find(srchQuery); // query it // loop over the cursor and display the retrieved result while (cur.hasNext()) { System.out.println(cur.next()); //I am using it only for the blog purpose to show the output. } } }
mongoDB output:
Sunday, April 1, 2012
How to alter "System" password in Oracle database express edition
Oracle database express edition is installed as part of OATS(Oracle Application Testing Suite) installation and during installation, I don't recall been asked to setup database administrator username and password, which is required to login to the Database Home page. However, you can login as a "SYSTEM" user but before that, you will need to setup the password for this user. Sorry, don't know the default password for "SYSTEM" user.
Following steps show how to setup the password for “SYSTEM” user.
NOTE: This was tested on Windows 7.
1: Make sure the database service is running. This can be checked by running "Start Database" option. If it is running, you will see following output.
2: Type following commands to connect to the database without using password.
3: Type in the following command to change the password.
alter user {username} identified by {password};
Example:
4: Now you should be able to login to Database homepage as "system" user with the new password.
Following steps show how to setup the password for “SYSTEM” user.
NOTE: This was tested on Windows 7.
1: Make sure the database service is running. This can be checked by running "Start Database" option. If it is running, you will see following output.
2: Type following commands to connect to the database without using password.
sqlplus /nolog connect / as sysdbaNow you are connected as "SYSTEM" user with full DBA rights. Therefore, you can go ahead and change the password of "SYSTEM" user.
3: Type in the following command to change the password.
alter user {username} identified by {password};
Example:
alter user system identified by oatsystem;
4: Now you should be able to login to Database homepage as "system" user with the new password.
Saturday, March 24, 2012
How to save mongoDB server status into a file
MongoDB serverStatus command provides a useful information about mongod instance. This information includes fields such as mem.virtual, globalLock.currentQueue.writers, extra_info.page_faults. This information can be accessed by executing db.serverStatus() command from the shell.
If you want to save the above result into a file, you can do as follows:
You can also execute the same using javascript file as an argument. The advantage of this approach is that you can have multiple commands in the file.
Example of Javascript file:
Output example:
If you want to save the above result into a file, you can do as follows:
>mongo --eval "printjson(db.serverStatus())" >>{outfile path} e.g. >mongo --eval "printjson(db.serverStatus())" >>C:\harinder\log.txt
You can also execute the same using javascript file as an argument. The advantage of this approach is that you can have multiple commands in the file.
>mongo <{Javascript path} >>{Outfile path} e.g. >mongo < C:\harinder\mongo.js >>C:\harinder\log.txt
Example of Javascript file:
db.getProfilingLevel() db.getLastError() db.foo.find()
Output example:
MongoDB shell version: 2.0.4 connecting to: test > 0 > null > { "_id" : ObjectId("4f6e92311c7ef28999436998"), "a" : 1 } > bye
Thursday, March 8, 2012
Saving vmstat with timestamp into a file on Redhat Linux Machine
By default vmstat output doesnot include timestamp and therefore, if you want to save it with the timestamp into a file on Redhat Linux machine, you can use following command.
$vmstat -n [delay [count]] | awk '{now=strftime("%Y-%m-%d %T "); print now $0}'>{file path}
e.g. vmstat -n 1 30 | awk '{now=strftime("%Y-%m-%d %T "); print now $0}'>/tmp/vmstat.txt
where:
Final result:
$vmstat -n [delay [count]] | awk '{now=strftime("%Y-%m-%d %T "); print now $0}'>{file path}
e.g. vmstat -n 1 30 | awk '{now=strftime("%Y-%m-%d %T "); print now $0}'>/tmp/vmstat.txt
where:
- n -> display vmstat header once
- 1 -> update vmstat every second
- 30 ->only display 30 records
- awk '{now=strftime("%Y-%m-%d %T "); print now $0}' -> print timestamp
- >/tmp/vmstat.txt -> path where the vmstat is saved
Final result:
2012-03-09 12:05:25 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------ 2012-03-09 12:05:25 r b swpd free buff cache si so bi bo in cs us sy id wa st 2012-03-09 12:05:25 1 0 0 23199964 473756 6719956 0 0 0 2 0 0 0 0 100 0 0 2012-03-09 12:05:26 0 0 0 23199964 473756 6719956 0 0 0 0 118 232 0 0 100 0 0 2012-03-09 12:05:27 0 0 0 23199964 473756 6719956 0 0 0 0 123 260 0 0 100 0 0 2012-03-09 12:05:28 0 0 0 23199964 473756 6719956 0 0 0 0 111 234 0 0 100 0 0 2012-03-09 12:05:29 0 0 0 23199964 473756 6719956 0 0 0 0 133 276 0 0 100 0 0 2012-03-09 12:05:30 1 0 0 23200088 473756 6719956 0 0 0 88 115 263 0 0 100 0 0 2012-03-09 12:05:31 1 0 0 23200088 473756 6719956 0 0 0 12 135 251 0 0 100 0 0 2012-03-09 12:05:32 0 0 0 23200088 473756 6719964 0 0 0 0 113 313 0 0 100 0 0 2012-03-09 12:05:33 0 0 0 23200088 473756 6719964 0 0 0 0 127 270 0 0 100 0 0 2012-03-09 12:05:34 0 0 0 23200088 473756 6719964 0 0 0 0 110 271 0 0 100 0 0 2012-03-09 12:05:35 1 0 0 23200088 473756 6719964 0 0 0 0 142 297 0 0 100 0 0 2012-03-09 12:05:36 0 0 0 23200088 473756 6719964 0 0 0 44 127 264 0 0 100 0 0 2012-03-09 12:05:37 0 0 0 23200088 473756 6719968 0 0 0 12 144 349 0 0 100 0 0 2012-03-09 12:05:38 0 0 0 23200088 473756 6719928 0 0 0 0 143 259 0 0 100 0 0 2012-03-09 12:05:39 0 0 0 23200088 473756 6719928 0 0 0 0 137 273 0 0 100 0 0 2012-03-09 12:05:40 0 0 0 23200088 473756 6719928 0 0 0 0 123 252 0 0 100 0 0 2012-03-09 12:05:41 0 0 0 23200088 473756 6719928 0 0 0 104 198 269 0 0 100 0 0 2012-03-09 12:05:42 0 0 0 23200088 473756 6719928 0 0 0 0 166 280 0 0 100 0 0 2012-03-09 12:05:43 0 0 0 23200088 473756 6719928 0 0 0 0 183 322 0 0 100 0 0 2012-03-09 12:05:44 0 0 0 23200088 473756 6719932 0 0 0 0 205 330 0 0 100 0 0 2012-03-09 12:05:45 0 0 0 23200088 473756 6719932 0 0 0 0 157 260 0 0 100 0 0 2012-03-09 12:05:46 0 0 0 23200088 473756 6719932 0 0 0 0 112 219 0 0 100 0 0 2012-03-09 12:05:47 0 0 0 23200088 473756 6719932 0 0 0 52 144 304 0 0 100 0 0 2012-03-09 12:05:48 0 0 0 23200088 473756 6719932 0 0 0 0 117 230 0 0 100 0 0 2012-03-09 12:05:49 0 0 0 23200088 473756 6719932 0 0 0 0 139 280 0 0 100 0 0 2012-03-09 12:05:50 0 0 0 23200088 473756 6719932 0 0 0 0 126 241 0 0 100 0 0 2012-03-09 12:05:51 0 0 0 23200088 473756 6719932 0 0 0 0 129 243 0 0 100 0 0 2012-03-09 12:05:52 0 0 0 23200088 473756 6719932 0 0 0 0 111 237 0 0 100 0 0 2012-03-09 12:05:53 0 0 0 23200088 473756 6719932 0 0 0 32 132 265 0 0 100 0 0 2012-03-09 12:05:54 0 0 0 23200088 473756 6719932 0 0 0 16 119 260 0 0 100 0 0
Saturday, March 3, 2012
Runtime Statistics in CouchDB
CouchDB is an open source document-oriented database. More information on CouchDB is available here.
CouchDB 0.9 and above comes with a list of counters that lets you inspect how CouchDB performs. On windows (local machine where CouchDB is installed), you can view these counters by navigating to the following URL: http://localhost:5984/_stats. More information is available here.
The information returned is in JSON format. There are free tools and websites available to display the stats in a more user friendly format.
Group | Key | Description |
---|---|---|
Couchdb | database_writes | Number of times a database was changed |
open_databases | Number of open databases | |
auth_cache_hits | Number of authentication cache hits | |
auth_cache_misses | Number of authentication cache misses | |
database_reads | Number of times a document was read from a database | |
request_time | Length of a request inside CouchDB without MochiWeb | |
open_os_files | Number of file descriptors CouchDB has open | |
httpd | Requests | Number of HTTP requests |
bulk_requests | Number of bulk requests | |
view_reads | Number of view reads | |
clients_requesting_changes | Number of clients for continuous _changes | |
temporary_view_reads | Number of temporary view reads | |
httpd_request_methods | DELETE | Number of HTTP DELETE requests |
HEAD | Number of HTTP HEAD requests | |
POST | Number of HTTP POST requests | |
PUT | Number of HTTP PUT requests | |
GET | Number of HTTP GET requests | |
COPY | Number of HTTP COPY requests | |
httpd_status_codes | 400 | Number of HTTP 400 Bad Request responses |
201 | Number of HTTP 201 Created responses | |
403 | Number of HTTP 403 Forbidden responses | |
409 | Number of HTTP 409 Conflict responses | |
200 | Number of HTTP 200 OK responses | |
202 | Number of HTTP 202 Accepted responses | |
404 | Number of HTTP 404 Not Found responses | |
301 | Number of HTTP 301 Moved Permanently responses | |
405 | Number of HTTP 405 Method Not Allowed responses | |
500 | Number of HTTP 500 Internal Server Error responses | |
401 | Number of HTTP 401 Unauthorized responses | |
304 | Number of HTTP 304 Not Modified responses | |
412 | Number of HTTP 412 Precondition Failed responses |
Below is a formated JSON output example:
{ "couchdb" : { "auth_cache_hits" : { "current" : 2089.0, "description" : "number of authentication cache hits", "max" : 222, "mean" : 0.83199999999999996, "min" : 0, "stddev" : 10.222, "sum" : 2089.0 }, "auth_cache_misses" : { "current" : 12.0, "description" : "number of authentication cache misses", "max" : 3, "mean" : 0.0050000000000000001, "min" : 0, "stddev" : 0.113, "sum" : 12.0 }, "database_reads" : { "current" : 643.0, "description" : "number of times a document was read from a database", "max" : 131, "mean" : 0.25700000000000001, "min" : 0, "stddev" : 4.1050000000000004, "sum" : 643.0 }, "database_writes" : { "current" : 205.0, "description" : "number of times a database was changed", "max" : 28, "mean" : 0.082000000000000003, "min" : 0, "stddev" : 1.056, "sum" : 205.0 }, "open_databases" : { "current" : 10.0, "description" : "number of open databases", "max" : 7, "mean" : 0.0040000000000000001, "min" : -5, "stddev" : 0.21099999999999999, "sum" : 10.0 }, "open_os_files" : { "current" : 10.0, "description" : "number of file descriptors CouchDB has open", "max" : 7, "mean" : 0.0040000000000000001, "min" : -5, "stddev" : 0.28699999999999998, "sum" : 10.0 }, "request_time" : { "current" : 13881.477999999999, "description" : "length of a request inside CouchDB without MochiWeb", "max" : 12043.0, "mean" : 115.679, "min" : 0.0, "stddev" : 1098.511, "sum" : 13881.477999999999 } }, "httpd" : { "bulk_requests" : { "current" : 27.0, "description" : "number of bulk requests", "max" : 10, "mean" : 0.010999999999999999, "min" : 0, "stddev" : 0.253, "sum" : 27.0 }, "clients_requesting_changes" : { "current" : null, "description" : "number of clients for continuous _changes", "max" : null, "mean" : null, "min" : null, "stddev" : null, "sum" : null }, "requests" : { "current" : 2395.0, "description" : "number of HTTP requests", "max" : 221, "mean" : 0.95299999999999996, "min" : 0, "stddev" : 10.359999999999999, "sum" : 2395.0 }, "temporary_view_reads" : { "current" : 92.0, "description" : "number of temporary view reads", "max" : 33, "mean" : 0.036999999999999998, "min" : 0, "stddev" : 0.94199999999999995, "sum" : 92.0 }, "view_reads" : { "current" : 144.0, "description" : "number of view reads", "max" : 37, "mean" : 0.058000000000000003, "min" : 0, "stddev" : 1.1579999999999999, "sum" : 144.0 } }, "httpd_request_methods" : { "COPY" : { "current" : 1.0, "description" : "number of HTTP COPY requests", "max" : 1, "mean" : 0.0, "min" : 0, "stddev" : 0.02, "sum" : 1.0 }, "DELETE" : { "current" : 187.0, "description" : "number of HTTP DELETE requests", "max" : 81, "mean" : 0.074999999999999997, "min" : 0, "stddev" : 1.6919999999999999, "sum" : 187.0 }, "GET" : { "current" : 1672.0, "description" : "number of HTTP GET requests", "max" : 222, "mean" : 0.66600000000000004, "min" : 0, "stddev" : 9.1310000000000002, "sum" : 1672.0 }, "HEAD" : { "current" : null, "description" : "number of HTTP HEAD requests", "max" : null, "mean" : null, "min" : null, "stddev" : null, "sum" : null }, "POST" : { "current" : 190.0, "description" : "number of HTTP POST requests", "max" : 35, "mean" : 0.075999999999999998, "min" : 0, "stddev" : 1.1719999999999999, "sum" : 190.0 }, "PUT" : { "current" : 345.0, "description" : "number of HTTP PUT requests", "max" : 85, "mean" : 0.13700000000000001, "min" : 0, "stddev" : 2.1110000000000002, "sum" : 345.0 } }, "httpd_status_codes" : { "200" : { "current" : 1734.0, "description" : "number of HTTP 200 OK responses", "max" : 221, "mean" : 0.68999999999999995, "min" : 0, "stddev" : 9.2690000000000001, "sum" : 1734.0 }, "201" : { "current" : 245.0, "description" : "number of HTTP 201 Created responses", "max" : 31, "mean" : 0.098000000000000004, "min" : 0, "stddev" : 1.2170000000000001, "sum" : 245.0 }, "202" : { "current" : 3.0, "description" : "number of HTTP 202 Accepted responses", "max" : 1, "mean" : 0.001, "min" : 0, "stddev" : 0.035000000000000003, "sum" : 3.0 }, "301" : { "current" : 3.0, "description" : "number of HTTP 301 Moved Permanently responses", "max" : 1, "mean" : 0.001, "min" : 0, "stddev" : 0.035000000000000003, "sum" : 3.0 }, "304" : { "current" : 25.0, "description" : "number of HTTP 304 Not Modified responses", "max" : 8, "mean" : 0.01, "min" : 0, "stddev" : 0.215, "sum" : 25.0 }, "400" : { "current" : 23.0, "description" : "number of HTTP 400 Bad Request responses", "max" : 8, "mean" : 0.0089999999999999993, "min" : 0, "stddev" : 0.22900000000000001, "sum" : 23.0 }, "401" : { "current" : 5.0, "description" : "number of HTTP 401 Unauthorized responses", "max" : 2, "mean" : 0.002, "min" : 0, "stddev" : 0.059999999999999998, "sum" : 5.0 }, "403" : { "current" : 14.0, "description" : "number of HTTP 403 Forbidden responses", "max" : 6, "mean" : 0.0060000000000000001, "min" : 0, "stddev" : 0.156, "sum" : 14.0 }, "404" : { "current" : 100.0, "description" : "number of HTTP 404 Not Found responses", "max" : 80, "mean" : 0.040000000000000001, "min" : 0, "stddev" : 1.6220000000000001, "sum" : 100.0 }, "405" : { "current" : 3.0, "description" : "number of HTTP 405 Method Not Allowed responses", "max" : 1, "mean" : 0.001, "min" : 0, "stddev" : 0.035000000000000003, "sum" : 3.0 }, "409" : { "current" : 3.0, "description" : "number of HTTP 409 Conflict responses", "max" : 1, "mean" : 0.001, "min" : 0, "stddev" : 0.035000000000000003, "sum" : 3.0 }, "412" : { "current" : null, "description" : "number of HTTP 412 Precondition Failed responses", "max" : null, "mean" : null, "min" : null, "stddev" : null, "sum" : null }, "500" : { "current" : 87.0, "description" : "number of HTTP 500 Internal Server Error responses", "max" : 75, "mean" : 0.035000000000000003, "min" : 0, "stddev" : 1.508, "sum" : 87.0 } } }
Friday, March 2, 2012
Monitoring specific MySQL counters using LoadRunner
You can monitor MySQL database using Sitescope. However, if you don't have access to the Sitescope application then you can write a simple LoadRunner script to monitor specific MySQL counters and plot the values using lr_user_data_point LR function. The following script is an enhancement to MySQL script detailed in my earlier post.
NOTE:
All session related information in MySQL is stored in a table called "SESSION_STATUS". Therefore, we will be querying this table for MySQL counter values.
For demonstration purpose, the script below will query the values for LAST_QUERY_COST, OPENED_TABLES, QCACHE_HITS, SELECT_FULL_JOIN and SELECT_SCAN counters.
Global declaration
Vvuser_int
Query Function
vuser_end
NOTE: Make sure you are explicitly declaring the atof function before using it or else you will get totally different values. See the screenshot of the values received for the above counters when atof was not declared explicitly before using it.
NOTE:
All session related information in MySQL is stored in a table called "SESSION_STATUS". Therefore, we will be querying this table for MySQL counter values.
For demonstration purpose, the script below will query the values for LAST_QUERY_COST, OPENED_TABLES, QCACHE_HITS, SELECT_FULL_JOIN and SELECT_SCAN counters.
Global declaration
#include "C:\\Program Files\\MySQL\\oldfiles\\include\\mysql.h" //mySQL.h path is included /*MySQL structure defined*/ MYSQL *mySQL; MYSQL_ROW row; MYSQL_RES *result; int MyRC; char *MySQLserver = "localhost"; // Location where server is running char *MySQLuser = "root"; // User name used to connect to the database char *MySQLpassword = ""; // Not a good idea to leave password empty char *MySQLdatabase = "information_schema"; //Database name int MySQLport = 3306; // Database port
Vvuser_int
//libmysql.dll file loaded using lr_load_dll function MyRC= lr_load_dll("C:\\Program Files\\MySQL\\MySQL Connector C 6.0.2\\lib\\opt\\libmysql.dll"); //Initialise mySQL connection handler mySQL= mysql_init(NULL); // Connect to the database mysql_real_connect(mySQL,MySQLserver, MySQLuser, MySQLpassword, MySQLdatabase, MySQLport,NULL,0); return 0;
Query Function
double atof(const char *string); // Explicit declaration Query() { int i=0; float VarValue[5]; //Float variable array /*Save SQL statement into variable into sqlQuery. This query returns values for the variable name ={LAST_QUERY_COST,OPENED_TABLES,QCACHE_HITS,SELECT_FULL_JOIN,SELECT_SCAN}*/ lr_param_sprintf("sqlQuery","select variable_value from session_status where variable_name IN" "('LAST_QUERY_COST','OPENED_TABLES','QCACHE_HITS','SELECT_FULL_JOIN','SELECT_SCAN')"); mysql_query(mySQL, lr_eval_string ("{sqlQuery}")); //Execute SQL statement result = mysql_store_result(mySQL); //Result of the sql statement is placed into MYSQL_RES result structure row=mysql_fetch_row(result); while(row!=NULL) //Iterate through to last row { VarValue[i]=atof(row[0]); //Save float row value to VarValue row=mysql_fetch_row(result); //Retrive next row of the fetched result i++; } /*Use lr_user_data_point function to generate the graph*/ lr_user_data_point("LAST_QUERY_COST", VarValue[0]); lr_user_data_point("OPEN_TABLES", VarValue[1]); lr_user_data_point("QCACHE_HITS", VarValue[2]); lr_user_data_point("SELECT_FULL_JOIN", VarValue[3]); lr_user_data_point("SELECT_SCAN", VarValue[4]); return 0; }
vuser_end
/*Free the memory allocated to result structure and close the database connection*/ mysql_free_result(result); mysql_close(mySQL); return 0;
NOTE: Make sure you are explicitly declaring the atof function before using it or else you will get totally different values. See the screenshot of the values received for the above counters when atof was not declared explicitly before using it.
Subscribe to:
Posts (Atom)