<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>StatHat Blog</title>
 <link href="http://blog.stathat.com/atom.xml" rel="self"/>
 <link href="http://blog.stathat.com"/>
 <updated>2019-05-07T11:21:48+07:00</updated>
 <id>http://blog.stathat.com</id>
 <author>
   <name>stat hat</name>
 </author>

 
 <entry>
   <title>Goodbye, api-ssl-balancer</title>
   <link href="http://blog.stathat.com/2018/01/16/goodbye_api_ssl_balancer.html"/>
   <updated>2018-01-16T00:00:00+07:00</updated>
   <id>http://blog.stathat.com/2018/01/16/goodbye_api_ssl_balancer.html</id>
   <content type="html">&lt;p&gt;It is a bittersweet night here at StatHat as we have to say goodbye to one of
our oldest, most hard-working friends: &lt;code&gt;api-ssl-balancer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;api-ssl-balancer&lt;/code&gt; was born on March 18, 2011 at 10:47:00 AM UTC-5.  It has been
the endpoint for &lt;code&gt;api.stathat.com&lt;/code&gt; since the beginning.  Every single data point
on StatHat has gone through its gates: 9.76 &lt;em&gt;trillion&lt;/em&gt; requests and counting.&lt;/p&gt;

&lt;p&gt;In these days of cloud computing where servers are ephemeral and only up for a few
hours or days, we don&amp;rsquo;t have relationships with our servers.  They are no longer
cleverly named after natural disasters or bivalve mollusks. But although it doesn&amp;rsquo;t
have a fancy name, &lt;code&gt;api-ssl-balancer&lt;/code&gt; has been around and unchanged for almost 7 years.&lt;/p&gt;

&lt;p&gt;Through thick and thin, &lt;code&gt;api-ssl-balancer&lt;/code&gt; has always worked.  Over the years, several
availability zones have gone dark, EBS stopped working for a day, EC2 instances
failed to launch, even good old S3 was unavailable.  But &lt;code&gt;api-ssl-balancer&lt;/code&gt;, you&amp;rsquo;ve always
been there, quietly sending HTTP requests along to our servers.  You&amp;rsquo;ve been connected
to all the availabilty zones: us-east-1a, b, c, d, e, and f.  Countless servers
in your autoscaling group have come and gone. When you were created, there was no
HTTP/2 or SPDY.  We couldn&amp;rsquo;t even point a root DNS record at you. You&amp;rsquo;ve been around
so long that you are officially called &amp;ldquo;Classic&amp;rdquo;.&lt;/p&gt;

&lt;p&gt;We know you understand.  We need the new instance types.  We need the enhanced network
performance.  HTTP/2 will be nice for our users (and hopefully our bandwidth).&lt;/p&gt;

&lt;p&gt;So last night, we changed the DNS record for &lt;code&gt;api.stathat.com&lt;/code&gt; to point to a so-called
application load balancer that supports HTTP/2 in front of a VPC network.
But even after the TTL of 3600 seconds went by, &lt;code&gt;api-ssl-balancer&lt;/code&gt; wouldn&amp;rsquo;t let go,
or maybe its friendly clients couldn&amp;rsquo;t believe that after 7 years the name was pointing
somewere else.  24 hours later and you still have 1,500 active connections and are
handling 700,000 requests per minute.  With heavy hearts we&amp;rsquo;re going to have to turn
you off and force your clients to connect to your new sibling.&lt;/p&gt;

&lt;p&gt;Goodbye, &lt;code&gt;api-ssl-balancer&lt;/code&gt;&amp;hellip;thank you for all the requests.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Send alerts to Keybase team chat channels</title>
   <link href="http://blog.stathat.com/2017/09/28/send_alerts_to_keybase_team_chat.html"/>
   <updated>2017-09-28T00:00:00+07:00</updated>
   <id>http://blog.stathat.com/2017/09/28/send_alerts_to_keybase_team_chat.html</id>
   <content type="html">&lt;p&gt;StatHat can now send alert notifications to &lt;a href=&#34;https://keybase.io/blog/introducing-keybase-teams&#34;&gt;Keybase team chat channels&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since team chat on Keybase is end-to-end encrypted, we can&amp;rsquo;t just post
a message to some API endpoint like we do for Slack and PagerDuty.
You need to add our bot user to your team.&lt;/p&gt;

&lt;p&gt;We created a Keybase user named &lt;code&gt;stathatbot&lt;/code&gt;.  You should check it out
to make sure it is legit by doing:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;keybase id stathatbot
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It should have valid proofs for @stathat on twitter, DNS for stathat.com,
and DNS for numerotron.com.  Given those proofs, you can be confident that
&lt;code&gt;stathatbot&lt;/code&gt; belongs to us here at StatHat.  You can follow &lt;code&gt;stathatbot&lt;/code&gt;
to keep track of its proofs and notice any changes.&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;/images/keybase/stathatbot_tw.png&#34; width=&#34;544&#34;&gt;&lt;/p&gt;

&lt;p&gt;Now you need to add &lt;code&gt;stathatbot&lt;/code&gt; to one of your teams.  Please note that
once on the team, &lt;code&gt;stathatbot&lt;/code&gt; will be able to read (and write) messages
to all the channels on the team.&lt;/p&gt;

&lt;p&gt;The best way to protect your data is
to use a subteam that is just for alerts or bots.  If &lt;code&gt;stathatbot&lt;/code&gt; is
just a member of a subteam, it can only access chat channels in that subteam,
and not the root team or any other subteams.  So, let&amp;rsquo;s say your team on
Keybase is &lt;code&gt;treehouse&lt;/code&gt;, you would do:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;keybase team create treehouse.alerts
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;to create the subteam.  And then&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;keybase team add-member treehouse.alerts --user=stathatbot --role=reader
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;reader&lt;/code&gt; role is a little confusing, but it means that it will only
have read access to any files you happen to put in &lt;code&gt;/keybase/team/treeehouse.alerts&lt;/code&gt;.
It can still read and write to any chat channel in &lt;code&gt;treehouse.alerts&lt;/code&gt;.
(For the record, the &lt;code&gt;stathatbot&lt;/code&gt; doesn&amp;rsquo;t even have file system access turned
on, but you should still give this bot as little access as you can.)  You will
need to add yourself and anyone else that wants to see the alerts to the subteam.&lt;/p&gt;

&lt;p&gt;Now, you&amp;rsquo;re all set on the Keybase side.&lt;/p&gt;

&lt;p&gt;In &lt;a href=&#34;https://www.stathat.com/settings/destinations&#34;&gt;StatHat alert destinations settings&lt;/a&gt;, there&amp;rsquo;s a new
section for Keybase.  You would enter &lt;code&gt;treehouse.alerts&lt;/code&gt; for the team name
and you can leave the channel blank to use the default &lt;code&gt;general&lt;/code&gt; channel.&lt;/p&gt;

&lt;p&gt;Once you enable this Keybase destination for manual and automatic alerts on the &lt;a href=&#34;https://www.stathat.com/settings&#34;&gt;main settings page&lt;/a&gt;,
all alert notifications will be sent to your Keybase team&amp;rsquo;s chat channel.&lt;/p&gt;

&lt;p&gt;Let us know if you have any further questions or issues setting this up.&lt;/p&gt;

&lt;p&gt;P.S. If you&amp;rsquo;re curious how this works: we have an isolated server where there&amp;rsquo;s a
user logged in to Keybase as &lt;code&gt;stathatbot&lt;/code&gt;.  There&amp;rsquo;s some code pulling alerts off
of an SQS queue.  When it gets one it uses &lt;code&gt;keybase chat api&lt;/code&gt; to send a message
to the appropriate team/channel.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>83% Bandwidth Reduction via API Response Change</title>
   <link href="http://blog.stathat.com/2017/05/05/bandwidth.html"/>
   <updated>2017-05-05T00:00:00+07:00</updated>
   <id>http://blog.stathat.com/2017/05/05/bandwidth.html</id>
   <content type="html">&lt;p&gt;A typical response to a StatHat stat API call looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;HTTP/1.1 200 OK
Content-Type: application/json
Date: Tue, 02 May 2017 14:53:45 GMT
Content-Length: 25
Connection: keep-alive

{&amp;quot;status&amp;quot;:200,&amp;quot;msg&amp;quot;:&amp;quot;ok&amp;quot;}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It&amp;rsquo;s pretty small.  152 bytes.  But users sent in 150 billion requests
last month, and StatHat responded with that 152 bytes to them all, which
is 20 terabytes.&lt;/p&gt;

&lt;p&gt;After studying &lt;a href=&#34;https://tools.ietf.org/html/rfc7231&#34;&gt;RFC 7231&lt;/a&gt;, we are going
to change the default success response to:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;HTTP/1.1 204 No Content
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It is 25 bytes (maybe 26 with a blank line after the header), 127 bytes leaner.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;204&lt;/code&gt; response is an accurate description of a successful API request:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The 204 (No Content) status code indicates that the server has
successfully fulfilled the request and that there is no additional
content to send in the response payload body.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While the &lt;code&gt;Date&lt;/code&gt; header field is encouraged, it is optional:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An origin server MUST NOT send a Date header field if it does not
have a clock capable of providing a reasonable approximation of the
current instance in Coordinated Universal Time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So let&amp;rsquo;s just pretend we don&amp;rsquo;t have a good clock.&lt;/p&gt;

&lt;p&gt;None of the official StatHat libraries look at the body of the response,
they just care about the 2xx success status.  We have tried this response
in production on a subset of the requests and have not received any reports
of it being a problem, so we are rolling it out for all requests.&lt;/p&gt;

&lt;p&gt;Note that we will still provide details for multiple stats uploaded in
a JSON request and any error cases.&lt;/p&gt;

&lt;p&gt;If you have code that parses the original body and would like to continue
doing so, include a &lt;code&gt;vb=1&lt;/code&gt; request parameter with your POST or GET request
and the servers will respond with the original verbose body output.&lt;/p&gt;

&lt;p&gt;This change should remove about 17 terabytes of useless data from the
internet pipes each month.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Is Pied Piper using StatHat?</title>
   <link href="http://blog.stathat.com/2016/06/26/is_pied_piper_using_stathat.html"/>
   <updated>2016-06-26T00:00:00+07:00</updated>
   <id>http://blog.stathat.com/2016/06/26/is_pied_piper_using_stathat.html</id>
   <content type="html">&lt;p&gt;
No, of course a fictional company on a TV show isn&#39;t using a real service
like StatHat.&lt;sup&gt;&lt;a href=&#34;#foot1&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;  But it sure looks like they are.
&lt;/p&gt;

&lt;img src=&#34;/images/piper/dau.jpg&#34; width=&#34;544&#34;&gt;

&lt;p&gt;
Season 3, Episode 9 &lt;em&gt;Daily Active Users&lt;/em&gt; was all about two stats:  Installs 
and Daily Active Users.  Tracking these with StatHat would be a piece of cake.
&lt;/p&gt;

&lt;p&gt;
Let&#39;s just assume &#34;Installs&#34; means &#34;New User Created&#34;.  In the show, they compare 
Installs to Daily Active Users.  &#34;Installs&#34; doesn&#39;t make much sense for
what appears to be primarily a web service.&lt;sup&gt;&lt;a href=&#34;#foot2&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;  
So whenever a new user is created, they 
could add one line of code to track this as a counter stat:
&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;db.Exec(&#34;INSERT INTO users (id, email, created_at, active_at) VALUES (?, ?, NOW(), NOW())&#34;, id, email)
stathat.PostEZCount(&#34;installs&#34;, &#34;stats@piedpiper.com&#34;, 1)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Whenever a user did something on the Pied Piper platform, they could update the 
user row in the database:
&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;db.Exec(&#34;UPDATE users SET active_at=NOW() WHERE id=?&#34;, id)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Then they could have a script that ran via cron every minute to send the
number of active users in the past 24 hours to StatHat:
&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var dau int
db.QueryRow(&#34;SELECT COUNT(*) FROM users WHERE active_at &gt; NOW() - INTERVAL 24 HOUR&#34;).Scan(&amp;dau)
stathat.PostEZValue(&#34;daily active users&#34;, &#34;stats@piedpiper.com&#34;, dau)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;
Those two calls to StatHat are all it takes to track these stats.  They don&#39;t 
need to be created on the website first as StatHat will create new stats dynamically
when it receives a new stat name.
&lt;/p&gt;

&lt;p&gt;The installs stat is a counter.  Every time someone signs up for Pied Piper, it sends 
a count of 1 to StatHat.  StatHat will then sum these up over time.&lt;/p&gt;

&lt;p&gt;The daily active users stat is a value.  Every minute, the cron script sends 
the current daily active users value to StatHat.  StatHat will then average this value 
over time.&lt;/p&gt;

&lt;p&gt;Now that the data is going to StatHat, there are many options for viewing it.
The web interface allows you to inspect the data at any timeframe, compare multiple
stats.  It also has &lt;a href=&#34;https://www.stathat.com/manual/cards&#34;&gt;cards&lt;/a&gt; that would
be an easy way to create a dashboard of Installs and Daily Active Users.  Or
&lt;a href=&#34;https://www.stathat.com/manual/statusboard&#34;&gt;Panic&#39;s Status Board&lt;/a&gt; would
be another easy choice.&lt;/p&gt;

&lt;p&gt;But there&#39;s also an embed API that allows you to embed stat data on any web page,
which would be one way to get a similar looking dashboard to the one on the show.
The stat integrations page gives you a small block of JavaScript you can paste
in any web page.  Here&#39;s a stat embedded on this blog post, styled to look somewhat 
similar to the Pied Piper dashboard:

&lt;style&gt;
.sh_embed_text {
	font-family: Monaco, monospace;
	font-size: 72px;
	color: #8995ad;
}
&lt;/style&gt;
&lt;div style=&#34;background: #151e31; color: #404c62; font-family: Monaco, monospace; padding-top: 50px; padding-bottom: 50px; padding-left: 20px; padding-right: 20px;&#34;&gt;
	&lt;h2 style=&#34;font-size: 32px&#34;&gt;INSTALLS&lt;/h2&gt;
&lt;script src=&#34;//www.stathat.com/js/embed.js&#34;&gt;&lt;/script&gt;
&lt;div style=&#34;padding-top:50px; padding-bottom:50px;&#34;&gt;
&lt;script&gt;StatHatEmbed.render({kind: &#39;text&#39;, s1: &#39;K6xI3hBsBACxjF9nAd7IhOPw8RbKH5XJ&#39;});&lt;/script&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;
The code to do this looks like:
&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;script src=&#34;//www.stathat.com/js/embed.js&#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script&amp;gt;StatHatEmbed.render({kind: &#39;text&#39;, s1: &#39;K6xI3hBsBACxjF9nAd7IhOPw8RbKH5XJ&#39;});&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&#39;s all that is needed.  You should see the number displayed above change every minute.
Since this stat is a counter, StatHat is displaying the total count received over the timeframe.
&lt;/p&gt;

&lt;img src=&#34;/images/piper/party.jpg&#34; width=&#34;544&#34;&gt;

&lt;p&gt;Perfect for milestone parties:&lt;/p&gt;

&lt;img src=&#34;/images/piper/crowd.jpg&#34; width=&#34;544&#34;&gt;

&lt;br/&gt;
&lt;br/&gt;
&lt;br/&gt;
&lt;strong&gt;Footnotes&lt;/strong&gt;
&lt;p&gt;
&lt;a name=&#34;foot1&#34;&gt;1&lt;/a&gt;: &lt;a href=&#34;https://en.wikipedia.org/wiki/Betteridge%27s_law_of_headlines&#34;&gt;Betteridge&#39;s law of headlines&lt;/a&gt; is true in this case.
&lt;/p&gt;
&lt;p&gt;
&lt;a name=&#34;foot2&#34;&gt;2&lt;/a&gt;: Yes, the &#34;platform&#34; is available on all devices so could be installable software, but it is also clearly a web service:
&lt;/p&gt;
&lt;img src=&#34;/images/piper/interface.jpg&#34; width=&#34;544&#34;&gt;
</content>
 </entry>
 
 <entry>
   <title>chartd.co: responsive, retina-compatible charts with just an img tag</title>
   <link href="http://blog.stathat.com/2016/04/09/chartd.html"/>
   <updated>2016-04-09T00:00:00+07:00</updated>
   <id>http://blog.stathat.com/2016/04/09/chartd.html</id>
   <content type="html">&lt;p&gt;We created a chart service that lives at &lt;a href=&#34;http://chartd.co&#34;&gt;chartd.co&lt;/a&gt;.  It
allows you to create responsive, retina-compatible
charts with just an img tag.  Like this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;//chartd.co/a.svg?w=580&amp;amp;h=180&amp;amp;d0=RXZZfhgdURRUYZgfccZXUM&amp;amp;d1=roksqfdcjfKGGMQOSXchUO&amp;amp;d2=y3vuuvljghrgcYZZcdVckg&amp;amp;d3=kdfffcZYbggdfdhkkkgjgk&amp;amp;ymin=45&amp;amp;ymax=90&amp;amp;t=Temperature&#34; alt=&#34;chartd chart&#34; /&gt;
&lt;/p&gt;

&lt;p&gt;That whole chart came from this URL:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;https://chartd.co/a.svg?w=580&amp;amp;h=180&amp;amp;d0=RXZZfhgdURRUYZgfccZXUM&amp;amp;d1=roksqfdcjfKGGMQOSXchUO&amp;amp;d2=y3vuuvljghrgcYZZcdVckg&amp;amp;d3=kdfffcZYbggdfdhkkkgjgk&amp;amp;ymin=45&amp;amp;ymax=90&amp;amp;t=Temperature
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We built it a long time ago and StatHat has been using it to include charts
in alert and report emails.  While we told a few other
companies about it, we never officially announced it.&lt;/p&gt;

&lt;p&gt;All the documentation for it is on the main page at
&lt;a href=&#34;http://chartd.co&#34;&gt;chartd.co&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Please let us know what you think of it!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Fix EC2 Network Issue: skb rides the rocket: 19 slots</title>
   <link href="http://blog.stathat.com/2014/12/22/fix_ec2_network_issue_skb_rides_the_rocket.html"/>
   <updated>2014-12-22T00:00:00+07:00</updated>
   <id>http://blog.stathat.com/2014/12/22/fix_ec2_network_issue_skb_rides_the_rocket.html</id>
   <content type="html">&lt;p&gt;Here&amp;rsquo;s the fix:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo ethtool -K eth0 sg off
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Back story:&lt;/p&gt;

&lt;p&gt;We&amp;rsquo;ve been noticing sporadic network issues with some of our EC2 instances.  The main
symptom is that once in a while, an RPC request will hang for around 10 minutes.&lt;/p&gt;

&lt;p&gt;We&amp;rsquo;ve never been able to reproduce it in a development environment, only in production.
Some days it happens a lot, some not at all.  All of our attempts to debug the issue
failed.  We have automatic monitoring tools that check for this happening and make a
server inactive until it clears up.  These handle the situation fine, but it&amp;rsquo;s still
annoying and suboptimal.&lt;/p&gt;

&lt;p&gt;Last week, I was investigating an unrelated issue.  I was reading a syslog and saw
this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;xen_netfront: xennet: skb rides the rocket: 19 slots
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If it wasn&amp;rsquo;t so odd, I would have passed right over it.  But I had to google it.
Which led me to &lt;a href=&#34;http://www.brendangregg.com/blog/2014-09-11/perf-kernel-line-tracing.html&#34;&gt;this blog post&lt;/a&gt; and &lt;a href=&#34;https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1317811&#34;&gt;this ubuntu bug report&lt;/a&gt;.  Apparently, it&amp;rsquo;s based on getting hit by a rocket launcher in Quake, which
takes me back to the daily capture the flag matches we used to have at Click working
on Throne of Darkness&amp;hellip;&lt;/p&gt;

&lt;p&gt;Anyway, I found similar log messages on the servers with the intermittent RPC request
issues.  I ran the command to turn off scatter-gather on one of the servers:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo ethtool -K eth0 sg off
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;No errors for 6 hours.  So I ran it on all of them.  And we haven&amp;rsquo;t seen the RPC
error since.  Now it&amp;rsquo;s in rc.local in all of our AMIs.  We haven&amp;rsquo;t noticed any
performance problems.  And getting rid of an occasional 10 minute RPC request is
a definite performance boost.&lt;/p&gt;

&lt;p&gt;So check your syslogs.  If you see anything like &amp;ldquo;skb rides the rocket&amp;rdquo; then
try turning off scatter-gather.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Send alerts to PagerDuty, Webhooks, and Slack</title>
   <link href="http://blog.stathat.com/2014/09/10/send_alerts_to_pagerduty_webhooks_and_slack.html"/>
   <updated>2014-09-10T00:00:00+07:00</updated>
   <id>http://blog.stathat.com/2014/09/10/send_alerts_to_pagerduty_webhooks_and_slack.html</id>
   <content type="html">&lt;p&gt;We expanded where you can send your StatHat alerts.  In
addition to email addresses and Campfire chat rooms, you
can send your alerts to PagerDuty, Slack channels, and
generic webhooks.&lt;/p&gt;

&lt;p&gt;We created a new system to set up your alert destinations.
You can configure defaults for manual and automatic alerts
as well as customized destinations for each manual alert.&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;http://www.stathat.com/manual/alerts&#34;&gt;Read all about alerts and the new destinations here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We have a few more integrations in the queue, but let us
know if there are other integrations you would love to
have.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Export Daily Summary Data</title>
   <link href="http://blog.stathat.com/2014/08/18/export_daily_summary.html"/>
   <updated>2014-08-18T00:00:00+07:00</updated>
   <id>http://blog.stathat.com/2014/08/18/export_daily_summary.html</id>
   <content type="html">&lt;p&gt;By popular demand, we made it easy to get daily summary data using the export API.
This query will return 7 days of summary data:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;https://www.stathat.com/x/ACCESSTOKEN/data/STATIDD_0/STATID_1?summary=7d
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can specify any standard timeframe abbreviation, for example 2 months:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;https://www.stathat.com/x/ACCESSTOKEN/data/STATIDD_0/STATID_1?summary=2M
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It uses the timezone set on the settings page to split the data exactly at midnight.&lt;br /&gt;
Any data received since midnight is not included.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>What&#39;s powering the new web interface?</title>
   <link href="http://blog.stathat.com/2014/04/10/whats-powering-the-new-web-interface.html"/>
   <updated>2014-04-10T00:00:00+07:00</updated>
   <id>http://blog.stathat.com/2014/04/10/whats-powering-the-new-web-interface.html</id>
   <content type="html">&lt;p&gt;We&amp;rsquo;ve had a lot of questions about what&amp;rsquo;s powering &lt;a href=&#34;/2014/04/09/web-app-interface-changes-stats.html&#34;&gt;our new interface&lt;/a&gt;, so
here&amp;rsquo;s a brief rundown:&lt;/p&gt;

&lt;h1&gt;&lt;a href=&#34;http://facebook.github.io/react/&#34;&gt;React&lt;/a&gt;&lt;/h1&gt;

&lt;p&gt;Everything inside the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tag is rendered with React components.&lt;/p&gt;

&lt;p&gt;We tried a lot of JS frameworks and libraries to help us make the UI more dynamic.  The one that fit best was React.
It provides a powerful way to make reusable components and the one-way data flow makes a lot of sense.
With React, our code is understandable, small, and fast.&lt;/p&gt;

&lt;h1&gt;&lt;a href=&#34;http://backbonejs.org/#Router&#34;&gt;Backbone.Router&lt;/a&gt;&lt;/h1&gt;

&lt;p&gt;React doesn&amp;rsquo;t have anything for routing.  We tried a bunch of these as well and settled on Backbone&amp;rsquo;s router.  It&amp;rsquo;s simple,
it works.&lt;/p&gt;

&lt;h1&gt;&lt;a href=&#34;http://d3js.org&#34;&gt;d3&lt;/a&gt;&lt;/h1&gt;

&lt;p&gt;We are using d3 to render our charts.  d3 is pretty amazing.  We&amp;rsquo;re using maybe 1% of its API, but were able to replicate our
hand-coded server-drawn charts quite easily.&lt;/p&gt;

&lt;h1&gt;&lt;a href=&#34;http://maxtaco.github.io/coffee-script/&#34;&gt;IcedCoffeeScript&lt;/a&gt;&lt;/h1&gt;

&lt;p&gt;We wrote some async JS code by hand a while back to get a bunch of datasets and split them up into a timeframe for a chart.
Then we came back to it and had no idea how it worked.  IcedCoffeeScript makes asynchronous JavaScript a breeze.
We replaced our code with a few lines of IcedCoffeeScript and never looked back.&lt;/p&gt;

&lt;h1&gt;&lt;a href=&#34;http://gulpjs.com/&#34;&gt;gulp&lt;/a&gt;&lt;/h1&gt;

&lt;p&gt;We use gulp to stitch all this JavaScript together, lint it, minify it, compress it.
Then we have a Go app that uploads the bundle to s3/CloudFront, updates an assets file, and HUPs
the web servers so they reload the assets file.&lt;/p&gt;

&lt;p&gt;&amp;raquo; &lt;a href=&#34;https://github.com/patrickxb/gulp-iced&#34;&gt;Here&amp;rsquo;s the gulp plugin we wrote for IcedCoffeeScript&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;&lt;a href=&#34;http://golang.org&#34;&gt;Go&lt;/a&gt;&lt;/h1&gt;

&lt;p&gt;Nothing has changed on the backend, we &lt;a href=&#34;http://blog.golang.org/building-stathat-with-go&#34;&gt;still use Go&lt;/a&gt; for everything.
It does a marvelous job with JSON.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Web App Interface Changes: Stats</title>
   <link href="http://blog.stathat.com/2014/04/09/web-app-interface-changes-stats.html"/>
   <updated>2014-04-09T00:00:00+07:00</updated>
   <id>http://blog.stathat.com/2014/04/09/web-app-interface-changes-stats.html</id>
   <content type="html">&lt;p&gt;We just deployed some significant changes to StatHat&amp;rsquo;s web interface.
Here are some changes concerning viewing and analyzing stats:&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;/images/interface/details.jpg&#34; width=&#34;628&#34;&gt;&lt;/p&gt;

&lt;p&gt;We changed the stat details interface to let you select any timeframe you want.
Our standard one hour to one year overview still exists, but you don&amp;rsquo;t need to switch
to the analyze interface to view something like 7 hours at 2 minute intervals.&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;/images/interface/timeframe.png&#34; width=&#34;628&#34;&gt;&lt;/p&gt;

&lt;p&gt;When you hover over the chart, you will now see the value at each data point.&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;/images/interface/hover.png&#34; width=&#34;628&#34;&gt;&lt;/p&gt;

&lt;p&gt;We are also including more summary data:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;most recent value&lt;/li&gt;
&lt;li&gt;standard deviation&lt;/li&gt;
&lt;li&gt;95% and 99% confidence intervals&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&#34;/images/interface/summary.png&#34; width=&#34;628&#34;&gt;&lt;/p&gt;

&lt;p&gt;Pressing the Play button makes the chart automatically update every minute.&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;/images/interface/play.png&#34;&gt;&lt;/p&gt;

&lt;p&gt;Like always, the analyze interface allows you to compare up to five stats on the same
chart.  Comparing stats of vastly different scales is easier now:  the left and right
axes are independent and can be set to any group of stats.  Comparing the number of
API calls (which ranges from 6M - 14M) with HTTP request times ranging from 100 - 1800ms
is clearer.&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;/images/interface/analyze.png&#34;&gt;&lt;/p&gt;

&lt;p&gt;The charts are fully responsive, from large screens:&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;/images/interface/large.png&#34;&gt;&lt;/p&gt;

&lt;p&gt;to medium:&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;/images/interface/medium.png&#34;&gt;&lt;/p&gt;

&lt;p&gt;to small:&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;/images/interface/small.png&#34;&gt;&lt;/p&gt;

&lt;p&gt;We made changes to make StatHat easier to use when you have lots of stats:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;stats are automatically collapsed into groups by common prefix&lt;/li&gt;
&lt;li&gt;intelligent filtering and improved search&lt;/li&gt;
&lt;li&gt;groups and saved searches visible in the stat list side bar&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are many more minor tweaks and updates, all with the goal of making StatHat
a more useful tool to analyze your stats.  Please let us know what you think of the
changes.&lt;/p&gt;

&lt;p&gt;Upcoming posts will highlight changes to alerts and describe the technologies behind
these interface changes.&lt;/p&gt;
</content>
 </entry>
 

</feed>
