Follow Me On...

Entries by Blake Robertson (47)

Monday
Mar192012

Sugar Online Preview -- Allows testing latest beta without having to install!

Want to test the latest version of sugar without having to install it?

Use SugarCRM Online Preview: http://www.sugarcrm.com/crm/SugarOnlinePreview and you’ll get a “cloud” instance to play around with for 7 days.  It takes less than 30 seconds!

This is a great way to test out the new features or see if your bug has been fixed without having to download it, allocate a database, go through the install wizard, etc.  

This preview mode doesn’t seem to be well publicized.  There really should be a link to it on the download page for customers.  I found this link one time before and couldn’t find it again even after signifigant searching around on the sugarcrm.com/forums.   So, bookmark it!

Wednesday
Mar072012

Error trying to run Windows Performance Index or Snagit 11 Crashing at startup?

Check if you are running windows 7 ‘N’.  Apparently this doesn’t include any media player files.  

Sunday
Mar042012

SugarCRM Server Performance Optimization / How to Benchmark Yourself

In an effort to improve the response time of my sugarcrm installation.  I developed a simple performance testing benchmark tool that allowed me to measure the impact each optimization had on the response time.  In this blog post I will a) present what optimizations worked the best for me b) explain how you can do the same and c) provide specific steps and recommendations for users who used the sugarcrm “FastStack” installers as their Apache+Mysql+PHP stack.

Test Methodology

To isolate the performance gain of each optimization, I’m changing one thing at a time and then running a performance benchmark script I wrote using the Apache Jmeter.  Jmeter is a free open source tool for load testing and performance measurement.  At the bottom of this article I provide a brief tutorial if you want to try testing the results yourself.

My test plan mimics the webbrowser.  It logs and fetches about 10 different module list view pages and loops 3 times.  My load test script does not fetch embedded resources in the php. It just calls index.php and passes relevant params such as module=Account, action=ListView.  So, none of the image files, js files, or css files are downloaded.  In this article i’m focusing purely on server side optimizations.  Perhaps I’ll dive into client side optimizations in a seperate article.

One thing that’s important to point out is that all these tests were done to measure the response time of the server when only one user was active.  And while there is generally a correlation between response time and amount of My tests focused on the average response time so just because the optimzations listed didn’t impact response time doesn’t mean that they do not decrease the amount of processing required or be asome of the tweaks I tested that didn’t have an improvement in terms of response time could very well reduce the amount of processing needed which in turn could provide a much greater impact when a lot of users are active.

Test Server Details

Windows Server 2003
Intel Core i7 2 cores @2.9Ghz
2GB Ram
250 Megs of diskspace free.

* All testing was done on SugarCRM Pro Edition v6.4.0 (unless otherwise specified)
* My Database is ~200mb, 1500 Accounts.
* We have ~20 users.  Only 1 active user when I did testing.
* To account for network delays, most results I ran test about 5 times, removed the worst and best and averaged the remaining 3.  

 

  • I was unable to isolate the reason for why Apache 2.2 / PHP 5.3 had such a major performance benefit.  I posted to the sugarcrm forums about it here: http://www.sugarcrm.com/forums/f6/need-help-identifying-cause-speedup-blog-article-its-not-apc-mysql-query-78499/
  • The performance improvements with APC opcode cache seem to make my webserver a little unstable.  So, I ended up disabling it.  
  • The tests marked with low confidence are ones that I’m not extremely confident on.  I did less tests on them and since the performance impact was so small all of them are kind of within the margin of error.
  • Mod Deflate was somewhat of a surprise.  Keep in mind that this test is only retrieving the .php file (none of the resources).  Since mod_deflate compresses the response, it makes sense that this would take more server processing time.  This slight increase in processing time is typically more then made up for by the shortend download time.  In my case, when running the test I was getting average bytes around 250k when deflate was off versus 44k when it was on.  So, I was compressing the html being returned a lot.  I’m still going to keep mod deflate on in production but it’s something to consider if you’re CRM is on your LAN as it might speed things up slightly.

 

 

Recommendations For FastStack Users

if you’re like me, I assumed when I installed the FastStack provided by SugarCRM that it would already be pre-optimized for sugarCRM.  This isn’t the case.  After going through this process for my own server, I suspect this was intentional to consume a low memory footprint and generally minimize potential for issuess such as needing to disable opcode cache before upgrading sugar.

First recommendation, install the latest stack.  I don’t know what changes were made in each version of the stack (I’ve looked everywhere for Release Notes and haven’t been able to find them…).  But, I know that between faststack version 6.0 and faststack version 6.4 there were signifigant improvements made.  Apache got upgraded from 2.0 to 2.2, PHP 5.2 —> 5.3, the php version installed with stack 6.4 comes with extension DLLs like php_apc, and php_gd which are compatible… so no need to go through the headache of finding the compatible binaries…  The GD extension is needed for the UI enhancements in 6.4 which make use of sprites.  Note: run repair after switching stacks.

Here’s a bulletted list of changes you should make:

  1. Enabled PHP opcode caching (maybe…) — After posting this I found that it was causing my Apache to crash.  I didn’t notice that much of an impact.
  2. Enabled Mysql Query Caching / Increase table size
  3. Enable mod_expires / mod_deflate 
  4. Make sure ajax ui is enabled.

I was planning on posting how to do 1-4 but got kinda of bored by the time I finished this article.  The links I provide below provide good guidance on it.  Or you can leave some comments and I’ll make a new post.

How to Test Against Your Own Tutorial

  1. Download jmeter: Apache JMeter - Downloads
  2. Run bin/jmeter.(bat|sh)
  3. Download my Test Plan from here: http://www.blakerobertson.com/files/…e-Clean-v2.jmx
  4. In Jmeter open the test plan (File->Open)
  5. Edit variables & run test as shown above.

I have created other more complex TestPlans.  The one I posted is sort of universal since it didnt’ depend on specific records to be around etc.  I have created more advanced scripts which also go to specific records.  You can have it download the CSS/JS files.  You can measure the server CPU / disk usage so you can compare the response time vs. server load.  There is a lot you can do.  If you’re interested in any of these things then please leave me a comment and I’ll see about writing more tutorials.

Useful SugarCRM articles 

All the tweaks I made in this article I got the idea from these articles.  I’d highly recommend reading them.

Some Quick Pointers on Improving SugarCRM Performance - great overview all around.  Specifically this article has good information on mysql tuning and sugarcrm specific tweaks.

Improving SugarCRM client-side performance: The server - Another good all around, specifically has great Apache snippets.  

* The developer blog as a ‘performance’ tag.  So, check here for the most up to date: Performance

Tuesday
Feb072012

Performance comparison mod_jk vs. mod_proxy_ajp for Apache 2.2

We use apache webserver as a frontend to tomcat and had been using mod_jk for years.  When we transitioned from Apache 2.0 to 2.2 we decided to try using mod_proxy_ajp because it seemed to be the direction most blogs/stackoverflow posts were recommending these days.  Not to mention I was unable to find mod_jk binaries for windows.  (I later found windows binaries for mod_jk (32-bit and 64-bit) here:
http://apache.osuosl.org//tomcat/tomcat-connectors/jk/binaries/windows/)

What we found is that if you have a high performance web application.  You’re absolutely going to want to use mod_jk.  I think this point is greatly understated on many other comparisons.

I did a quick and dirty performance test… using windows performance monitor (heh).  It has a neat feature that lets you calculate the average cpu over time which is pretty helpful.  Ironically, windows performance monitoring consumes an insane amount of cpu itself… but I digress.

Test #1 - CPU Utilization:

Win2008 R2, Apache 2.2.22, VMware
Generated a load of 400 requests/second (using a proprietary tool I wrote that simulates our application)
I let performance monitor run and calculate the average load consumed by each process over that 2 minute time period.
In between tests, all I did was modify the httpd.conf to change a few JkMount (mod_jk) statements to ProxyPassMatch (mod_proxy_ajp) statements.  Didn’t restart tomcat.   

Here are the results:

Average CPU %     Apache Webserver    Apache Tomcat    Total
Mod JK 12.96% 8.18% 21.14%
Mod Proxy AJP 18.49 25.94 44.43%

 

For the same load, our application used half as much CPU when using Mod JK!


 

Test #2 - Max Throughput Tests

After my initial post, I decided to go back and do another test using apache JMeter.  Click the thumbnail below to see the full results marked up with comments.  Essentially though, with mod_jk I was able to get 1400/sec and with mod_proxy_ajp I’d max out at about 900 (but with errors also).

Errors when using Mod Proxy AJP

As we ramped up number of active users we’d get errors much sooner with mod_proxy_ajp.  This is definitely more of an issue on Windows xp and Windows 2003 server machines then it was 2008 R2 or windows 7 box.  I don’t recall off hand all the things we tried to fix this.  I’m pretty sure we tried increasing ThreadsPerChild and other settings and it didn’t really help the problem at all.  I also remember we tried turning on mod_status and from the looks of things it did not appear that we were running out of workers.  It just didn’t add up.  But, afraid I didn’t investigate too much longer as the performance reasons alone were reason enough for me to switch back to Mod JK.  Perhaps someone else can shed more light on this.

Error Messages:
This is the error that would show up in apache-error.log when using mod_proxy_ajp under high load:

Windows 2008 R2 (with apache 2.2.22):

[Mon Feb 27 15:28:30 2012] [error] proxy: AJP: failed to make connection to backend: localhost
[Mon Feb 27 15:28:30 2012] [error] (OS 10055)An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full.  : proxy: AJP: attempt to connect to 127.0.0.1:8029 (*) failed

Another error message we saw is below.  I’m not sure if we got this error message only when we tested against windows XP/server 2003 boxes or if it was because we had Apache 2.2.21 on them.

[Tue Feb 07 14:48:00 2012] [warn] Server ran out of threads to serve requests. Consider raising the ThreadsPerChild setting
[Tue Feb 07 15:05:13 2012] [error] (OS 10061)No connection could be made because the target machine actively refused it.  : proxy: AJP: attempt to connect to 127.0.0.1:8029 (*) failed
[Tue Feb 07 15:05:13 2012] [error] proxy: AJP: failed to make connection to backend: localhost

Configuration Files

httpd.conf for mod_jk

JkWorkersFile C:/myapp/webserver/conf/workers.properties
JkLogFile C:/myapp/logs/apache-mod_jk.log
JkLogLevel error
JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
# JkOptions indicate to send SSL KEY SIZE,
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
# JkRequestLogFormat set the request format
#JkRequestLogFormat will print an entry such as: [Tue Feb 10 13:13:38 2009] worker2 tb1.alertustech.com 0.032000 -- for each jsp request.
#JkRequestLogFormat "%w %V %T"
# The following mount points forward requests matching the URL sequence to an application server.
JkMount /mywebapp/get*.jsp worker2

Workers.properties

worker.list=worker2
worker.worker2.type=ajp13
worker.worker2.host=localhost
worker.worker2.port=8029
worker.worker2.lbfactor=1
worker.worker2.socket_keepalive=false

httpd.conf for mod_proxy_ajp

ProxyPassMatch \/(mywebapp\/get.*\.jsp)$ ajp://localhost:8029/$1
Monday
Jan232012

Southwest Credit Card -- "Is it a good deal analysis"

Got bored during landing of a southwest flight and decided to see whether or not the southwest credit card was a good deal or not… Here’s the results of that analysis.

They say you get $25,000 in pts when you apply for the card and that this is a $400 value.  So, from this we can determine what the unpublished ratio of points to dollars is.

25,000 points = $400 (Southwest dollars)
$400/25,000 —> 0.016 $/pt
or 62.5 points/$

This means that 1.6% of what you spend in dollars becomes southwest credit.

Annual Fee

$69 airline fee —> x=69/.016 —> $4,312.5 a year to break even.

However, the above doesn’t take into account you get a free 3000 points a year.
3000 (pts) * 0.016 ($/pt) = $48

So, taking that into account… You need to spend at least:
(69-48)/0.016 = $1,312/yr to recoup your $69 annual fee.

After that you get 1.6%… to me that doesn’t sound like that great of a return.  Maybe next time I fly there will be another credit card ad I can digest for comparison.

Other misc

* Can be redeemed for international travel on 50+ global carriers.
* 3% fee on foreign expenses.
* Note: you get 3.2% back on southwest and partner hotel + rental car purchases.
* Points will expire if you don’t use the card for “flight or Partner earning activity every 24 months”. I don’t know if that means you have to buy southwest flights or if just taking a southwest flight is good enough. In my case I book all southwest using a business credit card.

Monday
Aug012011

Verdana in a Craigslist Post

Getting the font to change from the default Times New Roman can be tricky.

The only way I found to make it work is to use the following:

<font size="2" face="Verdana, Arial, Helvetica, sans-serif"></font>

Edit: Since I posted this I have been unable to make it work in particular postings.  If i copy the exact HTML that does apply the verdana font face in a Washington DC job posting over to a Baltimore Job posting.  The face=”Verdana” part is stripped off the Baltimore one.  So, perhaps they run slightly different versions of the engine.  The supported listing of HTML tags listed on craigslists site doesn’t list the face attribute as supported.  If you’re lucky maybe it’ll work… but If it doesn’t I wouldn’t waste too much time trying on account of this posting.

Sunday
Jul172011

DTMF issues with Trixbox/Asterisk?

Having problems with DTMF tones being recognized?

Our company was having issues where DTMF tones weren’t being recognized on certain IVRs… It was most reproducible trying to join most gotomeetings. We were running Asterisk 1.6.0 and Trixbox 2.8.

We tried pretty much everything possible including talking with our trunk, trying a different trunk, trying the different protocols, debugging with wireshark and nothing really made sense. We have our PBX hosted with lylix and the excellent engineers there upgraded our instance to Asterisk 1.6.2.18 and since then our DTMF issues have gone away. More info on this bug fix can be found here: https://issues.asterisk.org/view.php?id=15642

Update: 1.6.2.18 improved the issue signifigantly… but not completely.  We built asterisk from source upgrading it whatever is current around 1/15/2012 (too lazy to look up version email me if you need it though).

Keywords: GoToMeeting.com, GoToMeeting, DTMF

Sunday
Jul172011

Voicemail Script for Getting Rid of Solicitors

I got this tip from Less is More.
Create an extension which goes directly to voicemail.  When a solicitor calls up, transfer them to that extension and have a voicemail similar to:

Thank you for calling <Your Company Name>

Please listen to this message.  Due to the high volume of calls received from outside vendors calling to solicitor thier products and services, we must ask that you forward in writing a description of your product or service along with any other information on your organization to:

<address>

This address can also be found on our website.  <Website>

You can be assured that your information will be forwarded to the appropriate staff for review.  If they find your company is of interest to our business, a staff member will contact you directly at a later date.  Thank you for calling <Your Company Name> and thank you for understanding.

 

Tuesday
Jan112011

Switching from RingCentral to a Asterisk box... My Notes.

Here are my notes I put together when I did the pros and cons of switching to an asterisk based PBX system for my company.  At the time of writing we are using both concurrently.  In a nutshell, if you have someone tech savvy it’s definitely worth it.  You get a lot more features, freedom, and it’s cheaper.  My notes below are unedited from a google doc I kept so please excuse the grammar issues.

The notes on this article were prepared in September of 2010.

Feature Comparison RingCentral Vs Asterisk PBX  

Ring Central Pros:

  • The user interface is somewhat easier to use for setting up business hour calling rule type stuff.
  • Couldn’t find an option to have an email come through when someone doesn’t answer a call (but caller doesn’t leave a voice mail).
  • Ability to send a fax by sending an email (like the Ringcentral FaxOut option) is not built in to Asterisk by default.  There are addons which apparently provide this capability one is called AsterFax but since this functionality if built in to ringcentral it’s a pro for it. 
  • Other then that… all other features are matched / exceeded by Asterisk.

Asterisk Advantages:

  • Can have unlimited number of extentions and it doesn’t cost us any more a month.  Simplified per minute billing.  This means everyone can have a softphone + deskphone and it doesn’t cost anymore.
  • HD Voice capable (for higher quality phone calls)
  • Attended Transfer Option (allows you to stay on the line with caller in case the person you’re transfering to doesn’t pick up)
  • Caller ID can display contacts from our SugarCRM Database.
  • Caller ID can be prefixed with things like “Support:<number>|<contact name>”, “Sales:<number>|<contact name>”
  • Ability to define nested IVR hierarchy’s 
  • Panel view for when we have a receptionist allows them to transfer with drag and drop + see status of people’s phones.
  • Softphone’s dont add any additional cost (since extensions are free…)
  • Conference Calls can be done using a special extention… and all people attending call from inside your company don’t eat up your minutes. 
  • Interoffice calls are free (they’re handled by the PBX internally).
  • We can add direct dial numbers for 1.29 a month. 
  • Call Recording capabilities… we can have all sales calls recorded automatically for quality assurance. 
  • Call Queues - (people get put on hold until someone is available)
  • Call Parking Lots — (from the phone you can press a key sequence to put someone into a “parking lot slot”  then you call over to your buddy and say you have a call on 78.  The user then picks up his phone presses *78 and they’re connected to them.
  • Smart features like… If i’m already on a phone call and then I get a new call do not have it ring my cell phone also.  (in other words it skips the Find Me Settings if you’re using your desk phone).

Cost Comparison of RingCentral vs. Asterisk+FlowRoute

 Month of August: 

   Inbound Minutes: 1700
   Outbound Minutes: 2800


Asterisk + FlowRoute Sample Cost for August: 

   Monthly Fee: $35 (hosting fee to have asterisk box hosted by lylix)

   DID Fee: $1.39   (This is for each direct number… so we could have a support number, a local number and 866 number)

   Outbound Minute Cost: $27.44 = 0.0098 * 2793

   Inbound Minute Cost: $32.30 = 0.0190 * 1700 
   Total: $96.13

 
RingCentral Sample Cost for August 

   Digital Line Fees:  74.93 = 9.99 (ext1) + 9.99 (ext2) + 9.99 (ext3) + 4.99 (engineer ext) + 24.99 (sales ext) + 9.99 (ext4) + 4.99 (ext5) 

   RingCentral Power: 49.99 (includes 1000 minutes)

   Not Included Incoming Minutes: 29.4 = 700 * 0.042 

   Total: $154.32 + any minute pool overages

    * - Outbound minutes are assumed to be covered by each persons digital line.  This isn’t really the case since Basic lines don’t come with any minutes and people might go over minutes in standard plan.


* Since the per minute rates are much lower using flowroute the cost savings will go up significantly as you add more lines and use more minutes. 

 

Friday
Jul162010

Salesforce's "One Click, One Voicemail Activity" Button + Prompt box for comments.

I extended the idea presented here: http://www.youtube.com/watch?v=BOTH3XQGauk for creating a custom salesforce button which creates a followup task for a contact by allowing the user to specify some notes to go along with the task in a fast javascript prompt box.   This is a lot faster then creating a new activity which requires a new page to load and would setting the follow up date..

Follow the directions in the video except for when it comes to defining the custom button specify the following.

Behavior: Execute Javascript
Content Source: OnClick JavaScript

Here’s the code:

For a ‘Contact’ Button

var comments = prompt("Enter follow up details (to jog memory later)", "");
if( comments == null ) {
alert("Task creation canceled");
}
else {
comments = encodeURIComponent(comments); // encodes in url friendly way
window.location = ' /00T/e?followup=1&title=Call&retURL=%2F{!Lead.Id}&who_id={!Lead.Id}&what_id={!Lead.Id}&tsk6_fu='+comments+'&tsk5_fu=Follow+Up+w+{!Lead.Name}+[{!Lead.Name}]&tsk4_fu={!TODAY()+2}&save=x';
}
(Note not all code is visible above but it’ll be there when you copy and paste the selection above)

For a ‘Lead’ Button

var comments = prompt("Enter follow up details (to jog memory later)", "");
if( comments == null ) {
alert("Task creation canceled");
}
else {
comments = encodeURIComponent(comments); // encodes in url friendly way
window.location = ' /00T/e?followup=1&title=Call&retURL=%2F{!Contact.Id}&who_id={!Contact.Id}&what_id={!Account.Id}&tsk6_fu='+comments+'&tsk5_fu=Follow+Up+w+{!Contact.Name}+[{!Account.Name}]&tsk4_fu={!TODAY()+2}&save=x';
}
(Note not all code is visible above but it’ll be there when you copy and paste the selection above)

Usage Suggestion

The way we use this at our organization is we made several buttons: FU_1d, FU_2d, FU_1w, FU_3mo. Each button is a different length of time. Just copy the code above and change the +2 after TODAY() to +1, +2, +7, and +90 respectively.

Reference

Finally, here’s a reference of some of the GET parameters. I didn’t find the official documentation just a post on salesforce community so there are probably others.

tsk1=Assigned To
tsk2=Name
tsk3=Related To
tsk4=Due Date
tsk5=Subject
tsk6=Comments
tsk9=Activity Currency
tsk10=Type