<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tracelytics Blog</title>
	<atom:link href="http://www.tracelytics.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.tracelytics.com/blog</link>
	<description>Let&#039;s Talk About Your Performance</description>
	<lastBuildDate>Fri, 18 May 2012 16:53:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>The DevOps Reading List: 10 Books &amp; Blogs You Should Be Reading</title>
		<link>http://www.tracelytics.com/blog/the-devops-reading-list-10-books-blogs-you-should-be-reading/</link>
		<comments>http://www.tracelytics.com/blog/the-devops-reading-list-10-books-blogs-you-should-be-reading/#comments</comments>
		<pubDate>Thu, 17 May 2012 15:00:08 +0000</pubDate>
		<dc:creator>Brian Whalley</dc:creator>
				<category><![CDATA[DevOps]]></category>

		<guid isPermaLink="false">http://www.tracelytics.com/blog/?p=1124</guid>
		<description><![CDATA[When you&#8217;re doing research and planning application development, it&#8217;s always useful to learn from the stories and experience of your peers. Your own experience and background are critical towards having good judgement and making good decisions, but it&#8217;s great to leverage the experience of other people who&#8217;ve been there as well. Here&#8217;s a selection of [...]]]></description>
			<content:encoded><![CDATA[<p>When you&#8217;re doing research and planning application development, it&#8217;s always useful to learn from the stories and experience of your peers. Your own experience and background are critical towards having good judgement and making good decisions, but it&#8217;s great to leverage the experience of other people who&#8217;ve been there as well. Here&#8217;s a selection of great reading resources that can help you, this blog not included. If you&#8217;re interested in subscribing to the blogs mentioned, there&#8217;s also a Google Reader bundle or RSS feed that you can use to subscribe at the bottom of that section.</p>
<p><strong>Blogs To Read About DevOps, performance, and scalability:</strong></p>
<p>1) <a href="http://dev2ops.org/">Dev2Ops</a> (Updated Every 1-2 Weeks) - As the name would suggest, Dev2Ops covers everything you might want to know on this subject, and features a lot of video as well. Much of their material is also positioned for people in devops roles in larger organizations, and how to manage release and control systems in large organizations which have different kinds of problems than close, small teams.</p>
<p>2) <a href="http://blogs.atlassian.com/">Atlassian</a> (Updated 1-2x a week) - Atlassian&#8217;s excellent blog covers much of the infrastructure that teams need to stay in communication and on top of their business.</p>
<p>3) <a href="http://highscalability.com/">High Scalability</a> (Updated 2-3x a week) - One of the best blogs covering topics around DevOps, High Scalability includes everything in their material from new ideas and thought leadership to practical examples and news coverage of everything happening in the world of performance and scalability.</p>
<p>4) <a href="http://www.mysqlperformanceblog.com/">MySQL Performance Blog</a> (Updated 2-3x a week) - WIth a name like this, it&#8217;s hard to go wrong &#8211; You can&#8217;t really afford to skip this site at all if you&#8217;re responsible at all for database performance.</p>
<p>5) <a href="http://codeascraft.etsy.com/">Code as Craft</a> (Updated 3-5x a month) - By the Etsy team, Code as Craft describes the engineering and operations challenges and discoveries they&#8217;ve found at scale.</p>
<p>You can subscribe to all of these blogs (and our own) with one click now via our <a href="http://www.google.com/reader/bundle/user%2F06353485775933191566%2Fbundle%2FDevOps%20Blogs">Google Reader Bundle</a>! If you&#8217;re not a Google Reader user, <a href="http://www.google.com/reader/public/subscriptions/user%2F06353485775933191566%2Fbundle%2FDevOps%20Blogs">OPML</a> and <a href="http://www.google.com/reader/public/atom/user%2F06353485775933191566%2Fbundle%2FDevOps%20Blogs">RSS/Atom</a> versions of the Bundle are also available so that you can use your favorite application.</p>
<p><strong>Books!</strong> Here&#8217;s some great reading, whether you enjoy them digital or pulp, during your commute or at the gym, and anywhere in-between:</p>
<p>1) <a href="http://www.amazon.com/Web-Operations-Keeping-Data-Time/dp/1449377440">Web Operations: Keep The Data On Time</a> by <a href="https://twitter.com/#!/allspaw">John Allspaw</a> &amp; <a href="https://twitter.com/#!/jesserobbins">Jesse Robbins</a>. This is actually my current reading material and could almost be required reading material for anyone who wants to make a career in the development and operations world: John Allspaw and Jesse Robbins (with other select guest writers) break down some great engineering problems and stories about developing and scaling applications with a variety of tactics and issues at hand. If you only have the time or patience to read one book, this is the way to go.</p>
<p>2) <a href="http://www.amazon.com/Continuous-Integration-Improving-Software-Reducing/dp/0321336380">Continuous Integration</a> by Paul M Duvall, Steve Matyas, and Andrew Glover. The reasons why and benefits of CI are the subject of many other well-written blog posts <a href="http://martinfowler.com/articles/continuousIntegration.html">(One well known example is here)</a>, and this is a great book on the topic with examples and details on how to get the most out of it for your organization.</p>
<p>3) <a href="http://www.amazon.com/gp/product/0596518579/">The Art of Capacity Planning</a> by John Allspaw. We&#8217;ve already talked about John above &#8211; This is one of his other books. John&#8217;s incredible experience in infrastructure and capacity planning includes notable roles at Friendster, Yahoo/Flickr, and Etsy.</p>
<p>4) <a href="http://www.amazon.com/Lean-Enabling-Sustaining-Your-Transformation/dp/1439817561">Lean IT</a> by Steven C Bell and Michael Orzen. &#8220;Lean&#8221; is a phrase that&#8217;s often used and and even more often misused, and so resources that help appreciate the value of what lean strategies are and aren&#8217;t are very useful. If effectiveness and efficiency are problems for your group, adapting more of the lean strategies will probably benefit you. Even if your organization is already successful with lean strategies, it&#8217;s always useful to see examples and case studies of</p>
<p>5) <span id="btAsinTitle"><a href="http://www.amazon.com/Kanban-Successful-Evolutionary-Technology-Business/dp/0984521402">Kanban: Successful Evolutionary Change for Your Technology Business</a> by David Anderson and Donald Reinertsen. </span>If you&#8217;re part of a team and struggling as a group to manage and make progress on a number of projects simultaneously, you probably do work in an IT or DevOps organizing. They&#8217;re complicated and constantly full of different challenges at different levels, but there are resources available that can help you better plan and understand the work that you have to do.</p>
<p>6) This is a bonus one since it&#8217;s not directly about DevOps, but it is a critical book about management and business by one of the great legends of the topic. <span id="btAsinTitle"><a href="http://www.amazon.com/Management-Challenges-Century-Peter-Drucker/dp/0887309992">Management Challenges for the 21st Century</a> by Peter Drucker is a critical book for anyone responsible for business goals and operational success. There&#8217;s not much more that you can say about it than that. </span></p>
<p>What other blogs or books do you enjoy reading about web development and performance? What have you learned from? Let us know in the comments.</p>
<p><a href="http://www.flickr.com/photos/tvaughan/">(Photo Credit: Talltim)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.tracelytics.com/blog/the-devops-reading-list-10-books-blogs-you-should-be-reading/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Solving Two Of The Most Common Web Performance Mistakes</title>
		<link>http://www.tracelytics.com/blog/two-most-common-performance-mistakes/</link>
		<comments>http://www.tracelytics.com/blog/two-most-common-performance-mistakes/#comments</comments>
		<pubDate>Tue, 15 May 2012 11:15:19 +0000</pubDate>
		<dc:creator>Chris Erway</dc:creator>
				<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://www.tracelytics.com/blog/?p=1068</guid>
		<description><![CDATA[Here at Tracelytics, we love it when a customer thanks us for helping them track down a hard-to-diagnose performance problem. Over the past year, as we’ve helped more customers, we’ve noticed a few common patterns pop up, so we&#8217;re blogging about a few of them and their solutions. While every web stack is unique, when [...]]]></description>
			<content:encoded><![CDATA[<p>Here at Tracelytics, we love it when a customer thanks us for helping them track down a hard-to-diagnose performance problem. Over the past year, as we’ve helped more customers, we’ve noticed a few common patterns pop up, so we&#8217;re blogging about a few of them and their solutions.</p>
<p>While every web stack is unique, when you start scaling there are often low-hanging fruit waiting to be plucked (and fixed) that eventually everyone will encounter. They may not be glamorous, but they are common — and easy to fix once diagnosed.</p>
<p>This week, we’ll break down two common classes of performance problems we see in typical web apps — one for ops engineers, one for developers — and general approaches to solving them.</p>
<h2>The underprovisioned backend</h2>
<p><strong>Problem</strong><br />
You’re getting some publicity and seeing more traffic, but your app is getting slower, and you’re not sure why. You log into Tracelytics and see a graph like the one below. What does it mean? Why do requests seem to be spending so long in Apache or Nginx when you suspect it’s your app that’s slow? Shouldn’t they be spending all that time in the your app server backend (e.g., PHP, Rails/Unicorn, WSGI, etc)? Or maybe your app isn’t slow at all and there’s something wrong with your web server?</p>
<p><a href="http://www.tracelytics.com/blog/wp-content/uploads/read_stack_2_large_key.png"><img class="aligncenter size-large wp-image-1136" title="Nginx increasing, App layer (WSGI) constant" src="http://www.tracelytics.com/blog/wp-content/uploads/read_stack_2_large_key-650x214.png" alt="Nginx increasing, App layer (WSGI) constant" width="650" height="214" /></a></p>
<p><strong>Diagnosis</strong><br />
That growing amount of “web server time” indicates your requests are spinning their heels queued up in front of your app server, waiting to be processed. Your backend can only handle a certain number of requests per second, and that rate is determined by two important factors: the average performance of individual requests, and the number of workers (threads, processes, server instances) provisioned for your backend.</p>
<p>A lot of teams spend a lot of time thinking about the former concern — writing clean, well-performing code, worrying about database indexes, etc — but then get bitten by the latter when they start to scale.</p>
<p>Worse yet, real-world user traffic is highly variable, making it hard to figure out whether the slow performance you were seeing during a traffic spike was more to blame on the code or was because of a misconfigured deployment or underprovisioned backend. One useful feature of Tracelytics in this scenario is our layer breakdown, which charts web server &amp; app layer latencies over time to help you pin blame accordingly.</p>
<p><strong>Solution</strong><br />
Of course, it’s always a combination of both factors, but for many teams with scaling challenges, often the simplest, lowest-hanging performance mistake they make is simply not provisioning workers fast enough to meet user demand. Do the math — if you have, for example, just 8 Rails Unicorn workers available, and know that on average your dynamic pages take ~200ms per request, then your deployment can support at best only 40 requests per second.</p>
<p>Without a well-provisioned backend, even if most of your pages would load right away under typical conditions, a sudden spike or even a slow-growing, unnoticed rise in demand could quickly eat up all available workers. Requests start to queue up in the web server or load balancer before they ever make it to the app layer, and users experience slow page load times or timeout errors.</p>
<p>It’s tricky to pick the right number of processes &amp; threads that maximize concurrency on each app server without exceeding resource limits (CPU, memory). There are different operational concerns for every kind of backend and server environment &#8212; which are outside the scope of this article — but it’s not uncommon to find that the default configuration settings distributed with your server software are hugely inefficient without tuning.</p>
<p>But in the face of a 10x traffic spike, all that tuning won’t necessarily help if you’re not well-provisioned in anticipation already, and/or can’t quickly add capacity (more servers) when needed. Cloud services like Amazon’s EC2 Auto Scaling are a great way to schedule or trigger capacity increases and decreases to meet user demand. And don&#8217;t forget to exercise your stack with load testing, too — the screen shot above was actually taken from <a title="Performing under pressure, pt. 2: Collecting and visualizing load-test performance data" href="http://www.tracelytics.com/blog/performing-under-pressure-pt-2-collecting-and-visualizing-load-test-performance-data/">Dan&#8217;s post on load-testing the Reddit source</a>.</p>
<h2>The looped query</h2>
<p><strong>Problem</strong><br />
You wrote some code that looped over a set of related items — for example, a user’s comments or tags — and added a database query or service request inside the loop. Maybe you were working inside a loop in a template file, and just needed to grab a little more metadata inside that loop, so you called back to your app from the template.</p>
<p>You may have thought at the time: “But this query to grab the current tag’s last-updated date will return so quickly! It’s on a table with a great index! How could this be a performance problem later?” Or maybe you were following <a title="37 Signals Getting Real: Scale Later" href="https://gettingreal.37signals.com/ch04_Scale_Later.php">37 Signals’ advice to “scale later”</a> and just wanted to get it working quickly.</p>
<p><a href="http://www.tracelytics.com/blog/wp-content/uploads/query_loop-tall.png"><img class="alignnone size-large wp-image-1139" title="A trace of a query in a loop" src="http://www.tracelytics.com/blog/wp-content/uploads/query_loop-tall-650x413.png" alt="A trace of a query in a loop, using WordPress" width="650" height="413" /></a></p>
<p><strong>Diagnosis</strong><br />
At scale it’s not just about individual query performance: all those extra round-trips to the database can really hurt once you hit hundreds or thousands of items. Even if your database can fire back a response to each query in say, 1ms, the database adds a whole second of latency to run 1000 per-item lookup queries. Add in the time it takes your DB driver or ORM to format query arguments, send them over the network, wait for and process the response, and you could be adding several more seconds of unnecessary latency and extra work.</p>
<p>The screenshot above is taken from a trace of a WordPress page using a “comment karma” plugin that issues a SQL query for each comment. While each query takes only a millisecond or less, running 708 of them in sequence adds a couple of seconds of MySQL-related time, and the back-and-forth legwork in PHP to process the request &amp; response adds more time, all for a total of four seconds to load all those comments!</p>
<p><strong>Solution</strong><br />
Move that query out of the loop! Grab all the values that you need (e.g. all of a user’s tags, comments, or friends) with one big request, or in fixed-sized batches. Then once your app starts filling up with real data, you’ll be able to handle it gracefully. Double-check template code for per-item requests inside for loops.</p>
<h2>Conclusion</h2>
<p>Again, these issues aren&#8217;t glamorous, but we see them enough that they seemed like a good start to this series. In future posts we&#8217;ll look at more general classes of problems as well as specific pitfalls affecting certain web stacks.  And as always we&#8217;re curious to hear your performance stories, too!</p>
<p>(<a href="http://www.flickr.com/photos/hinkelstone/">Title Photo From Quapan on Flickr</a>)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tracelytics.com/blog/two-most-common-performance-mistakes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Solving Slow Database Performance In Java &amp; MySQL</title>
		<link>http://www.tracelytics.com/blog/solving-slow-database-performance-in-java-mysql/</link>
		<comments>http://www.tracelytics.com/blog/solving-slow-database-performance-in-java-mysql/#comments</comments>
		<pubDate>Wed, 09 May 2012 16:56:30 +0000</pubDate>
		<dc:creator>Dave Costantino</dc:creator>
				<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://www.tracelytics.com/blog/?p=1003</guid>
		<description><![CDATA[Tracelytics is currently in beta with new Java instrumentation to help businesses using better understand their application&#8217;s performance, and steer future optimization efforts. We&#8217;ve been working with a handful of customers that are trying to solve complex issues with application speed and a Java stack, and learning a lot about what types of problems they frequently run [...]]]></description>
			<content:encoded><![CDATA[<p>Tracelytics is currently in beta with new <a href="http://support.tracelytics.com/kb/installation-instructions/installing-java-instrumentation-beta">Java instrumentation</a> to help businesses using better understand their application&#8217;s performance, and steer future optimization efforts. We&#8217;ve been working with a handful of customers that are trying to solve complex issues with application speed and a Java stack, and learning a lot about what types of problems they frequently run into. Troubleshooting these setups can be tricky &#8211; The web application in today&#8217;s example is running on a nginx / Tomcat / MySQL stack. That&#8217;s a pretty common set of technologies to use, so let&#8217;s dive into how you can target and understand application slowness on specific pages.</p>
<p>The specific application we&#8217;re looking at is a message board (forum) that processes about 3600 requests per hour. Viewing the heatmap, we notice a pattern: there are basically 2 clusters of requests, those that take under 100 ms and then a set of slower requests that take over 600 ms, forming a line near the top:</p>
<p><a href="http://www.tracelytics.com/blog/solving-slow-database-performance-in-java-mysql/javaapplatency-before/" rel="attachment wp-att-1033"><img class="alignnone size-full wp-image-1033" title="Application Latency - Before" src="http://www.tracelytics.com/blog/wp-content/uploads/JavaAppLatency-Before.png" alt="" width="973" height="427" /></a></p>
<p>We select the slow, high latency requests in the heat map and check out the top URLs:<br />
<a href="http://www.tracelytics.com/blog/solving-slow-database-performance-in-java-mysql/javatopurls/" rel="attachment wp-att-1021"><img class="alignnone size-full wp-image-1021" title="JavaTopURLs" src="http://www.tracelytics.com/blog/wp-content/uploads/JavaTopURLs.png" alt="" width="520" height="245" /></a></p>
<p>Ah ha! This is a little more revealing to the source of our problem: The majority of these requests are related to &#8220;profile&#8221; pages, so investigating those seems like an appropriate place to start. Let&#8217;s break down an individual trace for the /user/profile/3.page request, where we notice that the majority of time is spent in a single SQL query:</p>
<p><a href="http://www.tracelytics.com/blog/solving-slow-database-performance-in-java-mysql/javatracenotes/" rel="attachment wp-att-1024"><img class="alignnone size-full wp-image-1024" title="JavaTraceNotes" src="http://www.tracelytics.com/blog/wp-content/uploads/JavaTraceNotes.png" alt="" width="912" height="208" /></a></p>
<p>Viewing that extent, Tracelytics provides us the exact SQL query being executed, along with the offending line of code in the application, in the form of a Java stack trace. The SQL query is:</p>
<pre class="brush: sql; title: ; notranslate">
SELECT COUNT(pm.privmsgs_to_userid) AS private_messages, u.*
    FROM jforum_users u
    LEFT JOIN jforum_privmsgs pm ON pm.privmsgs_type = 1
         AND pm.privmsgs_to_userid = u.user_id
    WHERE u.user_id = 3
    GROUP BY pm.privmsgs_to_userid
</pre>
<p>We connect to the MySQL database and run an &#8220;explain&#8221; on the query to provide us with the query plan:</p>
<pre class="brush: plain; title: ; notranslate">
mysql&gt; explain SELECT COUNT(pm.privmsgs_to_userid) AS private_messages, u.*
    FROM jforum_users u
    LEFT JOIN jforum_privmsgs pm ON pm.privmsgs_type = 1
        AND pm.privmsgs_to_userid = u.user_id
    WHERE u.user_id = 3
    GROUP BY pm.privmsgs_to_userid \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: u
type: const
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: const
rows: 1
Extra: Using temporary; Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: pm
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 2100274
Extra:
2 rows in set (0.00 sec)
</pre>
<p>In the above &#8216;explain&#8217;, we can immediately see the source of the problem: the &#8220;type: ALL&#8221; under &#8220;table: pm&#8221; means no index is being used when accessing the private_messages table and MySQL is doing a full table scan.</p>
<p>For any table with a very small number of rows, this probably wouldn&#8217;t matter. Unfortunately, this particular table has over 2.1 million rows and MySQL indicates it is going to examine them all (&#8220;rows: 2100274&#8243;). This is likely the source of our performance problem. To verify, we look at the table&#8217;s DDL with &#8220;show create table&#8221; and discover that the table actually has no indexes at all. This is the exact type of issue that only becomes a problem at scale: When the message board was young and only had a few users, this page was fast and seemed innocuous. Now that it&#8217;s part of a big database and there&#8217;s a lot of data being stored, <strong>even if the overall level of traffic is the same over time</strong>, this huge database takes a much longer time to scan through. Let&#8217;s say that one more time: <strong>Not every problem of application scaling is the result of increased users or load</strong> &#8211; Your storage and methods of accessing that storage can break down, too!</p>
<p>Let&#8217;s solve this issue quickly: By adding an index on the the two join conditions (privmsgs_type and privmsgs_to_userid), the query should become much more efficient.</p>
<p>We run:</p>
<pre class="brush: sql; title: ; notranslate">alter table jforum_privmsgs add key privmsgs(privmsgs_type,privmsgs_to_userid);</pre>
<p>By running this command, we&#8217;ve added an index to the table that the query can run against. To verify it is actually being used with our query, we run the same &#8220;explain&#8221; again:</p>
<pre class="brush: plain; title: ; notranslate">
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: u
type: const
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: const
rows: 1
Extra: Using temporary; Using filesort
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: pm
type: ref
possible_keys: privmsgs
key: privmsgs
key_len: 5
ref: const,const
rows: 8
Extra: Using index
2 rows in set (0.00 sec)
</pre>
<p>The &#8220;key: privmsgs&#8221; output indicates that our new index is being used. As a result, the number of rows examined on the jforum_privmsgs table has dropped from over 2.1 million to just 8 rows. We&#8217;re back to the small table sizes that are very fast for MySQL to scan through.</p>
<p>About a half hour later, we take another look at the heatmap. There is a very noticeable change around 2:15, right after we added the index:</p>
<p><a href="http://www.tracelytics.com/blog/solving-slow-database-performance-in-java-mysql/javaapplatency-after/" rel="attachment wp-att-1061"><img class="alignnone size-full wp-image-1061" title="Java App Latency - After" src="http://www.tracelytics.com/blog/wp-content/uploads/JavaAppLatency-After.png" alt="" width="975" height="429" /></a></p>
<p>We filtered our traces down to the /user/profile/3.page URL to see the effect our change has had on that particular page:</p>
<p><a href="http://www.tracelytics.com/blog/solving-slow-database-performance-in-java-mysql/javaapplatency-after-filter/" rel="attachment wp-att-1060"><img class="alignnone size-full wp-image-1060" title="Java App Latency - After - Filtered" src="http://www.tracelytics.com/blog/wp-content/uploads/JavaAppLatency-After-Filter.png" alt="" width="970" height="426" /></a></p>
<p>The profile requests are now averaging 11 ms. Originally, they were around 640 ms, which makes this about a 58x improvement. We made a very small change that provided a very large impact on the performance of our application! Not every problem will be this straightforward to solve, but without complete information about the time spent in each part of this request, this would have been a much more difficult and complicated problem to diagnose.</p>
<p>You can get this same performance data for your applications by signing up for a Tracelytics trial today: Start tracing today!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tracelytics.com/blog/solving-slow-database-performance-in-java-mysql/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Welcome Home, To Tracelytics</title>
		<link>http://www.tracelytics.com/blog/welcome-home-to-tracelytics/</link>
		<comments>http://www.tracelytics.com/blog/welcome-home-to-tracelytics/#comments</comments>
		<pubDate>Wed, 02 May 2012 15:00:23 +0000</pubDate>
		<dc:creator>Brian Whalley</dc:creator>
				<category><![CDATA[Company news]]></category>

		<guid isPermaLink="false">http://www.tracelytics.com/blog/?p=979</guid>
		<description><![CDATA[Yesterday we hosted our office-warming party at the new Tracelytics Headquarters in Boston. Lots of customers, friends, and associates were in the house to celebrate with us! Friends, customers, and co-workers from all over came over to help us break in the new space, and play some Foosball on our newly finished table. The Tracelytics [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday we hosted our office-warming party at the new Tracelytics Headquarters in Boston. Lots of customers, friends, and associates were in the house to celebrate with us!</p>
<p style="text-align: center;"><img class="size-full wp-image-985 aligncenter" title="6988215826_9f255bfa16_z" src="http://www.tracelytics.com/blog/wp-content/uploads/6988215826_9f255bfa16_z.jpeg" alt="" width="580" height="348" /></p>
<p>Friends, customers, and co-workers from all over came over to help us break in the new space, and play some Foosball on our newly finished table.</p>
<p><img class="aligncenter size-full wp-image-986" title="7134301765_d87f572f66_z" src="http://www.tracelytics.com/blog/wp-content/uploads/7134301765_d87f572f66_z.jpeg" alt="" width="640" height="425" /></p>
<p><img class="aligncenter size-full wp-image-988" title="7134306025_1a541abdc7_z" src="http://www.tracelytics.com/blog/wp-content/uploads/7134306025_1a541abdc7_z.jpeg" alt="" width="640" height="425" /></p>
<p>The Tracelytics logo has never looked so delicious.</p>
<p><img class="aligncenter size-full wp-image-987" title="7134287259_a83c789a4b_c" src="http://www.tracelytics.com/blog/wp-content/uploads/7134287259_a83c789a4b_c.jpeg" alt="" width="603" height="470" /></p>
<p>Thanks to everyone who came and helped make this a special night for us. We&#8217;re glad the rain didn&#8217;t stop people from coming by to visit! If you happened to miss us yesterday, feel free to drop by our office and see what we&#8217;re up to and what new tools we&#8217;re developing.</p>
<p>- The Tracelytics Team</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tracelytics.com/blog/welcome-home-to-tracelytics/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Blips or Ships? What We Saw At #UTRconf 2012</title>
		<link>http://www.tracelytics.com/blog/blips-or-ships-what-we-saw-at-utrconf-2012/</link>
		<comments>http://www.tracelytics.com/blog/blips-or-ships-what-we-saw-at-utrconf-2012/#comments</comments>
		<pubDate>Mon, 30 Apr 2012 15:45:57 +0000</pubDate>
		<dc:creator>Dan Kuebrich</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.tracelytics.com/blog/?p=965</guid>
		<description><![CDATA[Spiros and Dan were at Under the Radar 2012 this year, presenting on application performance and spreading the word about Tracelytics. Besides our own presentation, we ran into a lot of other interesting startups and ideas that are going to make the web faster and improve developer and user experience. If you want to check out [...]]]></description>
			<content:encoded><![CDATA[<p>Spiros and Dan were at <a title="under the radar" href="http://www.undertheradarblog.com" target="_blank">Under the Radar</a> 2012 this year, presenting on application performance and spreading the word about Tracelytics. Besides our own presentation, we ran into a lot of other interesting startups and ideas that are going to make the web faster and improve developer and user experience.</p>
<p>If you want to check out what we were doing there, here&#8217;s the recording of <a href="http://www.ustream.tv/recorded/22144256">Spiros presenting on Tracelytics</a> for the panel.</p>
<p>Here’s a few other startups that excited us:</p>
<h2>MemSQL</h2>
<p>You might already be convinced that you need to keep your DB hot set in memory, especially if you’re in a virtualized/cloud environment. So why not use a database that assumes that case and is optimized for it? That’s the premise behind <a title="memsql" href="http://memsql.com" target="_blank">MemSQL</a>, a YC2011 graduate that won the audience award for databases at UTR. They boast 30x faster than disk-backed MySQL and a smaller multiple over ramdisk-backed MySQL. You might be thinking: “isn’t this just <a title="voltdb" href="http://voltdb.com/" target="_blank">VoltDB</a>?” Well, there’s two big differences: first, it’s mysql wire-protocol compatible, meaning no pre-writing stored procedures and that it will be drop-in for many customers (MemSQL compiles your queries and caches them automatically). Second, it isn’t in GA yet, so there’s no way for you to try it out. This is one we’ll be watching going forward!</p>
<h2>ScaleArc</h2>
<p>At some point in every engineer’s life, they’ve considered writing a SQL proxy. Whether it’s to automate load balancing, sharding, or gaining visibility into the performance of your database layer, a proxy that speaks your SQL flavor down to the wire protocol would go a long way to make those tasks a breeze. That’s what <a title="scalearc" href="http://www.scalearc.com" target="_blank">ScaleArc</a> gives you. This might not be as sexy as those new-fangled database technologies flying around (see above), but it solves a few problems, like caching and profiling, without any code modification.  Particularly useful if you don&#8217;t have full control over the app.  It’s also an example of a developer-driven product, and we have a lot of respect for that here at Tracelytics.</p>
<h2>DataDog</h2>
<p>Have you seen the Velocity 2010 talk “<a title="velocity 2010 facebook" href="http://velocityconf.com/velocity2010/public/schedule/detail/13103" target="_blank">A Day in the Life of Facebook Operations</a>”? I had a craving for a dashboard like the one they use internally to keep track of operations events and code deploys. At the same time, on the other side of the country, <a title="datadog" href="http://www.datadoghq.com/product/" target="_blank">DataDog</a> was working on a collaborative ops vision very similar. Their service integrates feeds from dozens of monitoring sources (Ganglia, Nagios, GitHub, etc) and ties it together with real-time graphs and social commenting/sharing features for internal productivity.</p>
<p><em>(Full Disclosure: Tracelytics and DataDog are both funded by Battery Ventures)</em></p>
<h2>And Finally, Your Moment of Zen</h2>
<p>Though all the panels at UTR were full of insightful, hard-hitting judges, few were more entertaining than Joyent’s Jason Hoffman:</p>
<p><center><iframe style="border: 0px none transparent;" src="http://www.ustream.tv/embed/recorded/22148062/highlight/260361" frameborder="0" scrolling="no" width="480" height="270"></iframe></center><br />
(apologies in advance for ustream ads)</p>
<h2>Under our Under the Radar Radar?</h2>
<p>What did you enjoy at UTR?  Something we missed?  Let us know below!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tracelytics.com/blog/blips-or-ships-what-we-saw-at-utrconf-2012/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Join us at our office warming Party &#8211; May 1st!</title>
		<link>http://www.tracelytics.com/blog/office-party-may-1st/</link>
		<comments>http://www.tracelytics.com/blog/office-party-may-1st/#comments</comments>
		<pubDate>Wed, 25 Apr 2012 14:35:33 +0000</pubDate>
		<dc:creator>Brian Whalley</dc:creator>
				<category><![CDATA[Company news]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.tracelytics.com/blog/?p=934</guid>
		<description><![CDATA[We&#8217;ve just settled into our new office space on South Street in Boston, and we&#8217;d like to invite you all to a party at our offices to break them in. If you&#8217;d like to come, please feel free to RSVP here on evite so that we have a rough headcount for how many are coming, [...]]]></description>
			<content:encoded><![CDATA[<p><img class="wp-image-936 alignright" title="Tracelytics Door Logo" src="http://www.tracelytics.com/blog/wp-content/uploads/lOnJ6.jpeg" alt="Tracelytics Logo" width="360" height="407" /></p>
<p>We&#8217;ve just settled into our new office space on South Street in Boston, and we&#8217;d like to invite you all to a party at our offices to break them in. If you&#8217;d like to come, please <a href="http://new.evite.com/?utm_source=other_email&amp;utm_medium=email&amp;utm_content=text&amp;utm_campaign=host_conf#view_invite/rsvp_yes:eid=0227AAQZXGL24EFJ4EPBQJ464FW52Y">feel free to RSVP here on evite</a> so that we have a rough headcount for how many are coming, and please feel free to bring friends or colleagues &#8211; The more the merrier!</p>
<p>When: May 1st, 5:30 PM and on!</p>
<p>Where: <a href="http://www.google.com/maps?q=133+south+st,+boston,+ma&amp;hl=en&amp;ll=42.351186,-71.057339&amp;spn=0.006105,0.00971&amp;sll=42.351150,-71.057404&amp;hnear=133+South+St,+Boston,+Massachusetts+02111&amp;t=m&amp;z=17">133 South Street, Boston MA</a> (One block from South Station)</p>
<p>RSVP Here: <a href="http://new.evite.com/?utm_source=other_email&amp;utm_medium=email&amp;utm_content=text&amp;utm_campaign=host_conf#view_invite/rsvp_yes:eid=0227AAQZXGL24EFJ4EPBQJ464FW52Y">Evite Page</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.tracelytics.com/blog/office-party-may-1st/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Efficient Histograms via Quantile Summarization</title>
		<link>http://www.tracelytics.com/blog/efficient-histograms-via-quantile-summarization/</link>
		<comments>http://www.tracelytics.com/blog/efficient-histograms-via-quantile-summarization/#comments</comments>
		<pubDate>Mon, 23 Apr 2012 13:00:30 +0000</pubDate>
		<dc:creator>Dan Kuebrich</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.tracelytics.com/blog/?p=428</guid>
		<description><![CDATA[This is a guest post from summer 2011 intern Matt Smith.  We&#8217;ll be welcoming our summer 2012 interns soon! The latency histograms on our overview page give a nicely detailed alternative to the &#8220;average&#8221; latency trendline they accompany, showing underlying components to the average response time.  The concise representation may fool you, but these once [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;" align="CENTER"><em>This is a guest post from summer 2011 intern <a title="matt's github" href="https://github.com/fastismatt" target="_blank">Matt Smith</a>.  We&#8217;ll be welcoming our summer 2012 interns soon!</em></p>
<p style="text-align: left;" align="CENTER">The latency histograms on our overview page give a nicely detailed alternative to the &#8220;average&#8221; latency trendline they accompany, showing underlying components to the average response time.  The concise representation may fool you, but these once were the slowest feature in Tracelytics, sometimes taking over two minutes to load!  This obviously needed to be fixed, but it&#8217;s hard to know where to start working optimization when you need to make something not just 10% faster, but 1000% faster.  I faced a number of challenges, starting with algorithmic complexity and ending with fine-tuning python code.</p>
<h2 style="text-align: left;" align="CENTER">Histogram 101</h2>
<p style="text-align: left;" align="CENTER">First, a quick review for context: a <a title="wikipedia histogram" href="http://en.wikipedia.org/wiki/Histogram" target="_blank">histogram</a> is a plot of the frequency of observed values in a given sample.  In our case, we&#8217;re showing the distribution latencies for requests to a web app.  It&#8217;s usually drawn as bar charts due to the discrete nature of the bucketization.  We draw a continuous-looking line chart due to the fine granularity of the data:</p>
<p style="text-align: left;" align="CENTER"><img class="aligncenter" title="tracelytics histogram" src="http://i.imgur.com/itfoU.png" alt="latency histogram" width="381" height="143" /></p>
<p style="text-align: left;" align="CENTER">What goes into building this?  Well, to draw the chart we need to know how many traces took 1-2ms, how many took 2-3ms, 3-4ms&#8230; all the way up.  And the buckets should be sized intelligently based on the range of the data.  Which means that in the most naive solution, you&#8217;re looking at data proportional in size to the number of traces that have been observed.  Ok for small data sets, not so ok for larger ones.</p>
<h2><strong>Where did I start?</strong></h2>
<p>We knew (thanks to the traceview) a lot of time was being wasted fetching millions of traces worth of latency information from MySQL. Gathering this much data would even be slow locally, so the trouble doesn&#8217;t end  at the database, because we would still need to sort and analyze all of the data, only to condense it down to a couple of kilobytes to send off to the user. That&#8217;s too time consuming and requires too much work by several orders of magnitude. From that conclusion, we decided the best course of action was to find a way to drastically reduce both the amount of data we had to search and the amount of data we had to retrieve.</p>
<p>Fortunately, TR and Dan had already done some of the thinking for me. The solution we found was a variation of a technique called quantile summarization, used in financial analysis, which allows for arbitrary quantiles to be queried over a sliding time window. A small amount of information, called a &#8220;quantile sketch,&#8221; is stored for the latency distribution over a time slice.  These sketches can later be merged with sketches of other time slices to get information regarding an arbitrary time window.  (Want more details?  Starting point: &#8220;<a title="Continuously maintaining quantile summaries of the most recent n elements over a data stream" href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.89.6970" target="_blank">Continuously Maintaining Quantile Summaries of the Most Recent N Elements over a Data Stream</a>&#8220;)</p>
<p>The end result is a much faster query of the database and a lot less information being passed over the wires. However as a trade-off, the data requires a significant amount of post-processing&#8211;the merging of the sketches&#8211;to be useful. I whipped up an algorithm for this post-processing in Python and gave it a whirl and&#8230;</p>
<p><a href="http://www.tracelytics.com/blog/wp-content/uploads/comparison.png"><img class="aligncenter size-large wp-image-923" title="traceview - is it fast yet?" src="http://www.tracelytics.com/blog/wp-content/uploads/comparison-650x178.png" alt="traceview - is it fast yet?" width="650" height="178" /></a></p>
<p>&#8230;the graphs still took about 30 seconds to produce! I couldn&#8217;t believe it. I opened up a traceview, and looked for a gigantic chunk marking the amount of time spent in the database. But as it turns out, the database latency was only a thin sliver. Our plan to speed up the database leg of the journey was a huge success, but my simple Python code was taking <em>nearly half a minute to run</em>. I was already using the optimal algorithm from the papers. I couldn&#8217;t even remember the last time I had written something so slow. Frankly, I was embarrassed.</p>
<h2><strong>Well, then what the $%* is going on inside Python?</strong></h2>
<p>Have you ever wondered how Python handles all those fancy list operations? I certainly have, and like most people, I have no clue. Looking at my code I couldn&#8217;t immediately see an obvious problem that was causing things to crawl.</p>
<p>After I turned on <a title="tracelytics function profiling" href="http://support.tracelytics.com/kb/instrumenting-your-app/function-profiling" target="_blank">cProfile support in Tracelytics</a>, we built up a few traces to see what evidence Tracelytics could share on itself. According to the data, the problem stemmed from 20 seconds wasted in thousands of calls to Python&#8217;s pop method. Why would this happen? Shouldn&#8217;t popping from the ends of a list be fast?</p>
<p>As it turns out, popping an item from the front of a list is a very bad mistake because it automatically shifts all the remaining entries forward one slot in the array.  You could look at code like me, or maybe save some time with <a title="python list operations time complexity" href="http://wiki.python.org/moin/TimeComplexity#list" target="_blank">this handy entry on the Python wiki</a> I found later.  Keep in mind that we weren&#8217;t using a deque and pop(0) is very similar to remove.  By making this mistake, I had accidentally made my linear algorithm a quadratic algorithm. This is exactly the type of silly mistake I would have never noticed without profiling. With the continued help of profiling, I was able to make other little tweaks with memory allocation and method calls that resulted in shrinking the post-processing time down to a palatable sub-second latency.  Here&#8217;s a traceview of the work done generating a typical latency histogram:</p>
<p style="text-align: center;"><img class="aligncenter" title="traceview of latency histogram" src="http://i.imgur.com/qpfEi.png" alt="traceview of latency histogram" width="580" height="202" /></p>
<p>The entire trip from gathering the request, seeking the data, processing, and returning the data now maxes out at a few seconds. I&#8217;d say that is certainly a fair improvement from two minutes by anyone&#8217;s standard.  If a fresh intern could speed up something in the Tracelytics web app 100 fold, imagine what you can do to your app!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tracelytics.com/blog/efficient-histograms-via-quantile-summarization/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New in Tracelytics: Alerts 2.0 including Host Metrics</title>
		<link>http://www.tracelytics.com/blog/new-in-tracelytics-alerts-2-0-including-host-metrics/</link>
		<comments>http://www.tracelytics.com/blog/new-in-tracelytics-alerts-2-0-including-host-metrics/#comments</comments>
		<pubDate>Mon, 16 Apr 2012 10:15:33 +0000</pubDate>
		<dc:creator>TR Jordan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.tracelytics.com/blog/?p=865</guid>
		<description><![CDATA[We&#8217;re pleased to announce a major update to Tracelytics Alerts. We first released Alerts a few months back, which would notify you based on anomolous latency on your apps. We&#8217;ve just released three additional categories of Alerts: Layer latency, error rate, and host metrics. Let&#8217;s look at each of these. Layer Latency Latency is one [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;re pleased to announce a major update to Tracelytics Alerts. We first released Alerts a few months back, which would notify you based on anomolous latency on your apps. We&#8217;ve just released three additional categories of Alerts: Layer latency, error rate, and host metrics. Let&#8217;s look at each of these.</p>
<h2>Layer Latency</h2>
<p>Latency is one of the most important metrics available for keeping tabs on your website. Not only does it affect the user experience, but it can also serve as an early warning for lower-level operational issues. However, setting a single alert on a complex system is very unreliable &#8212; setting a high upper bound provides good protection against catastrophic failure, but what about finer-grained visibility? MySQL has a completely different latency distribution than Apache, and their failure modes can be quite different.<a href="http://www.tracelytics.com/blog/new-in-tracelytics-alerts-2-0-including-host-metrics/screen-shot-2012-04-13-at-3-16-24-pm/" rel="attachment wp-att-871"><img class="alignright size-thumbnail wp-image-871" title="Layer Alert Setup" src="http://www.tracelytics.com/blog/wp-content/uploads/Screen-Shot-2012-04-13-at-3.16.24-PM-230x106.png" alt="" width="230" height="106" /></a></p>
<p>That&#8217;s why we are adding layer-based latency alerting. Now you can set alerts on individual layers within your apps. Is memcache evicting too many keys, causing an abundance of slower SETs? Has the data set in MySQL grown beyond memory, causing queries to slow down or time out? Are there queueing problems in Nginx, caused by an influx of users? Layer alerts will alert you to performance issues as they develop, so that you can get in front of them right away.</p>
<h2>Error Rates</h2>
<p><img class="size-medium wp-image-869 alignleft" title="Error rate alert" src="http://www.tracelytics.com/blog/wp-content/uploads/Screen-Shot-2012-04-13-at-3.08.11-PM-300x162.png" alt="" width="300" height="162" /></p>
<p>Another big category we&#8217;re adding is error rates. In an ideal world, your webapp would never encounter an error. Unfortunately, connections fail, APIs get overloaded, and developers even occasionally forget to handle edge cases (shocking, but true). In a complex app, error rates are one of the most important metrics to keep close tabs on. Tracelytics will look for errors anywhere in your app, and report them if they become too numerous. This means we&#8217;ll monitor everything from DB connection errors to 500s from your webserver, and let you know if something looks amiss. We&#8217;ll even email you a list of the most common, recent errors we&#8217;ve seen, so you&#8217;ll know exactly where to jump in to fix it.</p>
<h2>Host Metrics</h2>
<p>While it&#8217;s great to take the 10,000ft view of your application, sometimes you just need to dive down and know what&#8217;s going on at the bare (or virtualized) metal. Tracelytics already lets you visualize host metrics right in the context of your applications performance, so now we&#8217;re taking it one step further and adding alerts on those host metrics. We&#8217;ll notify you when any metric exceeds your configured thresholds, making sure you&#8217;re up to date on exactly what&#8217;s happening.</p>
<div>
<p><a href="http://www.tracelytics.com/blog/new-in-tracelytics-alerts-2-0-including-host-metrics/screen-shot-2012-04-13-at-2-48-24-pm/" rel="attachment wp-att-870"><img class="alignright size-medium wp-image-870" title="Machine Metrics Alert" src="http://www.tracelytics.com/blog/wp-content/uploads/Screen-Shot-2012-04-13-at-2.48.24-PM-300x145.png" alt="" width="300" height="145" /></a><br />
&#8220;But wait!&#8221; you say, &#8220;I run in the cloud! I constantly bring up new instances &#8212; there&#8217;s no way I can set alerts on them as they join my infrastructure.&#8221;</p>
<p>Fortunately, you don&#8217;t have to! All machine metric alerts are set by app &#8212; instead of just watching a single matchine, we&#8217;ll watch all hosts within that app, and let you know if any of them exceed your threshold. If any of the machines in your app get overloaded, we&#8217;ll let you know. From there, you can go straight to the relevant Tracelytics app, see exactly which hosts are having trouble, and how your application is affected.</p>
<h2>Try it out!</h2>
<p>You can set up Alerts now from any of the app or layer pages, or from the newly redesigned Alerts management page. As before, any filters you have applied in the app will carry over when you go to create a latency alert, so you can see the data you&#8217;ll be alerted on before you set up the alert itself. We hope you&#8217;ll find Alerts as useful as we do!</p>
</div>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tracelytics.com/blog/new-in-tracelytics-alerts-2-0-including-host-metrics/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What Is Full Stack Application Tracing?</title>
		<link>http://www.tracelytics.com/blog/what-is-full-stack-application-tracing/</link>
		<comments>http://www.tracelytics.com/blog/what-is-full-stack-application-tracing/#comments</comments>
		<pubDate>Mon, 09 Apr 2012 14:26:46 +0000</pubDate>
		<dc:creator>Dan Kuebrich</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.tracelytics.com/blog/?p=823</guid>
		<description><![CDATA[You have a web app, and you care about its performance. How does Tracelytics look at what it’s doing and help you optimize, troubleshoot, and save time and money? We want to show you how to review the structure of a simple LAMP stack, what insights you can get out of the box, and what [...]]]></description>
			<content:encoded><![CDATA[<p>You have a web app, and you care about its performance. How does Tracelytics look at what it’s doing and help you optimize, troubleshoot, and save time and money? We want to show you how to review the structure of a simple LAMP stack, what insights you can get out of the box, and what kinds of problems you can diagnose using this approach.</p>
<h2>Our Guest Today: LAMP</h2>
<p>You may be familiar with this acronym: <strong>Linux, Apache, MySQL, and PHP</strong>. Of course, Tracelytics works with <a href="http://www.tracelytics.com/features/#!/supported-platforms">many different stacks</a>, but LAMP is a very common web application engine. Here’s what the stack looks like, assuming that your database is running on a separate host, either physically or virtually:</p>
<p style="text-align: center;"><a href="http://www.tracelytics.com/blog/wp-content/uploads/basic_lamp.png"><img class="aligncenter  wp-image-832" title="baisc LAMP stack" src="http://www.tracelytics.com/blog/wp-content/uploads/basic_lamp.png" alt="baisc LAMP stack" width="398" height="262" /></a></p>
<h2>Hosts + Layers = Apps</h2>
<p>Before we get our hands dirty, let’s take a moment to break down the LAMP stack into various parts.</p>
<ul>
<li><strong>Hosts: </strong>Web applications are software running on machines, be they physical or virtual. In this example, the Hosts are alice and bob. Hosts form the underpinning of performance with the resources they provide for the app to consume.</li>
<li><strong>Layers:</strong> Each component that is involved in servicing requests for your app is a Layer of the stack. In this example, Apache, PHP, and MySQL are each considered Layers. Typically, you might think of each service that runs in a distinct process as a different Layer.</li>
<li><strong>Apps:</strong> Finally, your entire production LAMP stack is a logical grouping of software components and hosts that work together to serve requests. Let&#8217;s call this an App. In the simple LAMP case, everything is considered part of the same App. If you have a separate staging environment, that’s a separate App.</li>
</ul>
<h2>How Does Tracelytics Work?</h2>
<p>How does Tracelytics gather data about Hosts, Layers, and Apps? Each is handled slightly differently.  The following diagram illustrates instrumentation points in green.  Explanation follows!</p>
<p><img class="aligncenter  wp-image-835" title="Basic LAMP Instrumented" src="http://www.tracelytics.com/blog/wp-content/uploads/basic_lamp_inst_2.png" alt="Basic LAMP Instrumented" width="398" height="282" /></p>
<ul>
<li><strong>Hosts:</strong> You want to know whether your app is starved for resources or overprovisioned.  For this reason, the Tracelyzer agent, installed on each host,  gathers metrics about utilization of CPU, memory, I/O, etc.  The Tracelyzer is a lightweight daemon, provided as an APT or YUM package, that you can install on every host in your deployment that you want to monitor.</li>
<li><strong>Layers: </strong>Each Layer is presented slightly differently by Tracelytics depending on what features are interesting: for example, when considering the MySQL Layer we are probably interested in queries, tables, and databases, and when looking at Apache we will want to see response codes and HTTP methods. Tracelytics follows requests through your stack, starting at the top layer, which is usually some kind of webserver. To get visibility into the request starting at the web server, you install instrumentation in the form of a plugin module (eg. Apache or Nginx module). In the LAMP stack, this instrumentation watches for when requests arrive into Apache from clients, when Apache passes along the request to PHP, when PHP replies with content, and when Apache finally passes that back to the end-user.</li>
<li><strong>What about getting more detail about MySQL and PHP?</strong> You can go even deeper, if you install instrumentation for the next layer of the stack down: PHP. That instrumentation, provided as a PHP extension, listens for incoming requests (e.g. when Apache hands them off), records interesting events such as calls to MySQL, errors, and more, and then notes when PHP finished processing the request and returned control to Apache. Because PHP is watching what queries it executes, there’s no need to run a modified MySQL server.</li>
<li><strong>Apps:</strong> An app is a logical grouping of Layers running on Hosts. It’s defined by you, the user, to help you keep track of everything you care about. By default, all new layers are added to an app called “default.” User-created apps are defined by their entry point; The point at which requests enter the stack. In our example, that is Apache running on alice. After you have defined the entry points for an app, Tracelytics will follow requests passing through the entry point and automatically populate the remaining hosts and layers in your stack. Because the discovery happens automatically, Tracelytics understands when multiple Apps are sharing Host or Layer resources (eg. a database). A Tracelytics account can support an unlimited number of apps, which can be useful to segment your performance data across different environments.</li>
</ul>
<h2>Solving Performance Problems</h2>
<p>All of this information comes together in Tracelytics to help you solve web application performance problems. Here’s a few examples of finding problems in a LAMP stack.</p>
<ul>
<li><strong>Request Queuing:</strong> One common tuning problem is getting the correct number of worker processes/threads in the application layer.  When this number is too low, it can causes requests to queue in the webserver, a bottleneck adding latency to every request.  Because Tracelytics starts monitoring requests at the web server level, it’s easy to catch this problem&#8211;if too much time is being spent in Apache before the request is handed off to PHP, this is the likely culprit.<br />
<a href="http://www.tracelytics.com/blog/wp-content/uploads/traceview_queue.png"><img class="aligncenter size-medium wp-image-841" title="request queueing traceview" src="http://www.tracelytics.com/blog/wp-content/uploads/traceview_queue-300x50.png" alt="request queueing traceview" width="300" height="50" /></a><br />
In the picture above, we can see that a significant amount of time was spent in the webserver before it was able to pass the request to a worker thread at the app layer.</li>
<li><strong>Bottlenecks:</strong> What&#8217;s the worst leg of the critical path for a given request?  We watch every query made in each trace, which lets Tracelytics show you the low-hanging fruit in terms of slowest queries, frequently-executed queries, and queries that keep users waiting the longest overall. And the same for remote service calls, methods in your app, and more!<br />
<a href="http://www.tracelytics.com/blog/wp-content/uploads/top_queries.png"><img class="aligncenter size-medium wp-image-840" title="top queries" src="http://www.tracelytics.com/blog/wp-content/uploads/top_queries-300x189.png" alt="top queries" width="300" height="189" /></a></li>
<li><strong>Query Loops:</strong> It’s generally faster to retrieve a set of rows from a table all at once rather than making a separate query roundtrip for each. However, an unfortunately common design pattern is to fetch a list of items, then execute some other query (eg. to get an attribute of the item) once for each. This can be hard to catch if you’re just looking at slow query logs, because generally each individual query is relatively quick. But they start to add up. Because Tracelytics is watching each called to request makes, it’s easy to isolate and optimize query loops.<br />
<a href="http://www.tracelytics.com/blog/wp-content/uploads/query_loop1.png"><img class="aligncenter size-medium wp-image-836" title="query loop traceview" src="http://www.tracelytics.com/blog/wp-content/uploads/query_loop1-300x180.png" alt="query loop traceview" width="300" height="180" /></a></li>
<li><strong>Underprovisioning:</strong> Easy juxtaposition of latency graphs and host-level metrics allows you to quickly determine if bad latency is related to lack of machine resources.  That&#8217;s why we pull in host data along with tracing data:<br />
<a href="http://www.tracelytics.com/blog/wp-content/uploads/juxtaposition.png"><img class="aligncenter size-medium wp-image-839" title="memory / latency juxtaposition" src="http://www.tracelytics.com/blog/wp-content/uploads/juxtaposition-300x129.png" alt="memory / latency juxtaposition" width="300" height="129" /></a><br />
Look at how the latency rise coincides with increased memory pressure and CPU utilization&#8211; Perhaps you just diagnosed a memory leak?</li>
</ul>
<p>Let us know if you have questions or comments about this, or other ideas about ways you could use these tools to diagnose performance issues in your application.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tracelytics.com/blog/what-is-full-stack-application-tracing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>We&#8217;re Out To Trace Everything: Behind The Tracelytics Series A Funding</title>
		<link>http://www.tracelytics.com/blog/trace-everything-behind-the-tracelytics-series-a-funding/</link>
		<comments>http://www.tracelytics.com/blog/trace-everything-behind-the-tracelytics-series-a-funding/#comments</comments>
		<pubDate>Mon, 26 Mar 2012 08:59:31 +0000</pubDate>
		<dc:creator>Spiros Eliopoulos</dc:creator>
				<category><![CDATA[Company news]]></category>

		<guid isPermaLink="false">http://www.tracelytics.com/blog/?p=771</guid>
		<description><![CDATA[Running a modern web application&#8211;a complex distributed system&#8211;is hard. That’s why we’re excited to announce a $5.2 million round of funding that will allow us to deliver our unique smart tracing to more web applications, empowering customers with actionable insights that help solve problems faster. Here’s a few ways that Tracelytics is ahead of the [...]]]></description>
			<content:encoded><![CDATA[<p>Running a modern web application&#8211;a complex distributed system&#8211;is hard. That’s why we’re excited to announce a $5.2 million round of funding that will allow us to deliver our unique smart tracing to more web applications, empowering customers with actionable insights that help solve problems faster.</p>
<p>Here’s a few ways that Tracelytics is ahead of the pack, a bit about why we raised this money, and where it’s going to take us. Hang on!</p>
<h2>Smart Tracing</h2>
<h3>Beyond Monolithic</h3>
<p>The modern web application spans layers, hosts, and applications&#8211;why settle for partial and piecemeal visibility into your stack? Tracelytics is the only application performance management solution that provides full-stack visibility, following requests across boundaries between layers, hosts, and applications. Our smart tracing goes the extra mile so that you can solve tough problems that would be overlooked by legacy solutions. We are now able to use our smart tracing in PHP, Python, and Ruby, and we&#8217;re working on more for the future.</p>
<h3>Beyond Averages</h3>
<p>Traditional APM figures out which questions you might ask and presents the minimum data necessary to answer those, often in the form of averages you wish you could break down just a bit farther. Our innovative <a href="http://www.tracelytics.com/features/#!/end-to-end-tracing">heatmaps and data-sifting features</a> help answer questions that you&#8211;and we&#8211;haven’t even thought of yet. We&#8217;ve now analyzed over 500 million individual traces sent to us by our customers and users since launching the software, and helped them understand what that data really means.</p>
<p><a href="http://www.tracelytics.com/features/#!/end-to-end-tracing"><img class="aligncenter size-full wp-image-806" title="heatmap-the-stack" src="http://www.tracelytics.com/blog/wp-content/uploads/heatmap-the-stack.png" alt="Application Stack Heatmap" width="650" height="340" /></a></p>
<h3>Beyond Per-Host Pricing</h3>
<p>Are you stuck paying per-host to get visibility into your apps, even in the autoscaling world of the cloud?  Tracelytics is priced based on the <a href="http://www.tracelytics.com/pricing/">configurable volume of requests</a> you decide to trace—not a legacy per-host model. Install everywhere, get visibility into your entire infrastructure, and pay only for what you use. With Tracelytics, you won’t have to cut corners to keep your costs down.</p>
<h2>New Free 30-Day Premium Plan Trial</h2>
<p>We’re also launching our new 30-day free trial, letting you experience the best of Tracelytics with full access to the Premium plan. Try it out today&#8211;no credit card is required and you’ll be up and tracing in minutes. If you&#8217;re ready to start really understanding what makes your web application tick and how to improve it, <a href="http://www.tracelytics.com/signup" target="_blank">you can sign up now</a>, or watch a <a href="http://www.tracelytics.com/tour/" target="_blank">2-minute install walkthrough</a>. It&#8217;s really that fast.</p>
<h2>What’s Next</h2>
<p>We’ve raised this money for two reasons: to keep improving the most comprehensive and powerful full-stack APM solution, and to scale our sales and marketing functions as a business.  In support of this growth, the company, currently located in Providence, RI, is opening a headquarters in Boston.</p>
<p>We&#8217;re also hiring, and already we are welcoming two awesome new team members: say hello to Sarah Ducas and Brian Whalley!  Could you be the next tracer?  <a href="http://www.tracelytics.com/about-us/" target="_blank">Check out our jobs page</a>.</p>
<p>And last but certainly not least: we’ll also be sharing a number of new innovations and features in the coming months—stay tuned!</p>
<h2>Our Investors and Allies</h2>
<p>Bain Capital Ventures joins our existing investors Google Ventures, Battery Ventures, and Flybridge Capital Partners in backing Tracelytics. Bain brings to the table deep knowledge of the application performance management space as well as a hands-on approach that has impressed us from the beginning. We’re also supported by a heavenly choir of angel investors and, of course, our customers and fans.</p>
<p>Together, we are making the web a faster and more reliable place.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tracelytics.com/blog/trace-everything-behind-the-tracelytics-series-a-funding/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Recording operations events: tlog</title>
		<link>http://www.tracelytics.com/blog/recording-operations-events-tlog/</link>
		<comments>http://www.tracelytics.com/blog/recording-operations-events-tlog/#comments</comments>
		<pubDate>Wed, 21 Mar 2012 00:47:30 +0000</pubDate>
		<dc:creator>Dan Kuebrich</dc:creator>
				<category><![CDATA[Features]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[operations]]></category>
		<category><![CDATA[tlog]]></category>

		<guid isPermaLink="false">http://www.tracelytics.com/blog/?p=724</guid>
		<description><![CDATA[If you&#8217;ve ever been on the ops team for a web application, you&#8217;ve probably noticed that many performance degradations and even downtime incidents are caused by human error. Sometimes that takes the form of misconfiguration, but often it&#8217;s a performance or availability problem due to regressions in application code. There&#8217;s therefore a strong incentive to [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve ever been on the ops team for a web application, you&#8217;ve probably noticed that many performance degradations and even downtime incidents are <a title="human error as contributor to downtime" href="http://www.computerworld.com/s/article/9180479/Stupid_data_center_tricks" target="_blank">caused by human error</a>. Sometimes that takes the form of misconfiguration, but often it&#8217;s a performance or availability problem due to regressions in application code.</p>
<p>There&#8217;s therefore a strong incentive to maintain a record of all operations events (releases, configuration changes, upgrades) that can be easily correlated with performance and error data to quickly resolve problems and find root cause for issues.  That&#8217;s why Tracelytics provides an API for recording operations events.</p>
<p>In this blog post, I&#8217;ll introduce you to using our command-line tool tlog to annotate events in Tracelytics, and then go through a quick case study of how we (and our customers) use it to track regressions in code.</p>
<h2>Introducing tlog</h2>
<p>The tlog tool is a command-line client for the API that allows you to report system-wide events that appear as annotations above the charts shown in Tracelytics.   It is automatically installed as part of the tracelyzer package, so you can run tlog wherever you are tracing.</p>
<pre class="brush: plain; title: ; notranslate">
$ tlog --help
Usage: tlog [options] [MESSAGE]
Logs an annotation message for viewing in Tracelytics.

Options:
  -h, --help   show this help message and exit
  -m MESSAGE   specifies the message to report.
  -a APPNAME   specifies an app to which this message belongs. (optional)
  -H HOSTNAME  specifies an alternate hostname associated with this
                   message. (optional)
</pre>
<p>It will then show up like this on your charts and heatmaps (though collapsed by default):</p>
<p style="text-align: center;"><a href="http://www.tracelytics.com/blog/wp-content/uploads/annotation_demo.png"><img class="aligncenter size-large wp-image-739" title="tlog and annotations!" src="http://www.tracelytics.com/blog/wp-content/uploads/annotation_demo-650x210.png" alt="tlog and annotations!" width="650" height="210" /></a></p>
<p>It&#8217;s that simple!  Here&#8217;s <a title="support documentation for tlog" href="http://support.tracelytics.com/kb/instrumenting-your-app/recording-system-events-with-tlog" target="_blank">the full tlog documentation</a>.</p>
<h2>Integrating annotations with operations processes</h2>
<p>Of course, for these ops annotations to be useful they have to exist! That&#8217;s why we provide the command line tlog client that&#8217;s easy to integrate with your deployment and operations processes. The most common way this is used is to note new code deployments. Here&#8217;s a screenshot from a <a title="seatgeek tracelytics blog post" href="http://seatgeek.com/blog/dev/performance-monitoring-with-tracelytics" target="_blank">great blog post </a>written by SeatGeek:</p>
<p style="text-align: center;"><a href="http://seatgeek.com/blog/dev/performance-monitoring-with-tracelytics"><img class="aligncenter size-medium wp-image-740" title="SeatGeek performance monitoring with Tracelytics" src="http://www.tracelytics.com/blog/wp-content/uploads/seatgeek_crop-300x248.png" alt="SeatGeek performance monitoring with Tracelytics" width="300" height="248" /></a></p>
<p>You can see here that a performance issue was resolved by a subsequent deployment of code.</p>
<p>Okay, great, so how would I do that?  For a basic approach, you&#8217;d just have your deploy scripts execute something along the lines of:</p>
<pre class="brush: plain; title: ; notranslate">
$ tlog -m &quot;Pushed a new release.&quot; -a &quot;My_AppName&quot;
</pre>
<p>For a more interesting example, which integrates the git branch and commit hash, here&#8217;s a fabric snippet that we use in our deploy automation:</p>
<pre class="brush: python; title: ; notranslate">
def _tlog_deploy(app, extra=None):
    user = local(&quot;whoami&quot;)
    host = run(&quot;hostname&quot;)
    with cd(&quot;/deploy/tracelons/tracelytics&quot;):
        branch = run(&quot;git branch | grep '*' | cut -d' ' -f2&quot;)
        commit = run(&quot;git log | head -n1 | cut -d' ' -f2&quot;)
    if extra:
        extra = ' ' + extra
    else:
        extra = ''

    with settings(warn_only=True):
        run('tlog -m &quot;[deploy] %s deployed %s (%s) on %s%s&quot; -a &quot;%s&quot;'
                % (user, branch, commit, host, extra, app))
</pre>
<h2>In practice: finding a performance regression</h2>
<p>It&#8217;s always great eat your own dog food, even if sometimes it&#8217;s embarrassing to get caught eating dog food.  So, here&#8217;s just one incident in which we used Tracelytics to ensure that Tracelytics was running well.</p>
<p>After noting that one of our chart endpoints was suddenly causing latency alerts, we investigated in Tracelytics and  noticed that requests to our web app were spending more time in the MySQL layer than they had previously:</p>
<div id="attachment_741" class="wp-caption aligncenter" style="width: 577px"><a href="http://www.tracelytics.com/blog/wp-content/uploads/self_case_1.png"><img class="size-full wp-image-741" title="early warning of a performance issue" src="http://www.tracelytics.com/blog/wp-content/uploads/self_case_1.png" alt="early warning of a performance issue" width="567" height="360" /></a><p class="wp-caption-text">early warning of a performance issue!</p></div>
<p>And it turned out that this coincided with a code release—how unexpected!  Because we do very frequent releases inspired by continuous deployment, we already knew where to look.  In fact, a re-factored query had lost a constraint on a subquery which caused it to be doing work that was later thrown away by app logic.</p>
<p>So we were able to quickly find the issue, but as usual there&#8217;s more than one way to skin a cat.  In this case we were able to verify the problem using Tracelytics before even looking at the commits and code involved. Drilling down on the MySQL layer, we were led to a particular recently slow query,  as well as traces showing the circumstances under which it manifested:</p>
<p><a href="http://www.tracelytics.com/blog/wp-content/uploads/self_case_2.png"><img class="aligncenter size-full wp-image-742" title="a very slow query" src="http://www.tracelytics.com/blog/wp-content/uploads/self_case_2.png" alt="a very slow query" width="572" height="517" /></a></p>
<p>Fortunately, in addition to being easy to track down, the issue was also easy to resolve!</p>
<h2>Beyond tlog</h2>
<p>Looking to get the most out of Tracelytics?  This isn&#8217;t the only way to extend your visibility: check out <a title="PHP Framework Instrumentation" href="http://www.tracelytics.com/blog/2012/03/php-framework-instrumentation/" target="_blank">last week&#8217;s post on framework instrumentation</a>, or head to the documentation to read about the <a title="Custom Instrumentation" href="http://support.tracelytics.com/kb/instrumenting-your-app/extending-tracelytics-customizing" target="_blank">custom event API</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tracelytics.com/blog/recording-operations-events-tlog/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP Framework Instrumentation</title>
		<link>http://www.tracelytics.com/blog/php-framework-instrumentation/</link>
		<comments>http://www.tracelytics.com/blog/php-framework-instrumentation/#comments</comments>
		<pubDate>Mon, 12 Mar 2012 14:58:25 +0000</pubDate>
		<dc:creator>Dan Kuebrich</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.tracelytics.com/blog/?p=708</guid>
		<description><![CDATA[We love it when our users explore our custom instrumentation API and we love it even more when they share the results of their labor. Today we&#8217;re showcasing user-crafted plug-ins that extend the functionality of tracing for two PHP frameworks: Drupal and ExpressionEngine. Drupal The Drupal module for Tracelytics captures the currently active menu item [...]]]></description>
			<content:encoded><![CDATA[<p>We love it when our users explore our custom instrumentation API and we love it even more when they share the results of their labor. Today we&#8217;re showcasing user-crafted plug-ins that extend the functionality of tracing for two PHP frameworks: Drupal and ExpressionEngine.</p>
<h2>Drupal</h2>
<p>The <a href="http://drupal.org/project/tracelytics" target="_blank">Drupal module for Tracelytics</a> captures the currently active menu item and source file (what might be considered Drupal&#8217;s equivalent to actions and controllers) as well as optionally partitioning traffic into different categories based on whether the user is anonymous, logged in, administrator, or whether it&#8217;s actually an action running from shell or cron.  Finally, all of this is configurable through Drupal&#8217;s admin system.</p>
<p>It&#8217;s under development on drupal.org &#8212; <a href="http://drupal.org/project/tracelytics" target="_blank">check it out</a>!</p>
<h2>ExpressionEngine</h2>
<p>If you&#8217;re running ExpressionEngine, you can get improved reporting of controller and action information by using Ian Cook&#8217;s EE hooks for tracing. They actually have New Relic hooks built in as well for comparison. The code snippet, as well as more background, <a href="http://learningsomethingnewwith.wordpress.com/2012/03/04/instrumenting-expressionengine-with-tracelytics-and-new-relic/" target="_blank">is available here</a>.</p>
<h2>Other frameworks</h2>
<p>Of course, Drupal and Expression Engine aren&#8217;t the only frameworks in the world—far from it! We also have <a href="http://support.tracelytics.com/kb/instrumenting-your-app/instrumenting-codeigniter-php-apps" target="_blank">CodeIgniter hooks documented</a>, as well as modules for several Python and Ruby frameworks (see <a href="http://support.tracelytics.com" target="_blank">support.tracelytics.com</a>).  But what if you are using something else? Read on to find out how simple it is to add custom tracing data with Tracelytics.</p>
<h2>Custom instrumentation API</h2>
<p>There&#8217;s a lot of things Tracelytics can tell you about your app right out-of-the-box—what errors are happening, what URLs are slow, which queries could use some optimization, etc. But answering some questions, like “what controller and action am I in?” or &#8221; is this a logged in session?&#8221; requires a bit of insight into the actual application logic. Using our custom instrumentation API, it&#8217;s super easy to add extra information to your traces in semantically meaningful ways.</p>
<p>There&#8217;s documentation available on our support site, but here&#8217;s a quick concrete example. We&#8217;ve mentioned controllers and actions several times in this post—these are great to annotate on traces so that Tracelytics can group requests intelligently, and they are super easy to add even if you are running a custom framework. Simply call oboe_log (or the equivalent in Python/Ruby) with an associative array containing the keys Controller and Action, like so:</p>
<pre class="brush: php; title: ; notranslate">
oboe_log(&quot;info&quot;, array(&quot;Controller&quot; =&gt; $controller,
                       &quot;Action&quot; =&gt; $action));
</pre>
<p>&#8230;which will give you a new way to break up and drill down on your data:</p>
<p><img class="aligncenter" title="Custom Instrumentation" src="http://i.imgur.com/xsppZ.png" alt="" width="447" height="201" /></p>
<pre></pre>
<p>Of course there&#8217;s tons more you can do—segment API traffic and real-user traffic, log errors on 404s, profile heavy parts of your application code—check out <a title="Tracelytics documentation" href="http://support.tracelytics.com" target="_blank">the documentation</a> for some ideas.  And let us know what you come up with; we&#8217;re happy to hook you up with some free tracing in exchange!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tracelytics.com/blog/php-framework-instrumentation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New Feature: Tracelytics Page Guide</title>
		<link>http://www.tracelytics.com/blog/new-feature-tracelytics-page-guide/</link>
		<comments>http://www.tracelytics.com/blog/new-feature-tracelytics-page-guide/#comments</comments>
		<pubDate>Wed, 07 Mar 2012 22:45:03 +0000</pubDate>
		<dc:creator>Brian Fleming</dc:creator>
				<category><![CDATA[Features]]></category>

		<guid isPermaLink="false">http://www.tracelytics.com/blog/?p=673</guid>
		<description><![CDATA[Web apps are always getting more complex and distributed, so it&#8217;s important that Tracelytics both lets you cut right to the heart of your data and is also dead-simple to use. We&#8217;re always pushing the envelope on consumable, insightful data with innovative visualizations, customizable interfaces and timely delivery of information, so it&#8217;s good to take a step back and [...]]]></description>
			<content:encoded><![CDATA[<p>Web apps are always getting more complex and distributed, so it&#8217;s important that Tracelytics both lets you cut right to the heart of your data and is also dead-simple to use. We&#8217;re always pushing the envelope on consumable, insightful data with <a title="Focus on Data: Eliminating Visualization Noise" href="http://www.tracelytics.com/blog/2011/10/focus-on-data-eliminating-visualization-noise/">innovative visualizations</a>, <a title="Partition your website, your way" href="http://www.tracelytics.com/blog/2012/01/partition-your-website-your-way/">customizable interfaces</a> and <a title="Introducing Tracelytics Alerts" href="http://www.tracelytics.com/blog/2012/02/introducing-tracelytics-alerts/">timely delivery of information</a>, so it&#8217;s good to take a step back and make sure that Tracelytics is also dead-simple to use.  It&#8217;s fine for your app to be complicated, but that doesn&#8217;t mean that managing its performance needs to be as well.</p>
<h2>The problem</h2>
<p>Since performance data is complex and there are many ways to examine it, we wanted to make sure you are getting the most out of the Tracelytics interface.  Some apps tackle the problem with persistent contextual help paired with key page elements (we&#8217;ve tried that). Other apps use offsite documentation where they can elaborate on use cases (<a title="Tracelytics Support Documentation" href="http://support.tracelytics.com" target="_blank">we have that too</a>).  Still others use more conversational documentation such as blogs to call attention to features (hopefully why you&#8217;re reading this).</p>
<h2>What we decided to do</h2>
<p><a href="http://www.tracelytics.com/blog/?attachment_id=685#main"><img class="aligncenter size-full wp-image-685" title="pg_full" src="http://www.tracelytics.com/blog/wp-content/uploads/pg_full.png" alt="Tracelytics Page Guide" width="1318" height="517" /></a></p>
<p>Today we are announcing the Tracelytics Page Guide. This is a dynamic in-page contextual help system that we  use to call attention to important page features, use cases, tips &amp; tricks and anything else to help you reach insightful understanding of your data as fast as possible. Unlike persistent help (those little ? icons you see in some apps), the page guide doesn&#8217;t get in your way after you&#8217;ve learned about the features of a page. But it&#8217;s always waiting for you on the sidelines, just in case you need a refresher. Unlike documentation sites and manuals, it is attached to page elements so there is no confusing where the feature is located. Finally, the Page Guide is dynamic: the items in the guide depend on what features you see on the screen.</p>
<h2>How does it work?</h2>
<p>Pinned to the right side of your browser window, on pages with features and elements we think you should know about, you will see the Page Guide icon.</p>
<p><a href="http://www.tracelytics.com/blog/?attachment_id=687#main"><img class="aligncenter size-full wp-image-687" title="pg_icon" src="http://www.tracelytics.com/blog/wp-content/uploads/pg_icon.png" alt="Page Guide Icon" width="317" height="239" /></a></p>
<p>Click on the Page Guide icon and you will see numbered flags get attached to various elements on the page.</p>
<p><a href="http://www.tracelytics.com/blog/?attachment_id=689#main"><img class="aligncenter size-full wp-image-689" title="pg_flag" src="http://www.tracelytics.com/blog/wp-content/uploads/pg_flag.png" alt="Page Guide Flag" width="132" height="132" /></a></p>
<p>We highlight the element that the Page Guide description is about. Clicking on any of the numbered flags updates the description at the bottom of the screen with info on the item you&#8217;re interested in.</p>
<p><a href="http://www.tracelytics.com/blog/?attachment_id=692#main"><img class="aligncenter size-full wp-image-692" title="pg_desc" src="http://www.tracelytics.com/blog/wp-content/uploads/pg_desc.png" alt="Page Guide Description" width="1318" height="185" /></a></p>
<p>You can also scroll through the Page Guide items using the previous and next arrows in the description area, providing a tour-like experience:</p>
<p><img class="aligncenter size-full wp-image-690" title="pg_pager" src="http://www.tracelytics.com/blog/wp-content/uploads/pg_pager.png" alt="Page Guide Pager" width="266" height="158" /></p>
<p>You won&#8217;t see the Page Guide on all pages in the app&#8211;currently, it&#8217;s applied to a few representative pages&#8211;but that doesn&#8217;t mean we&#8217;re done!  Feel free to <a title="contact@tracelytics.com" href="mailto:contact@tracelytics.com">email us</a>, <a title="Tracelytics Twitter" href="http://twitter.com/Tracelytics" target="_blank">tweet us</a>, or jump in our IRC channel at #tracelytics on freenode and let us know what pages or features we should make sure to get into the guide in the coming days.</p>
<h2>One more thing…</h2>
<p>We think that pageguide.js could help a lot of other apps and sites so we&#8217;re thinking about open sourcing it.  Just like feature requests, <a title="contact@tracelytics.com" href="mailto:contact@tracelytics.com">email</a>, <a title="Tracelytics Twitter" href="http://twitter.com/Tracelytics" target="_blank">tweet</a>, or IRC if you think this is a good idea, want to contribute, or just want to say hi!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tracelytics.com/blog/new-feature-tracelytics-page-guide/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Announcing Open Registration!</title>
		<link>http://www.tracelytics.com/blog/announcing-open-registration/</link>
		<comments>http://www.tracelytics.com/blog/announcing-open-registration/#comments</comments>
		<pubDate>Mon, 27 Feb 2012 15:27:56 +0000</pubDate>
		<dc:creator>Dan Kuebrich</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.tracelytics.com/blog/?p=656</guid>
		<description><![CDATA[Beginning today, no invitation is required to register a Tracelytics account and start tracing.  If that&#8217;s all you needed to read, click here to sign up!  In just minutes, you&#8217;ll be tracing requests, getting unparalleled insight, and solving problems. There&#8217;s also a few new features we&#8217;ve introduced and changes we&#8217;ll be rolling out over the [...]]]></description>
			<content:encoded><![CDATA[<p>Beginning today, no invitation is required to register a Tracelytics account and start tracing.  If that&#8217;s all you needed to read, <a title="Sign up for Tracelytics!" href="https://www.tracelytics.com/signup" target="_blank">click here to sign up!</a>  In just minutes, you&#8217;ll be tracing requests, getting unparalleled insight, and solving problems.</p>
<p>There&#8217;s also a few new features we&#8217;ve introduced and changes we&#8217;ll be rolling out over the next few weeks.  Here&#8217;s a quick overview:</p>
<h2>Trace Cap Enforcement</h2>
<p>We price our service per-trace because we believe your visibility shouldn&#8217;t be limited by per-host fees, but rather provided on a pay-as-you-go basis&#8211;just like cloud infrastructure. Deploy the Tracelytics agents across your entire infrastructure and only pay for the actual volume of traces you consume.</p>
<p>Beginning March 15th, we&#8217;ll be enforcing limits on traces per month according to the plan you&#8217;re subscribed to.  This means that after your monthly allotment of traces, plus a grace window, your account will stop processing new data until the end of your billing month.  You won&#8217;t be cut off from the data&#8211;you will still have access to the traces processed up until the cutoff&#8211;but the data will no longer be live.</p>
<p>To help make this a smooth transition, we&#8217;re providing several new ways to be updated on trace consumption.  A meter in the app will keep track of traces used, and you&#8217;ll be automatically warned (via email) if you&#8217;re getting close to the limit or exceeding it.  Finally, as mentioned above, this is a soft limit: we&#8217;ll process a few extra traces for users that are only slightly over.</p>
<h2>Email as Login</h2>
<p>No more remembering service-specific usernames!  Just use the email you registered with to log in to your Tracelytics account(s).</p>
<h2>Alerts</h2>
<p>You don&#8217;t need to be logged into Tracelytics every minute of the day to stay on top of your site&#8217;s performance.  With <a title="Introducing Tracelytics Alerts" href="http://www.tracelytics.com/blog/2012/02/introducing-tracelytics-alerts/" target="_blank">alerts</a>, set up latency constraints and be notified when your app is in violation.  We&#8217;ll take care of the math to make sure it&#8217;s not just a fluke triggering the alert.  Coming soon: alerting on machine metrics!</p>
<h2>Partitions</h2>
<p>Ever wondered how your app performs for logged in vs logged out users?  Browsers vs web crawlers?  User type A vs user type B?  With <a title="Partition your website, your way" href="http://www.tracelytics.com/blog/2012/01/partition-your-website-your-way/" target="_blank">partitions</a>, you can segment data in Tracelytics to reflect the populations you want to get insight on.</p>
<h2>And Lastly: A Big Thanks!</h2>
<p>It&#8217;s important to thank our beta and early-adopter users who helped make Tracelytics what it is today&#8211;you guys rock!  The feedback isn&#8217;t over; we&#8217;re always looking to hear your thoughts.  Get in touch with us at <a title="contact@tracelytics.com" href="mailto:contact@tracelytics.com">contact@tracelytics.com</a>, on <a title="Tracelytics support" href="https://login.tracelytics.com/account/support" target="_blank">our support site</a>, or chat with us in IRC on freenode at #tracelytics.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tracelytics.com/blog/announcing-open-registration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing Tracelytics Alerts</title>
		<link>http://www.tracelytics.com/blog/introducing-tracelytics-alerts/</link>
		<comments>http://www.tracelytics.com/blog/introducing-tracelytics-alerts/#comments</comments>
		<pubDate>Tue, 07 Feb 2012 12:01:08 +0000</pubDate>
		<dc:creator>TR Jordan</dc:creator>
				<category><![CDATA[Features]]></category>

		<guid isPermaLink="false">http://www.tracelytics.com/blog/?p=613</guid>
		<description><![CDATA[Modern web systems are complex, and running them is not easy. Even a robust, well-designed system requires constant maintenance and tuning just to make sure it runs smoothly. Here at Tracelytics, we&#8217;re constantly working to tame that complexity and make running websites simpler, easier, and more intuitive. To that end, we&#8217;re exicted to announce a [...]]]></description>
			<content:encoded><![CDATA[<p>Modern web systems are complex, and running them is not easy. Even a robust, well-designed system requires constant maintenance and tuning just to make sure it runs smoothly. Here at Tracelytics, we&#8217;re constantly working to tame that complexity and make running websites simpler, easier, and more intuitive. To that end, we&#8217;re exicted to announce a new feature: Tracelytics Alerts.</p>
<p>Tracelytics Alerts are similar to other monitoring solutions, with one important difference. Instead of keeping track of machine availability, network connectivity, or other low-level metrics, Alerts measures what matters most: your website&#8217;s performance. Performance is more that just <a title="Let’s Talk About Your Performance" href="http://www.tracelytics.com/blog/2011/10/hello-world/">latency distributions and sparklines</a>; it is a direct measure of how effectively you are serving your content to users. Because of this, measuring, tracking, and keeping you up-to-date on your website&#8217;s responsiveness is a more relevant metric of availability than availability itself.</p>
<p><a href="http://www.tracelytics.com/blog/2012/02/introducing-tracelytics-alerts/good-alert-2/" rel="attachment wp-att-625"><img class="alignright size-large wp-image-625" title="Creating an Alert" src="http://www.tracelytics.com/blog/wp-content/uploads/Good-Alert1-650x287.jpg" alt="" width="650" height="287" /></a></p>
<h3>Why Performance Monitoring?</h3>
<p>The reason that performance monitoring is so powerful is simple: high latencies are a leading indicator for downtime and other serious operational issues. Before a machine goes down, either due to a traffic increase, hardware defects, or network contention, it will generally start to fail by responding to existing requests more slowly. For example, a RAID5 array with a bad disk will not stop working; it will simply respond to requests more slowly, due to having to recompute the lost data from checksum blocks. Unless you&#8217;ve had the forsight to set up OS-level monitoring on every critical device on your system, this sort of problem could easily go unnoticed. However, setting up a single top-level Alert can warn you of lurking issues before they become problems.</p>
<div id="attachment_645" class="wp-caption alignright" style="width: 310px"><a href="http://www.tracelytics.com/blog/2012/02/introducing-tracelytics-alerts/spike-crash/" rel="attachment wp-att-645"><img class="size-medium wp-image-645" title="spike-crash" src="http://www.tracelytics.com/blog/wp-content/uploads/spike-crash-300x77.jpg" alt="" width="300" height="77" /></a><p class="wp-caption-text">A latency spike, then 4 hours of downtime. Not good!</p></div>
<h3>Slicing and Dicing</h3>
<p>Because it&#8217;s so important for Alerts to operate on data you already work with, we&#8217;ve built them right into our Layer Summary page, at the App level. Apps tend to be pretty coarsely grained, so Alerts also support filters on domains, URLs, controllers, and actions. Once you&#8217;ve picked a threshold and verified its behavior, we&#8217;ll keep an eye on it. By default, we&#8217;ll email you when something goes wrong, and again when the system recovers. And you can tweak them whenever you like.</p>
<h3>Review and Drilldown</h3>
<p>Of course, learning about a problem is only the beginning of fixing it. Back on the Layer Summary page, we&#8217;ve added a new section devoted to reviewing past Alerts. This shows only existing Alerts that could be triggered by the data on the page. This lets you see your past Alerts, right next to the data that caused them. From here, you can drill down to the offending layer, find the machine that&#8217;s going bad, and make it right at quickly as possible.<a href="http://www.tracelytics.com/blog/2012/02/introducing-tracelytics-alerts/vis-alert-2/" rel="attachment wp-att-637"><img class="aligncenter size-large wp-image-637" title="Layer Summary with Alert" src="http://www.tracelytics.com/blog/wp-content/uploads/vis-alert1-650x450.jpg" alt="" width="650" height="450" /></a></p>
<h4>A note for the mathematically inclined</h4>
<p>As you review past Alerts, you may notice that the data in some charts may seem to disagree with when we saw a violation of your Alert. This is because they are calculated slightly differently. Most data is averaged over the displayed window &#8212; points on the day view are 15 minute averages. To provide up-to-the-minute responsiveness, Alerts (including previews) uses <a href="http://en.wikipedia.org/wiki/Moving_average">exponentially weighted moving averages</a>. This (honestly, fairly boring and standard) way of calculating the current value of a quantity smooths over spikes and noise in the data, while still providing a fast response to meaningful changes.</p>
<h3>Get Started!</h3>
<p>We&#8217;ve already gotten a lot of mileage out of these internally, and we look forward to hearing your feedback. If you think you could benefit from monitoring at a higher level, set up a few Alerts, and let us know what you think!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tracelytics.com/blog/introducing-tracelytics-alerts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Partition your website, your way</title>
		<link>http://www.tracelytics.com/blog/partition-your-website-your-way/</link>
		<comments>http://www.tracelytics.com/blog/partition-your-website-your-way/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 16:29:40 +0000</pubDate>
		<dc:creator>TR Jordan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.tracelytics.com/blog/?p=555</guid>
		<description><![CDATA[One of our ongoing goals is to make sure you can slice up and drill down on your data in any way you need to. Just creating a web app already gives you a lot of ways to do this: we pull out your URLs, controller/actions, apps, and more. Internally, though, there can be even [...]]]></description>
			<content:encoded><![CDATA[<p>One of our ongoing goals is to make sure you can slice up and drill down on your data in any way you need to. Just creating a web app already gives you a lot of ways to do this: we pull out your URLs, controller/actions, apps, and more. Internally, though, there can be even more. To help you tackle that challenge, we&#8217;re excited to annouce a new feature: Partitions. Partitions are a new type of filter that let you tell us what category a particular request falls into, right from inside your code.</p>
<p><a href="http://www.tracelytics.com/blog/2012/01/partition-your-website-your-way/filter/" rel="attachment wp-att-583"><img class="alignright size-medium wp-image-583" title="Filter header" src="http://www.tracelytics.com/blog/wp-content/uploads/filter-300x91.jpg" alt="Partition header" width="300" height="91" /></a></p>
<p>What is this meant for? To help you get started, here&#8217;s a few places we&#8217;ve found partitions to be useful:</p>
<h3>Logged in vs. Logged out</h3>
<p><a href="http://www.tracelytics.com/blog/2012/01/partition-your-website-your-way/cqjdn/" rel="attachment wp-att-578"><img class="alignright size-medium wp-image-578" title="Logged In vs. Logged Out" src="http://www.tracelytics.com/blog/wp-content/uploads/cqJDN-300x252.png" alt="Partition Block" width="300" height="252" /></a></p>
<p>First and foremost, Tracelytics shows you how fast the various contents of your page load, which directly translates to your user&#8217;s experience on your site. Frequently, though, not all users see the same content; specifically, logged in users tend to have a much richer experience. That richness comes at a price, though.</p>
<p>If your pages typically load in 0.8 seconds, is that because everybody is getting a good experience, or is your barebones landing page hiding the fact that most registered users are actually waiting 4 seconds before all their content shows up? With partitions, you can divide up your traffic and make sure that even both groups are seeing the kind of performance you want them to see.  (And it&#8217;s true&#8211;this is important. Just ask <a href="http://www.codinghorror.com/blog/2011/06/performance-is-a-feature.html">Stack Overflow</a>.)</p>
<h3>API vs. Browser vs. Googlebot</h3>
<p>As businesses grow, they frequently run more than just a website. There will be internal tools for both business and development, an API for 3rd-party developers, a beta site for adventurous customers, and more&#8211;often all running from the same codebase on the same hardware. Code and infrastructure reuse is great, but it can make it difficult to understand what kind of experience each group has.</p>
<p>With partitions, you can tag where each request is coming from. That information is propagated to all layers within that app, so even if only your load-balancer knows that the incoming request is for the beta site, you can still view all database queries the beta site incurred (and hopefully see that they&#8217;re better than what you have in prod right now!). Similarly, web crawlers tend to disproportionately visit slow or uninteresting corners of your web site. By separating these requests into their own partition, you can attack and optimize the pages that are slow for real, live users. Partitioning like this ensures that no matter how your users visit your site, they&#8217;ll get a fast, consistent experience.</p>
<h3>Semantic Separation</h3>
<p><a href="http://www.tracelytics.com/blog/2012/01/partition-your-website-your-way/ksyus/" rel="attachment wp-att-588"><img class="alignright size-medium wp-image-588" title="Semantic Separation" src="http://www.tracelytics.com/blog/wp-content/uploads/kSYUS-262x300.jpg" alt="Semantic Separation" width="262" height="300" /></a></p>
<p>One of the larger chunks of code we have is our trace-processing pipeline. In order to ensure that all our customers get their data in realtime, it&#8217;s important that all the machinery is well-behaved and consistent. All of our customers run different stacks and configurations, and, as a result, their traces turn out a little bit differently. We use partitions to categorize each trace by its dominant layer type, e.g. SQL, services, or profiles. Since we process each of these types in separate modules, they each perform a little differently. Being able to split them up in the same way that we think and talk about them makes debugging and performance tuning that much faster.</p>
<h3>Get to it!</h3>
<p>Hopefully by now, you&#8217;ve thought of some way you could divide up your own apps with partitions. If so, head on over to the <a title="partition documentation" href="https://login.tracelytics.com/account/support_redir?to=http://support.tracelytics.com/kb/instrumenting-your-app/partitions">partition documentation</a>, get started, and let us know how it goes!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tracelytics.com/blog/partition-your-website-your-way/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Performing under pressure, pt. 2: Collecting and visualizing load-test performance data</title>
		<link>http://www.tracelytics.com/blog/performing-under-pressure-pt-2-collecting-and-visualizing-load-test-performance-data/</link>
		<comments>http://www.tracelytics.com/blog/performing-under-pressure-pt-2-collecting-and-visualizing-load-test-performance-data/#comments</comments>
		<pubDate>Wed, 11 Jan 2012 16:12:21 +0000</pubDate>
		<dc:creator>Dan Kuebrich</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.tracelytics.com/blog/?p=423</guid>
		<description><![CDATA[In part 1 of this post, we covered writing web app load tests using multi–mechanize.  This post picks up where the other left off and will discuss how to gather interesting and actionable performance data from the load tests, using (of course) Tracelytics as an example. The big problem we had after writing load tests [...]]]></description>
			<content:encoded><![CDATA[<p>In <a title="part one" href="http://www.tracelytics.com/blog/2012/1/performing-under-pressure-pt-1-load-testing-with-multi-mechanize/">part 1 of this post</a>, we covered writing web app load tests using multi–mechanize.  This post picks up where the other left off and will discuss how to gather interesting and actionable performance data from the load tests, using (of course) Tracelytics as an example.</p>
<p>The big problem we had after writing load tests was that timing data gathered by multi-mechanize is inherently external to the application. This means it can tell us the response times of requests when the app is under load but doesn’t identify bottlenecks or configuration problems. So we need to be gathering a bit more data about how the internals of our web application respond to the workload.</p>
<p>For this blog post, I’ll be using Tracelytics&#8217; instrumentation, which is installable from OS-native packages and, in the case of Reddit, takes care of instrumenting nginx, pylons, SQL queries, memcache calls, and Cassandra calls automatically.</p>
<h2>Test 1: ramp-up read threads</h2>
<pre class="brush: plain; title: ; notranslate">
[global]
run_time: 1800
rampup: 1800
results_ts_interval: 20
progress_bar: on
console_logging: off
xml_report: on
[user_group-1]
threads: 10
script: view_base.py

[user_group-2]
threads: 10
script: view_all.py

[user_group-3]
threads: 10
script: view_all_new.py

[user_group-4]
threads: 10
script: view_all_top.py
</pre>
<p>So, this test is going to run for 30 minutes and generate steadily increasing read-oriented loads on various pages.  Like in a cooking show, I&#8217;ve taken all the waiting out, so let&#8217;s skip straight to the results!</p>
<p>What we’re looking at here is the performance of the deafult open-source Reddit install under a steadily increasing read load, broken down by layer of the stack:</p>
<p><a href="http://www.tracelytics.com/blog/wp-content/uploads/read_stack_1_large.png"><img class="aligncenter size-full wp-image-518" title="read test 1 (small)" src="http://www.tracelytics.com/blog/wp-content/uploads/read_stack_1_small.png" alt="" width="600" height="247" /></a></p>
<p>At first, it performs like a champ. But as the number of concurrent users rises over time, we see that requests slow down. In fact, it looks like we are spending a lot of time per-request in nginx.</p>
<p>We also have access to machine metrics here (blue bar at bottom), so I’ve pulled up the load on the box. Our machine is bored&#8211;the max load the machine reaches is only 1.06&#8211;but it’s serving slowly! This is a sign that we might not have enough worker threads in our application layer.</p>
<p>In fact, the default Reddit install only sets up a single uwsgi worker. So, let’s fix that, and move on. Here’s what it looks like with 10 uwsgi processes, same workload:</p>
<p><a href="http://www.tracelytics.com/blog/wp-content/uploads/read_stack_2_large.png"><img class="aligncenter size-full wp-image-527" title="read stacked (post-proc-increase) (small)" src="http://www.tracelytics.com/blog/wp-content/uploads/read_stack_2_small.png" alt="" width="600" height="198" /></a></p>
<p>It seems that we’ve traded our uwsgi queuing problems for an overloaded machine, but at least it’s fully utilizing the hardware now&#8211;and our throughput is much greater!</p>
<h2>Test 2: ramp-up write threads</h2>
<pre class="brush: plain; title: ; notranslate">
[global]
run_time: 1800
rampup: 1800
results_ts_interval: 10
progress_bar: on
console_logging: off
xml_report: off

[user_group-1]
threads: 10
script: vote_comment.py

[user_group-2]
threads: 10
script: submit_comment.py
</pre>
<p>This test will vote and submit comments on a particular thread with inceasing numbers of logged in users.  Ok, go!</p>
<p><a href="http://www.tracelytics.com/blog/wp-content/uploads/write_heatmap_1.png"><img class="aligncenter size-full wp-image-511" title="write load heatmap" src="http://www.tracelytics.com/blog/wp-content/uploads/write_heatmap_1.png" alt="" width="600" height="409" /></a></p>
<p>One really interesting thing is that we can see there are two distinct trends in the data&#8211;one band grows slower faster than the other.  Selecting them for comparison, we can see that the slower band is for rendering the comments, while the faster one is the POST requests for commenting/voting:</p>
<p><a href="http://www.tracelytics.com/blog/wp-content/uploads/write_comparison_heatmap_large.png"><img class="aligncenter size-full wp-image-512" title="write comparison heatmap (small)" src="http://www.tracelytics.com/blog/wp-content/uploads/write_comparison_heatmap_small.png" alt="" width="600" height="316" /></a></p>
<p>We might have expected to see contention for the database (in this case, postgres).  However, by pushing the limits with our load tests, we figured out that the actual limiting factor will be cores on our app servers (or, in this case, server) before we have to worry about the database.  Here&#8217;s what the breakdown by layer of stack looked like&#8211;note that we&#8217;re spending almost no time in our database calls (measured through sqlalchemy and the Cassandra client):</p>
<p><a href="http://www.tracelytics.com/blog/wp-content/uploads/write_stack_1_large.png"><img class="aligncenter size-full wp-image-525" title="write stacked (small)" src="http://www.tracelytics.com/blog/wp-content/uploads/write_stack_1_small.png" alt="" width="600" height="194" /></a></p>
<h2>Where to go from here:</h2>
<ul>
<li>Performance testing is not only valuable to ensure that a new Web app meets projected demand; it can also be part of your CI system to detect performance regressions during everyday development. Here’s <a title="jenkins screencast" href="http://www.youtube.com/watch?v=HatB6IlCLEs" target="_blank">a screencast about getting performance tests running in Jenkins</a>.</li>
<li>If your website is particularly AJAX-heavy, you may also want to do load testing that simulates a browser better and execute JavaScript in order to create the exact load patterns that users will. This makes testing significantly more resource intensive as it requires spinning up headless browsers, but can be accomplished using <a title="selenium" href="http://seleniumhq.org/" target="_blank">selenium</a> or a hosted selenium service.</li>
<li>Tracelytics performance monitoring and analysis isn’t only for load tests; most of our customers run our lightweight instrumentation in production as well as development environments. <a title="sign up!" href="http://www.tracelytics.com/register/" target="_blank">Sign up for a free trial</a>—no credit card required.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.tracelytics.com/blog/performing-under-pressure-pt-2-collecting-and-visualizing-load-test-performance-data/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Performing under pressure, pt. 1: Load-testing with multi-mechanize</title>
		<link>http://www.tracelytics.com/blog/performing-under-pressure-pt-1-load-testing-with-multi-mechanize/</link>
		<comments>http://www.tracelytics.com/blog/performing-under-pressure-pt-1-load-testing-with-multi-mechanize/#comments</comments>
		<pubDate>Tue, 10 Jan 2012 22:59:46 +0000</pubDate>
		<dc:creator>Dan Kuebrich</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.tracelytics.com/blog/?p=421</guid>
		<description><![CDATA[Many types of performance problems can result from the load created by concurrent users of web applications, and all too often these scalability bottlenecks go undetected until the application has been deployed in production.  Load testing, the generation of simulated user requests, is a great way to catch these types of issues before they get [...]]]></description>
			<content:encoded><![CDATA[<p>Many types of performance problems can result from the load created by concurrent users of web applications, and all too often these scalability bottlenecks go undetected until the application has been deployed in production.  Load testing, the generation of simulated user requests, is a great way to catch these types of issues before they get out of hand.  Last month I presented about load testing with Canonical&#8217;s <a href="http://goldb.org/" target="_blank">Corey Goldberg</a> at the <a title="boston python meetup" href="http://meetup.bostonpython.com/events/36664122/" target="_blank">Boston Python Meetup</a> last week and thought the topic deserved blog discussion as well.</p>
<p>In this two-part series, I&#8217;ll walk through generating load using the Python <a href="http://multimechanize.com" target="_blank">multi-mechanize</a> load testing framework, then collect and analyze data about app performance using Tracelytics.</p>
<p>Also, a request: there&#8217;s <a href="http://wwwsearch.sourceforge.net/mechanize/">mechanize documentation available</a>, but I unfortunately haven&#8217;t found any full documentation of the python mechanize API online&#8211;post a comment if you know where to find it!</p>
<h2>Meet the app: Reddit</h2>
<p>The web app that I&#8217;ll be using for all the examples in this post is an <a title="github/reddit" href="https://github.com/reddit/reddit" target="_blank">open source reddit</a> running on a single node in EC2. You don&#8217;t need to understand how it works in order to enjoy this post, but if you do want to play along, there is a <a title="reddit install script" href="https://github.com/reddit/reddit/wiki/reddit-install-script-for-Ubuntu" target="_blank">super–easy install script</a> that sets up a whole stack.</p>
<h2>Generating the data</h2>
<p>Performance testing can start off simple: hit pages in your app, and monitor how long they take to load. You can automate this using something like the mechanize library in Python, or even something more low level like httplib/urllib2.  This is a good start, but today we’re looking for concurrency as well.</p>
<p>Enter <a href="http://code.google.com/p/multi-mechanize/" target="_blank">multi–mechanize</a>. Multi–mechanize takes simple request or transaction simulation scripts you&#8217;ve written and fires them repeatedly from many threads simultaneously in configurable patterns. It&#8217;s as easy as writing a few scripts that simulate users doing different actions on your website (login, browse, submit comment, etc.) and then writing a short config that tells multi–mechanize how to play them back.</p>
<p>Since our site is reddit, I&#8217;m going to write a few scripts that read discussion threads, one that posts comments, and one that votes on comments. I&#8217;ll walk through writing to of the scripts: a simple read–only request, and more complicated one that logs in and submits a comment. The rest of them are available in the <a href="https://github.com/dankosaur/reddit-loadtest">full source</a> of the load tests on github.</p>
<h2>A simple mechanize script</h2>
<pre class="brush: python; title: ; notranslate">
import mechanize
import time

class Transaction(object):
    def __init__(self):
        self.custom_timers = {}
        self.base_url = 'http://reddit.tracelytics.com'

    def run(self):
        br = mechanize.Browser()
        br.set_handle_robots(False)

        start_timer = time.time()
        resp = br.open(self.base_url + '/r/all/')
        resp.read()
        latency = time.time() - start_timer
        self.custom_timers['All_Items'] = latency
        assert (resp.code == 200), 'Bad HTTP Response'

if __name__ == '__main__':
    trans = Transaction()
    trans.run()
    print trans.custom_timers
</pre>
<p>First, the test is wrapped in a Transaction class—this is how multi–mechanize will run each of your scripts. The __init__() is called once per worker thread, then run() will be invoked repeatedly to generate the requests of your transaction. For development and debugging, it’s easier to just run the scripts individually, so the __main__ block at the end provides that functionality.</p>
<p>All of the work here is happening in the run() method. A mechanize browser is instantiated, and our simple request for the front page of Reddit is performed. Finally, we make sure that a valid page was returned.</p>
<p>There’s one more thing: custom timers.  Multi–mechanize can collect timing information about the requests it performs. If you store that information in a correctly-named dict, it will be able to generate charts of the data later.</p>
<h2>A more complicated script</h2>
<p>Now, let’s take a look at a slightly more complicated script. This one posts a comment on a particular story, so it’ll have to take the following actions:</p>
<ul>
<li>Log in as a user</li>
<li>Open thread page on Reddit</li>
<li>Post comment</li>
</ul>
<p>It&#8217;s a bit longer, so I&#8217;ve broken it up according to the bullets above with accompanying explanation.  The full version of the example can be found here:  <a href="https://gist.github.com/1529242" target="_blank">https://gist.github.com/1529242</a></p>
<pre class="brush: python; title: ; notranslate">
import mechanize
import urllib

BASE_URL = 'http://my-reddit'
THREAD = BASE_URL + '/r/reddit/particular-thread'

class Transaction(object):
    def __init__(self):
        self.user = 'redditor'
        self.pass = 'password'
    def run(self):
        # init browser and cookie jar
        br = mechanize.Browser()
        br.set_handle_redirect(True)
        br.set_handle_referer(True)
        br.set_handle_robots(False)
        # do login
        _ = br.open(BASE_URL)
        br.select_form(nr=1)
        br.form['user'] = self.user
        br.form['passwd'] = self.pass
        r = br.submit()
        r.read()
        assert (r.code == 200), 'Bad HTTP Response'
</pre>
<p>The first thing that’s happening here is familiar: pulling up a page in our mechanize browser. In order to login, though, we need to start interacting with forms on the page, and this means tweaking some of the default mechanize browser settings.  We need to set three attributes on our browser: follow 30x redirects (lets the login redirect back), specify the Referrer page header (validation for comment post), and ignore robots.txt rules (Reddit doesn&#8217;t like robots playing human).</p>
<p>After that, it&#8217;s on to forms.  The mechanize browser interface with forms is pretty simple: you can list all the forms on the page with browser.forms, select a form to interact with using select_form, and then manipulate the fields of the form using the browser.form object.</p>
<p>select_form  can take a variety of selection predicates, most of which revolve around using attributes such as the form’s CSS ID. Our example, Reddit, doesn’t have much identifying information associated with forms, so I’ve used numeric selection to grab them. The login form happens to be form 1.</p>
<pre class="brush: python; first-line: 25; title: ; notranslate">
        # go to comment page
        posting = THREAD
        rval = THREAD.split('/')[4]
        r = br.open(posting)
        r.read()
        assert (r.code == 200), 'Bad HTTP Response'
</pre>
<p>Pretty straightforward: head to the thread page now that we&#8217;re logged in.  Now we want to actually submit the comment.  Here&#8217;s the heavy lifting:</p>
<pre class="brush: python; first-line: 31; title: ; notranslate">
        # load required value from hidden form field
        br.select_form(nr=0)
        uh = br.form['uh']

        # select top-level comment form
        br.select_form(nr=12)
        thing_id = br.form['thing_id']
        id = '#' + br.form.attrs['id']

        # build and submit the comment posting
        data = {'uh':uh, 'thing_id':thing_id, 'id':id, 'renderstyle':'html',
                'r':rval, 'text':&quot;This is such an interesting comment!&quot;}
        nd_dict = dict((k, urllib.quote(v).replace('%20', '+')) for\
                        k,v in data.iteritems())
        new_data = '&amp;'.join(&quot;%s=%s&quot; % (k,v) for k,v in nd_dict.iteritems())

        r = br.open(BASE_URL + '/api/comment', new_data)
        r.read()
        assert (r.code == 200), 'Bad HTTP Response'

if __name__ == '__main__':
    trans = Transaction()
    trans.run()
</pre>
<p>Comment submission is a little bit different because it works via AJAX.  The mechanized browser doesn’t process JavaScript, meaning that we’ll have to take things into our own hands here.  So, we inspect two forms to grab the state information that JavaScript on the page would use to submit the form, and we construct our own request manually.  (Form 0 provides the &#8216;uh&#8217; value in a hidden field; form 12 is the top-level comment submit form.)</p>
<p>In this simple example, user credentials are provided in __init__. However, a more realistic example might involve many different users logging in. In the code on github, I’ve written a <a href="https://github.com/dankosaur/reddit-loadtest/blob/master/projects/reddit_write/test_scripts/util.py#L6" target="_blank">user pool implementation</a> that takes care of this problem by instantiating a pool of logged in users for each script (then, each invocation of run can check out a different user).</p>
<p><em>(Debugging note for those playing along: if comments are not showing up in the thread but are showing up in the users profile, that means that some of the background jobs may not be running correctly. The site re-caches the comment tree asynchronously after posts.)</em></p>
<h2>Running the full load test</h2>
<p>After writing a few individual mechanize scripts, the final step is putting them all together with a multi–mechanize config. Multi-mechanize organizes load tests in terms of “projects” which are represented by subdirectories of a directory called projects. Each project contains a config file and a directory called test_scripts which contains your individual load tests scripts. It should look like this:</p>
<p>The config file specifies how long the load test should run for, whether it should ramp up the amount of pain or keep it constant,  a few output and statistics settings, and of course the number of threads and scripts you want to run. Here’s an example config:</p>
<pre class="brush: plain; title: ; notranslate">
[global]
run_time: 240
rampup: 0
results_ts_interval: 20
progress_bar: on
console_logging: off
xml_report: on

[user_group-1]
threads: 20
script: view_base.py

[user_group-2]
threads: 20
script: view_all.py&lt;/pre&gt;
</pre>
<p>Runtime sets the duration of the test, in seconds. Ramp up, if nonzero, tolls multi-mechanize to linearly increase the number of threads up to the specified numbers during the wrapup.</p>
<p>And here’s how to invoke them, finally:</p>
<pre class="brush: plain; title: ; notranslate">

$ multi-mechanize reddit_read
  user_groups:  2
  threads: 40

[=          6%           ]  14s/240s   transactions: 680  timers: 680  errors: 0
</pre>
<h2>Learning from our load tests</h2>
<p>Multi—mechanize collects statistics about timing information that you provide in your tests (custom_timers) and dumps the output in a results subdirectory of your project. This can easily be plotted in your favorite graphics package.  Here&#8217;s an example of the average times from a read load increasing over 30 minutes:</p>
<p><a href="http://www.tracelytics.com/blog/wp-content/uploads/matplot_multimech.png"><img class="aligncenter size-medium wp-image-543" title="matplot multimech" src="http://www.tracelytics.com/blog/wp-content/uploads/matplot_multimech-300x192.png" alt="" width="300" height="192" /></a></p>
<p>Ok, so it&#8217;s getting slower, but why??  These timers treat the application like a black box—they’ll show you that it can be slow, but you won’t know why or what layers of the stack are slow. In <a title="Performing under pressure, pt. 2: Collecting and visualizing load-test performance data" href="http://www.tracelytics.com/blog/2012/01/performing-under-pressure-pt-2-collecting-and-visualizing-load-test-performance-data/">the next post</a>, we’ll talk about how to gather actionable data from your load tests.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tracelytics.com/blog/performing-under-pressure-pt-1-load-testing-with-multi-mechanize/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>New year, new settings!</title>
		<link>http://www.tracelytics.com/blog/new-year-new-settings/</link>
		<comments>http://www.tracelytics.com/blog/new-year-new-settings/#comments</comments>
		<pubDate>Thu, 05 Jan 2012 18:02:04 +0000</pubDate>
		<dc:creator>Dan Kuebrich</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.tracelytics.com/blog/?p=476</guid>
		<description><![CDATA[Happy new year, tracers!  Today, we&#8217;re rolling out a new Settings page that simplifies Tracelytics configuration.  You can now manage tracing on your different stacks with an improved UI and the help of many requested features such as renaming and deletion.  Here&#8217;s what it looks like and some big improvements we made: 1. Simplified app [...]]]></description>
			<content:encoded><![CDATA[<p>Happy new year, tracers!  Today, we&#8217;re rolling out a new Settings page that simplifies Tracelytics configuration.  You can now manage tracing on your different stacks with an improved UI and the help of many requested features such as renaming and deletion.  Here&#8217;s what it looks like and some big improvements we made:</p>
<p><a href="http://www.tracelytics.com/blog/wp-content/uploads/app_box.png"><img class="alignleft size-full wp-image-485" style="margin-top: 5px; margin-bottom: 5px; margin-left: 10px; margin-right: 10px;" title="app_box" src="http://www.tracelytics.com/blog/wp-content/uploads/app_box.png" alt="" width="205" height="238" /></a></p>
<h3></h3>
<h3></h3>
<h3>1. Simplified app presentation</h3>
<p>Apps are now displayed as an entry point (where requests begin to be traced in the stack) as well as the other component layers and hosts.  Clicking a layer expands the list of hosts, and we automatically remove layers and hosts that aren&#8217;t tracing or get moved to other apps.  We&#8217;ve focused on layers as the components of your stack are likely to be much more static than the hosts they run on.</p>
<p><a href="http://www.tracelytics.com/blog/wp-content/uploads/inline_install.png"><img class="alignright size-medium wp-image-486" title="inline install" src="http://www.tracelytics.com/blog/wp-content/uploads/inline_install-300x185.png" alt="" width="300" height="185" /></a></p>
<h3></h3>
<h3></h3>
<h3>2. Seamless instrumentation of new layers and hosts</h3>
<p>It&#8217;s super-easy to add and configure new apps; now it&#8217;s easy to install new instrumentation as well, with built-in install walkthrough.</p>
<h3></h3>
<h3></h3>
<h3><a href="http://www.tracelytics.com/blog/wp-content/uploads/new_layers.png"><img class="size-full wp-image-484 alignleft" style="margin-top: 5px; margin-bottom: 5px; margin-left: 10px; margin-right: 10px;" title="new hosts and layers" src="http://www.tracelytics.com/blog/wp-content/uploads/new_layers.png" alt="" width="308" height="79" /></a></h3>
<h3>3. Get notified when new layers and hosts appear</h3>
<p>One of the best things about tracing is that it can be extended as you install modules that provide instrumentation for different hosts and parts of your stack.  Now you can keep track of changes in app instrumentation across your deployment.</p>
<h3><a href="http://www.tracelytics.com/blog/wp-content/uploads/rename_delete.png"><img class="size-full wp-image-482 alignright" title="rename/delete" src="http://www.tracelytics.com/blog/wp-content/uploads/rename_delete.png" alt="" width="208" height="42" /></a></h3>
<h3>4. App renaming and deletion</h3>
<p>Just in time for spring cleaning: you can now rename and delete apps.  Renamed apps will keep their current data and configuration, but deletion is a one-way street.</p>
<p><a href="http://www.tracelytics.com/blog/wp-content/uploads/search.png"><img class="size-full wp-image-483 alignleft" style="margin-top: 5px; margin-bottom: 5px; margin-left: 10px; margin-right: 10px;" title="search" src="http://www.tracelytics.com/blog/wp-content/uploads/search.png" alt="" width="200" height="136" /></a></p>
<h3>5. Search</h3>
<p>Trying to make sure everything is in the right place across your handful of deployments?  We&#8217;ve got search for layers and hosts both within as well as across all apps.</p>
<p>Ok!  You can check it out<a title="settings page" href="https://login.tracelytics.com/settings" target="_blank"> live on your app</a>, or <a title="sign up -- free trial!" href="http://www.tracelytics.com/register/" target="_blank">sign up</a> to try out tracing.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.tracelytics.com/blog/new-year-new-settings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Structure of your Success</title>
		<link>http://www.tracelytics.com/blog/the-structure-of-your-success/</link>
		<comments>http://www.tracelytics.com/blog/the-structure-of-your-success/#comments</comments>
		<pubDate>Thu, 10 Nov 2011 23:42:47 +0000</pubDate>
		<dc:creator>TR Jordan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.tracelytics.com/?p=178</guid>
		<description><![CDATA[When you&#8217;re talking about the performance of your site, the first advice you&#8217;ll get is to measure it. Measure the round trip time of the average user&#8217;s TCP connection. Measure the template rendering time. Measure the response time of the memcached cluster. Last time, we talked about the myriad ways you can visualize that data. [...]]]></description>
			<content:encoded><![CDATA[<p><strong>When you&#8217;re talking about the performance of your site, the first advice you&#8217;ll get is to measure it.</strong> Measure the round trip time of the average user&#8217;s TCP connection. Measure the template rendering time. Measure the response time of the memcached cluster. Last time, we talked about the myriad ways you can visualize that data. <strong>Timing measurements aren&#8217;t everything, though.</strong> This time, let&#8217;s talk about the other side of the coin. Let&#8217;s talk about the structure of a request to your web app.</p>
<h2>The Whole Sandwich: Performance by Layer</h2>
<p><span><strong>Structure is simply the call graph of your application.</strong> Complex structure is what makes distributed apps hard to debug and even harder to optimize. Each trace has its own structure, and the relationships within that graph can make or break the performance of a web app.</span></p>
<p><span>When measuring performance, people typically throw away structural information and keep only timing information.  But in order to answer sophisticated questions about web application performance, it helps to know about both the performance and structure of your app.  To make this concrete, let&#8217;s track down a problem in a PHP <span>webapp</span> using <span>Tracelytics</span>.</span></p>
<div id="attachment_261" class="wp-caption aligncenter" style="width: 590px"><a href="http://blog.tracelytics.com/?attachment_id=261#main"><img class="size-full wp-image-261 " title="App performance by layer." src="http://blog.tracelytics.com/wp-content/uploads/b1.png" alt=" stacked area chart" width="580" height="347" /></a><p class="wp-caption-text">(click to enlarge)</p></div>
<p><span>We&#8217;ll start at the app page, looking at the stacked area chart. Remember that this visualization shows us the average request time, broken down by the time spent in each layer. The first thing to notice here is that the performance is wildly inconsistent. Secondly, the variation seems to be largely in PHP and <span>php</span>_<span>mysql</span>, where we have client-side instrumentation of MySQL queries. The largest spikes here put the response time between 200 and 500 ms, but more typically 50 to 100ms. Nothing too surprising here yet &#8212; the variance is a bit worrying, but with fewer than 9,000 traces per week we don&#8217;t expect to see the most consistent measurements.</span></p>
<p><span>Perhaps this variance is due to poorly performing queries&#8211;why don&#8217;t we take a look at an individual layer of our stack next?<br />
</span></p>
<h2>Examining Layer Performance</h2>
<p><span>Let&#8217;s take a look at the queries the app is running by drilling down on the <span>php</span>_<span>mysql</span> layer, where we might expect to find some slow queries.  You might do this with the slow query log, but we can get more info out of a heatmap:</span></p>
<div id="attachment_262" class="wp-caption aligncenter" style="width: 583px"><a href="http://www.tracelytics.com/blog/2011/11/the-structure-of-your-success/b2/" rel="attachment wp-att-262"><img class="size-full wp-image-262" title="Heatmap of query latency." src="http://blog.tracelytics.com/wp-content/uploads/b2.png" alt="heatmap" width="573" height="346" /></a><p class="wp-caption-text">(click to enlarge)</p></div>
<p><span>What we find is something a little less obvious.  Recall that<strong> the heatmap shows us the distribution of calls, broken down by duration, over a period of time</strong>&#8211;like a bunch of histograms next to each other. From the stacked area chart, we saw a lot of time spent in <span>php</span>_<span>mysql</span>, but this graph shows that nearly every call (up to 98%, the default cutoff) completes faster than 12ms, with the majority returning faster than 2ms. Even more striking, the <span>heatmap</span> is showing a total count of more than 2 million calls &#8212; which might  sound like a lot of queries per trace given the 9,000 traces we saw in the stacked area chart.  Where are they all coming from?<br />
</span></p>
<h2>Structured Data to the Rescue<span class="Apple-style-span" style="font-size: 13px; font-weight: normal;"> </span></h2>
<div id="attachment_268" class="wp-caption aligncenter" style="width: 585px"><a href="http://blog.tracelytics.com/?attachment_id=268#main"><img class="size-full wp-image-268" title="A trace with many queries." src="http://blog.tracelytics.com/wp-content/uploads/b31.png" alt="trace view" width="575" height="334" /></a><p class="wp-caption-text">(click to enlarge)</p></div>
<p>By now, what&#8217;s going on may be obvious, but let&#8217;s examine<strong> the trace view, a visualization of the structure of an individual request</strong>, to confirm our intuition.  This particular request actually made <strong>over 1600 calls</strong> to MySQL, most of which were very similar. While each query examined individually is fast, well-indexed, and nicely behaved, the overall request is inconsistent and slow. This is a classic case of putting a query inside of a loop. If we instead retrieved all the needed data at once, we could iterate over it much faster, saving a lot of overhead in round trips and query execution.</p>
<p>In this case, the structure of the request unnecessarily introduced both an absolute delay and an increase in variability to the page load time. <strong>Each layer, examined individually, was performing well, but that&#8217;s not enough to guarantee good performance.</strong> The structure of the application and the quality of the code play just as much of a role as DB tuning and scaling metrics.</p>
<blockquote><p>“The key to performance is elegance, not battalions of special cases.”<br />
<span> &#8211; Jon Bentley and Douglas <span>McIlroy</span></span></p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.tracelytics.com/blog/the-structure-of-your-success/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.871 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-05-18 18:31:10 -->

