{"id":558,"date":"2013-01-18T09:28:02","date_gmt":"2013-01-18T08:28:02","guid":{"rendered":"http:\/\/www.streppone.it\/cosimo\/blog\/?p=558"},"modified":"2013-02-19T18:29:26","modified_gmt":"2013-02-19T17:29:26","slug":"net-statsd-server-perl-port-of-flickr-etsy-statsd","status":"publish","type":"post","link":"https:\/\/www.streppone.it\/cosimo\/blog\/2013\/01\/net-statsd-server-perl-port-of-flickr-etsy-statsd\/","title":{"rendered":"Net::Statsd::Server, a Perl port of Flickr\/Etsy&#8217;s statsd"},"content":{"rendered":"<p>If you&#8217;re looking for a Perl client to connect to a <b>statsd<\/b> daemon, checkout <a href=\"https:\/\/metacpan.org\/module\/Net::Statsd\">Net::Statsd on CPAN<\/a>, now at version 0.08.<\/p>\n<p>This post is about the <b>server<\/b> component of <a href=\"http:\/\/codeascraft.etsy.com\/2011\/02\/15\/measure-anything-measure-everything\/\">statsd<\/a>.<\/p>\n<h2>Tracking metrics: up to now<\/h2>\n<p>The idea of statsd started in Flickr by Cal Henderson, and <a href=\"https:\/\/github.com\/iamcal\/Flickr-StatsD\">some code is still available<\/a>, but it&#8217;s not very functional or complete.<\/p>\n<p>Since reading about statsd, I found the concept brilliant. I have been using a similar technique long before hearing about statsd though. I learned it from colleagues here at Opera in 2008. They were using it to track application metrics for the Opera Link server. I thought it was great, so I also implemented it, extending it by making it very easy to add metrics and to see the output automatically in Munin. Here&#8217;s how it worked basically:<\/p>\n<p><code># ...<br \/>\nuse Opera::Stats;<br \/>\n# ...<br \/>\nOpera::Stats::count(\"site.logins\");<br \/>\n# ...<br \/>\n<\/code><\/p>\n<p>The project code would have typically tens or hundreds of these calls. Each call would store\/increment a counter in a local or remote memcached. Then a complementary <code>Opera::Stats::Munin<\/code> module would automatically generate the output needed to implement a full Munin plugin given the metrics to be exposed.<\/p>\n<p>So far, so good. <b>Except there were a few things that didn&#8217;t work quite right<\/b>:<\/p>\n<ul>\n<li>Using TCP connections, maybe even to remote machines, even though it was never a problem, could be in case the memcached machines went down<\/li>\n<li>Volume was a concern. I had to worry about tracking too many metrics. How would that affect functioning of memcached for regularly stored keys and values? Would those metrics-related keys cause evictions in the regular memcached content?<\/li>\n<li>Even though the munin integration made it very easy to have charts, there were still some limitations: creating new charts requires some wrapper plugin with 1 or 2 lines of Perl code. Flexibility was also an issue.<\/li>\n<\/ul>\n<h2>Enter statsd<\/h2>\n<p><b>I have been thinking of replacing this system with statsd for a while.<\/b> However, I wanted to have a <a href=\"https:\/\/github.com\/etsy\/statsd\">more in-depth look at it<\/a> before deploying it.<\/p>\n<p>Turns out that statsd is a simple project, which I like, but requires <b>nodejs<\/b>. Knowing next to nothing about nodejs, I took some time to learn a few things.<\/p>\n<p>I also realized I have been wanting to learn about <a href=\"https:\/\/metacpan.org\/module\/AnyEvent\">AnyEvent<\/a> for a long time.<\/p>\n<h2>Net::Statsd::Server<\/h2>\n<p>Two weeks ago, I spent a busy weekend reimplementing 95% of statsd in Perl. On Sunday night, I had a <a href=\"https:\/\/github.com\/cosimo\/perl5-net-statsd-server\">functional version of statsd written in Perl with AnyEvent<\/a>.<\/p>\n<p>AnyEvent stuff is surprising at times. I found especially interesting to debug the cases where your timer (<code>AE::timer<\/code>) doesn&#8217;t fire unless you actually save it to a scalar, as in:<\/p>\n<p><code># This won't fire!<br \/>\nAE::timer 10, 10, \\&do_something;<\/p>\n<p># This will though.<br \/>\n# This behaviour is triggered by \"defined wantarray\"<br \/>\nmy $t = AE::timer 10, 10, \\&do_something;<br \/>\n<\/code><\/p>\n<p>Since that weekend, I have spent a few more nights tweaking Net::Statsd::Server. Yesterday I wrote a new piece of functionality (a new &#8220;File&#8221; backend) that is actually <b>not<\/b> in the original statsd.<\/p>\n<p>It looks like I might need new backends as well, so I think it&#8217;s &#8220;an investment with a good ROI&#8221;, even though <b>I did it mainly for fun and in my free time<\/b>.<\/p>\n<h2>Performance<\/h2>\n<p><b>I wanted to make sure my statsd server implementation would be fast<\/b>. I started by bringing up the nodejs statsd and firing my <a href=\"https:\/\/metacpan.org\/source\/COSIMO\/Net-Statsd-0.08\/benchmark.pl\">official benchmark script<\/a> with 1 million iterations, and then comparing the results with my own statsd server.<\/p>\n<p>That didn&#8217;t work out very well. Or rather, it worked out brilliantly, showing around 40K requests\/s being handled by nodejs-statsd and 50K requests\/s by <code>Net::Statsd::Server<\/code>. Problem is: how do you measure the performance of a UDP server? Or, for that matter, of a UDP client?<\/p>\n<p>I figured out that, being UDP connection-less fire-and-forget, <b>it doesn&#8217;t really matter how many packets\/s the client fires<\/b>, as long as you can generate more than your server can handle. Just as a data point, I reached around 73-75k statsd API calls per second (for the <code>gauge<\/code> API, around 55-58k for counters and timers). What really matters is <b>how many packets reach the server<\/b>.<\/p>\n<p>BTW, I used another amazing piece of software called <a href=\"https:\/\/metacpan.org\/module\/Devel::NYTProf\">Devel::NYTProf<\/a> to optimize the performance of the incoming packets code path as much as I could.<\/p>\n<h2>The test setup<\/h2>\n<p>To measure how many packets are received on the server-side, I prepared a test configuration:<\/p>\n<p><code>{ graphitePort: 2003<br \/>\n, graphiteHost: \"graphite.localdomain\"<br \/>\n, host: \"0.0.0.0\"<br \/>\n, port: 8125<br \/>\n, backends: [ \".\/backends\/graphite\", \".\/backends\/console\" ]<br \/>\n, mgmt_address: \"0.0.0.0\"<br \/>\n, mgmt_port: 8126<br \/>\n}<\/code><\/p>\n<p>The same configuration file for the Perl server becomes:<\/p>\n<p><code>{  \"graphitePort\": 2003,<br \/>\n&nbsp; \"graphiteHost\": \"graphite.localdomain\",<br \/>\n&nbsp; \"host\" : \"0.0.0.0\",<br \/>\n&nbsp; \"port\": 8125,<br \/>\n&nbsp; \"mgmt_address\" : \"0.0.0.0\",<br \/>\n&nbsp; \"mgmt_port\": 8126,<br \/>\n&nbsp; \"backends\": [ \"Graphite\", \"Console\" ],<br \/>\n&nbsp; \"log\" : {<br \/>\n&nbsp; &nbsp; \"backend\" : \"stdout\",<br \/>\n&nbsp; &nbsp; \"level\" : \"LOG_WARN\",<br \/>\n&nbsp; }<br \/>\n}<\/code><\/p>\n<p>Using the <code>benchmark.pl<\/code> code mentioned above, run with:<\/p>\n<p><code>$ perl benchmark.pl 1000000<\/code><\/p>\n<p>I started up first the nodejs statsd, then the Net::Statsd::Server daemon and captured their output. Both servers are configured to use their Graphite backend and flush to a valid and active graphite host. The Console backend is also active for both servers, so I could capture the output and look at the <code>statsd.packets_received<\/code> counter and directly measure how many packets are received in the server.<\/p>\n<p>The benchmark utility with first argument = 1000000 generates 5 million statsd API calls, that is, 5 million UDP packets.<\/p>\n<p>Of these 5 million packets, nodejs statsd was able to capture 2106768, 1596275, 1479145 and 1490640 packets over several runs.<\/p>\n<p>Net::Statsd::Server, again in 3 different runs, was able to capture 2106242, 1884810, 1822042 and 1866500 packets.<\/p>\n<p>I have performed more tests, and they had a very low deviation from the last runs (1.5M for etsy&#8217;s statsd and 1.8M for Net::Statsd::Server). Removing the 2 peak results of ~2.1Mb, <b>it would seem that the Perl statsd is capable of receiving 22% more packets<\/b> than the original statsd daemon written in javascript.<\/p>\n<p>Of course, this is just my test. I have tried to run the test on different hardware, but I haven&#8217;t got significantly different results. If you try yourself, please let me know what numbers you get. I&#8217;d be curious to know :-)<\/p>\n<h2>SO_RCVBUF<\/h2>\n<p>Given the massive amount of UDP packets that were lost in the tests (50%+ in the best runs), I tried to figure out a way to improve this and I stumbled on <code>SO_RCVBUF<\/code>.<\/p>\n<p>My understanding was that bumping up <code>SO_RCVBUF<\/code> on the listening UDP socket would dramatically decrease packet loss. However, I hadn&#8217;t been able to prove the theory because I hadn&#8217;t seen an improvement in the total number of packets received. At least until I read <a href=\"http:\/\/stackoverflow.com\/questions\/5913298\/causes-of-linux-udp-packet-drops\">this article on UDP packet loss on stackoverflow.com<\/a>, that pointed me to the <code>net.core.rmem_max<\/code> sysctl.<\/p>\n<p>After modifying <code>net.core.rmem_max<\/code>, setting it to 100M, just to avoid its effect, and using the following code in <code>Net::Statsd::Server<\/code>:<\/p>\n<p><code># Bump up SO_RCVBUF on UDP socket, to buffer up incoming<br \/>\n# UDP packets, to avoid massive packet loss when load is very high.<br \/>\nsetsockopt($self->{server}->fh, SOL_SOCKET, SO_RCVBUF, 1*1024*1024)<br \/>\n  or die \"Couldn't set SO_RCVBUF: $!\";<br \/>\n<\/code><\/p>\n<p>I can see some <b>very interesting effect<\/b>.<\/p>\n<p>Re-running the node.js statsd, I could see an increased amount of captured packets (1691700, 1675902, ~10% increase).<br \/>\nRunning again the <code>Net::Statsd::Server<\/code> daemon, <b>I recorded 2678507 and 2477246 packets, for an impressive ~40% increase!<\/b><\/p>\n<p>As a last effort, I tried varying the <code>SO_RCVBUF<\/code> size from 1 to 64Mb to see what effect it had on the amount of captured packets (or UDP packet loss if you prefer).<\/p>\n<p>I haven&#8217;t run any scientific set of tests, but I can&#8217;t see any statistically significant increase for values greater than 4-8Mb, so I haven&#8217;t decided where to set the default in <code>Net::Statsd::Server<\/code> yet. Any chosen value is likely to need specific sysctl tuning anyway, so YMMV.<\/p>\n<h2>Why?<\/h2>\n<p><b>Did I really do it for fun?<\/b> Yes, mainly, but also because:<\/p>\n<ul>\n<li>I don&#8217;t like adding node.js to our production stack just to run statsd. I have never operated a node.js server, so I don&#8217;t want to take this &#8220;risk&#8221;. The product we&#8217;re building is going live soon! :-) And note that this does apply to anything, it&#8217;s not about node.js per se :-)<\/li>\n<li>to learn how statsd was put together<\/li>\n<li>to learn AnyEvent<\/li>\n<li>to learn how to build a high performance UDP server<\/li>\n<li>Basically, to learn :-)<\/li>\n<\/ul>\n<p>Code is up on CPAN, as usual: <a href=\"https:\/\/metacpan.org\/modules\/Net::Statsd::Server\">https:\/\/metacpan.org\/module\/Net::Statsd::Server<\/a>.<\/p>\n<p>If you happen to use it, <a href=\"mailto:cosimo@streppone.it?subject=Net::Statsd::Server\">please give me some feedback!<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you&#8217;re looking for a Perl client to connect to a statsd daemon, checkout Net::Statsd on CPAN, now at version 0.08. This post is about the server component of statsd. Tracking metrics: up to now The idea of statsd started in Flickr by Cal Henderson, and some code is still available, but it&#8217;s not very [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[512],"tags":[49,236,517,518,515,75,50,238,516,61],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Net::Statsd::Server, a Perl port of Flickr\/Etsy&#039;s statsd - Random hacking<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.streppone.it\/cosimo\/blog\/2013\/01\/net-statsd-server-perl-port-of-flickr-etsy-statsd\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Net::Statsd::Server, a Perl port of Flickr\/Etsy&#039;s statsd - Random hacking\" \/>\n<meta property=\"og:description\" content=\"If you&#8217;re looking for a Perl client to connect to a statsd daemon, checkout Net::Statsd on CPAN, now at version 0.08. This post is about the server component of statsd. Tracking metrics: up to now The idea of statsd started in Flickr by Cal Henderson, and some code is still available, but it&#8217;s not very [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.streppone.it\/cosimo\/blog\/2013\/01\/net-statsd-server-perl-port-of-flickr-etsy-statsd\/\" \/>\n<meta property=\"og:site_name\" content=\"Random hacking\" \/>\n<meta property=\"article:published_time\" content=\"2013-01-18T08:28:02+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2013-02-19T17:29:26+00:00\" \/>\n<meta name=\"author\" content=\"cosimo\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"cosimo\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2013\/01\/net-statsd-server-perl-port-of-flickr-etsy-statsd\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2013\/01\/net-statsd-server-perl-port-of-flickr-etsy-statsd\/\"},\"author\":{\"name\":\"cosimo\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1\"},\"headline\":\"Net::Statsd::Server, a Perl port of Flickr\/Etsy&#8217;s statsd\",\"datePublished\":\"2013-01-18T08:28:02+00:00\",\"dateModified\":\"2013-02-19T17:29:26+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2013\/01\/net-statsd-server-perl-port-of-flickr-etsy-statsd\/\"},\"wordCount\":1277,\"commentCount\":11,\"publisher\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1\"},\"keywords\":[\"cpan\",\"etsy\",\"metrics\",\"monitoring\",\"Net::Statsd::Server\",\"performance\",\"perl\",\"statsd\",\"udp\",\"webops\"],\"articleSection\":[\"Operations\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.streppone.it\/cosimo\/blog\/2013\/01\/net-statsd-server-perl-port-of-flickr-etsy-statsd\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2013\/01\/net-statsd-server-perl-port-of-flickr-etsy-statsd\/\",\"url\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2013\/01\/net-statsd-server-perl-port-of-flickr-etsy-statsd\/\",\"name\":\"Net::Statsd::Server, a Perl port of Flickr\/Etsy's statsd - Random hacking\",\"isPartOf\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#website\"},\"datePublished\":\"2013-01-18T08:28:02+00:00\",\"dateModified\":\"2013-02-19T17:29:26+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2013\/01\/net-statsd-server-perl-port-of-flickr-etsy-statsd\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.streppone.it\/cosimo\/blog\/2013\/01\/net-statsd-server-perl-port-of-flickr-etsy-statsd\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2013\/01\/net-statsd-server-perl-port-of-flickr-etsy-statsd\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.streppone.it\/cosimo\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Net::Statsd::Server, a Perl port of Flickr\/Etsy&#8217;s statsd\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#website\",\"url\":\"https:\/\/www.streppone.it\/cosimo\/blog\/\",\"name\":\"Random hacking\",\"description\":\"Assume nothing. Code defensively. Keep it simple, stupid!\",\"publisher\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.streppone.it\/cosimo\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1\",\"name\":\"cosimo\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/cb1d938720df45a2720724aae99e3bfc?s=96&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/cb1d938720df45a2720724aae99e3bfc?s=96&r=g\",\"caption\":\"cosimo\"},\"logo\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/image\/\"},\"url\":\"https:\/\/www.streppone.it\/cosimo\/blog\/author\/cosimo\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Net::Statsd::Server, a Perl port of Flickr\/Etsy's statsd - Random hacking","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.streppone.it\/cosimo\/blog\/2013\/01\/net-statsd-server-perl-port-of-flickr-etsy-statsd\/","og_locale":"en_US","og_type":"article","og_title":"Net::Statsd::Server, a Perl port of Flickr\/Etsy's statsd - Random hacking","og_description":"If you&#8217;re looking for a Perl client to connect to a statsd daemon, checkout Net::Statsd on CPAN, now at version 0.08. This post is about the server component of statsd. Tracking metrics: up to now The idea of statsd started in Flickr by Cal Henderson, and some code is still available, but it&#8217;s not very [&hellip;]","og_url":"https:\/\/www.streppone.it\/cosimo\/blog\/2013\/01\/net-statsd-server-perl-port-of-flickr-etsy-statsd\/","og_site_name":"Random hacking","article_published_time":"2013-01-18T08:28:02+00:00","article_modified_time":"2013-02-19T17:29:26+00:00","author":"cosimo","twitter_card":"summary_large_image","twitter_misc":{"Written by":"cosimo","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2013\/01\/net-statsd-server-perl-port-of-flickr-etsy-statsd\/#article","isPartOf":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2013\/01\/net-statsd-server-perl-port-of-flickr-etsy-statsd\/"},"author":{"name":"cosimo","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1"},"headline":"Net::Statsd::Server, a Perl port of Flickr\/Etsy&#8217;s statsd","datePublished":"2013-01-18T08:28:02+00:00","dateModified":"2013-02-19T17:29:26+00:00","mainEntityOfPage":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2013\/01\/net-statsd-server-perl-port-of-flickr-etsy-statsd\/"},"wordCount":1277,"commentCount":11,"publisher":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1"},"keywords":["cpan","etsy","metrics","monitoring","Net::Statsd::Server","performance","perl","statsd","udp","webops"],"articleSection":["Operations"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.streppone.it\/cosimo\/blog\/2013\/01\/net-statsd-server-perl-port-of-flickr-etsy-statsd\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2013\/01\/net-statsd-server-perl-port-of-flickr-etsy-statsd\/","url":"https:\/\/www.streppone.it\/cosimo\/blog\/2013\/01\/net-statsd-server-perl-port-of-flickr-etsy-statsd\/","name":"Net::Statsd::Server, a Perl port of Flickr\/Etsy's statsd - Random hacking","isPartOf":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#website"},"datePublished":"2013-01-18T08:28:02+00:00","dateModified":"2013-02-19T17:29:26+00:00","breadcrumb":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2013\/01\/net-statsd-server-perl-port-of-flickr-etsy-statsd\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.streppone.it\/cosimo\/blog\/2013\/01\/net-statsd-server-perl-port-of-flickr-etsy-statsd\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2013\/01\/net-statsd-server-perl-port-of-flickr-etsy-statsd\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.streppone.it\/cosimo\/blog\/"},{"@type":"ListItem","position":2,"name":"Net::Statsd::Server, a Perl port of Flickr\/Etsy&#8217;s statsd"}]},{"@type":"WebSite","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#website","url":"https:\/\/www.streppone.it\/cosimo\/blog\/","name":"Random hacking","description":"Assume nothing. Code defensively. Keep it simple, stupid!","publisher":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.streppone.it\/cosimo\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1","name":"cosimo","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/cb1d938720df45a2720724aae99e3bfc?s=96&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/cb1d938720df45a2720724aae99e3bfc?s=96&r=g","caption":"cosimo"},"logo":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/image\/"},"url":"https:\/\/www.streppone.it\/cosimo\/blog\/author\/cosimo\/"}]}},"_links":{"self":[{"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/posts\/558"}],"collection":[{"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/comments?post=558"}],"version-history":[{"count":20,"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/posts\/558\/revisions"}],"predecessor-version":[{"id":771,"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/posts\/558\/revisions\/771"}],"wp:attachment":[{"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/media?parent=558"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/categories?post=558"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/tags?post=558"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}