<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Realtime on Jason Wilder&#39;s Blog</title>
        <generator uri="https://gohugo.io">Hugo</generator>
        <link>http://jasonwilder.com/categories/realtime/</link>
        
        <language>en-us</language>  
        <updated>Tue, 19 Nov 2013 00:00:00 UTC</updated>
        
        <item>
            <title>Fluentd vs Logstash</title>
            <link>http://jasonwilder.com/blog/2013/11/19/fluentd-vs-logstash/</link>
            <pubDate>Tue, 19 Nov 2013 00:00:00 UTC</pubDate>
            
            <guid>http://jasonwilder.com/blog/2013/11/19/fluentd-vs-logstash/</guid>
            <description>

&lt;p&gt;&lt;a href=&#34;http://fluentd.org&#34;&gt;Fluentd&lt;/a&gt; and &lt;a href=&#34;http://logstash.net&#34;&gt;Logstash&lt;/a&gt; are two open-source projects that
focus on the problem of centralized logging.  Both projects address the &lt;a href=&#34;http://jasonwilder.com/blog/2013/07/16/centralized-logging-architecture/&#34;&gt;collection and transport&lt;/a&gt;
aspect of centralized logging using different approaches.&lt;/p&gt;

&lt;p&gt;This post will walk through a sample deployment to see how each differs from the other.  We&amp;rsquo;ll look
at the dependencies, features, deployment architecture and potential issues.  The point is not to figure out
which one is the best, but rather to see which one would be a better fit for your environment.&lt;/p&gt;

&lt;p&gt;The example setup we&amp;rsquo;ll walk through is collecting web server logs on multiple hosts and archiving
them to S3:&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;http://jasonwilder.com/images/centralized-logging-s3.png&#34; alt=&#34;Centralized Logs With S3&#34; /&gt;&lt;/p&gt;

&lt;p&gt;This type of architecture would be suitable for archival or processing with
&lt;a href=&#34;http://hive.apache.org/&#34;&gt;Hive&lt;/a&gt; or &lt;a href=&#34;http://pig.apache.org/&#34;&gt;Pig&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Another common architecture is storing logs in &lt;a href=&#34;http://www.elasticsearch.org/&#34;&gt;ElasticSearch&lt;/a&gt; to
make them searchable with &lt;a href=&#34;http://www.elasticsearch.org/overview/kibana/&#34;&gt;Kibana&lt;/a&gt;
or &lt;a href=&#34;http://graylog2.org/&#34;&gt;Graylog2&lt;/a&gt;. Setting that up is somewhat independent of using Logstash
or Fluentd so I&amp;rsquo;ve left that out to keep things simple.&lt;/p&gt;

&lt;h2 id=&#34;installation-requirements:d94954b9a471ac6eb86d0c66c558309a&#34;&gt;Installation Requirements&lt;/h2&gt;

&lt;h3 id=&#34;logstash:d94954b9a471ac6eb86d0c66c558309a&#34;&gt;Logstash&lt;/h3&gt;

&lt;p&gt;Logstash is a &lt;a href=&#34;http://jruby.org/&#34;&gt;JRuby&lt;/a&gt; based application which requires the JVM to run.  Since it runs on the JVM, it
can run anywhere the JVM does, which is usually means Linux, Mac OSX, and Windows.  The package is shipped
as single executable jar file which makes it very easy to install.&lt;/p&gt;

&lt;p&gt;One of the downsides of depending on the JVM is that it&amp;rsquo;s memory footprint can be higher than you
would want for transporting logs.  Fortunately, &lt;a href=&#34;https://github.com/elasticsearch/logstash-forwarder&#34;&gt;Lumberjack&lt;/a&gt;
can be run on individual hosts to collect and ship logs and Logstash can be run on the
centralized log hosts.&lt;/p&gt;

&lt;p&gt;Lumberjack is a Go based project with a much smaller memory
and CPU footprint. Deployment is still straightforward as Logstash and is basically installing a single
binary.  The project provides &lt;code&gt;deb&lt;/code&gt; and &lt;code&gt;rpm&lt;/code&gt; packages to make it easier to deploy.
An SSL certificates is required to setup authentication between Lumberjack and Logstash which is
a little more complicated, but a nice benefit that encrypted transport is the default.&lt;/p&gt;

&lt;h3 id=&#34;fluentd:d94954b9a471ac6eb86d0c66c558309a&#34;&gt;Fluentd&lt;/h3&gt;

&lt;p&gt;Fluentd is a &lt;a href=&#34;http://en.wikipedia.org/wiki/Ruby_MRI&#34;&gt;CRuby&lt;/a&gt; application which requires Ruby 1.9.2 or later.  There is an open-source
version, fluentd, as well as a commercial version, td-agent.  Fluentd runs on Linux and Mac OSX,
but &lt;a href=&#34;http://docs.fluentd.org/articles/faq#does-fluentd-run-on-windows&#34;&gt;does not run on Windows&lt;/a&gt; currently.&lt;/p&gt;

&lt;p&gt;For larger installs, they recommend using &lt;a href=&#34;http://www.canonware.com/jemalloc/&#34;&gt;jemalloc&lt;/a&gt; to
avoid memory fragmentation.  This is included in the &lt;code&gt;deb&lt;/code&gt; and &lt;code&gt;rpm&lt;/code&gt; packages but needs to be installed
manually if using the open-source version.&lt;/p&gt;

&lt;p&gt;If you use the open-source version, you&amp;rsquo;ll need to install Fluentd from source or via &lt;code&gt;gem install&lt;/code&gt;.
Since Fluentd is primarily developed by a commercial company, their &lt;code&gt;deb&lt;/code&gt; and &lt;code&gt;rpm&lt;/code&gt; packages are
configured to send data to their hosted centralized logging platform.&lt;/p&gt;

&lt;p&gt;Apart from Ruby, they also recommend running &lt;code&gt;ntpd&lt;/code&gt; which you should be running anyways.&lt;/p&gt;

&lt;h2 id=&#34;feature-comparison:d94954b9a471ac6eb86d0c66c558309a&#34;&gt;Feature Comparison&lt;/h2&gt;

&lt;p&gt;Logstash supports a number of inputs, codecs, filters and outputs.  Inputs are sources of data.
Codecs essentially convert an incoming format into an internal Logstash representation as well
as convert back out to an output format.  These are usually used if the incoming message is not
just a single line of text.  Filters are processing actions on events and
allow you to modify events or drop events as they are processed.  Finally, outputs are destinations
where events can be routed.&lt;/p&gt;

&lt;p&gt;Fluentd is similar in that it has inputs and outputs and a matching mechanism to route
log data between destinations.  Internally,
log messages are converted to JSON which provides structure to an unstructered log message.
Messages can be tagged and then routed to different outputs.&lt;/p&gt;

&lt;p&gt;Both projects have very similar capabilities and highlighting the difference between them from a
feature standpoint is difficult.  They both have plugin models that allow you to extend their functionality
if needed.  They also have rich repository of plugins already available.&lt;/p&gt;

&lt;p&gt;Probably the most significant difference between Fluentd and Logstash is their design focus.
&lt;em&gt;Logstash emphasizes flexibility and interoperability&lt;/em&gt; whereas
&lt;em&gt;Fluentd prioritizes simplicity and robustness&lt;/em&gt;.  This does not mean that
Logstash is not robust or Fluentd is not flexible, rather each has prioritized
features differently.&lt;/p&gt;

&lt;p&gt;Fluentd has fewer inputs than Logstash, out of the box, but many of the inputs
and outputs have built-in support for buffering, load-balancing, timeouts and retries.  These
types of features are necessary for ensuring data is reliably delivered.&lt;/p&gt;

&lt;p&gt;For example, the
&lt;a href=&#34;http://docs.fluentd.org/articles/out_forward&#34;&gt;out_forward&lt;/a&gt; plugin used to transfer logs from one
fluentd instance to another has many robustness options that can be configured to ensure messages
are delivered reliably.&lt;/p&gt;

&lt;h2 id=&#34;architecture-comparison:d94954b9a471ac6eb86d0c66c558309a&#34;&gt;Architecture comparison&lt;/h2&gt;

&lt;p&gt;From a deployment architecture standpoint, both frameworks are very similar.  With Logstash, each
web server would be configured to run Lumberjack and tail the web server logs.  Lumberjack would forward the logs
to a server running Logstash with a Lumberjack input.  The Logstash server would also have an
output configured using the &lt;a href=&#34;http://logstash.net/docs/1.2.2/outputs/s3&#34;&gt;S3 output&lt;/a&gt;.  Since Lumberjack
requires SSL certs, the log transfers would be encrypted from the web server to the log server.&lt;/p&gt;

&lt;p&gt;With fluentd, each web server would run fluentd and tail the web server logs and forward them to
another server running fluentd as well.  This server would be configured to receive logs and write
them to S3 using the &lt;a href=&#34;https://github.com/fluent/fluent-plugin-s3&#34;&gt;S3 plugin&lt;/a&gt;.  Fluentd does not
support encryption so logs would be transferred unencrypted.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Update: &lt;a href=&#34;https://twitter.com/repeatedly/status/402869393148760064&#34;&gt;@repeatedly&lt;/a&gt; pointed me to the
&lt;a href=&#34;https://github.com/tagomoris/fluent-plugin-secure-forward&#34;&gt;fluent-plugin-secure-forward&lt;/a&gt;
that some companies are using for encrypted transport.&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&#34;improving-availability:d94954b9a471ac6eb86d0c66c558309a&#34;&gt;Improving Availability&lt;/h3&gt;

&lt;p&gt;One central log server is a single point of failure.  What happens if we wanted to have more than
one central log server?&lt;/p&gt;

&lt;p&gt;Lumberjack can be configured to use &lt;a href=&#34;https://github.com/elasticsearch/logstash-forwarder#configuring&#34;&gt;multiple servers&lt;/a&gt;
but will only send logs to one until that one fails.  If that happens, previously collected log data
won&amp;rsquo;t be accessible until that host is resurrected.  Essentially, it supports a master with hot-standby
servers.&lt;/p&gt;

&lt;p&gt;Fluentd on the other hand can forward two copies of the logs to each server if needed, load-balance
between multiple hosts or have a master with a hot-standy in case of failure.  There are lot of
options for not only improving availabilty but also scalability if your log volume increases
substantially. Keep in mind, that if you forward multiple copies, this could create duplicate logs
in S3 which might need to be handled when you analyze them.&lt;/p&gt;

&lt;h2 id=&#34;potential-issues:d94954b9a471ac6eb86d0c66c558309a&#34;&gt;Potential Issues&lt;/h2&gt;

&lt;p&gt;The &lt;a href=&#34;http://logstash.net/docs/1.2.2/tutorials/getting-started-centralized&#34;&gt;Logstash docs&lt;/a&gt; suggests
using &lt;a href=&#34;http://redis.io&#34;&gt;Redis&lt;/a&gt; as the receiving output if you run Logstash (not Lumberjack) on each
host.  This setup is based on Redis Lists and/or Pub/Sub which can lose messages if
the receiver dies after removing the message from Redis and before it has had a chance to forward it
along.  Additionally, Redis would need to be configured with &lt;a href=&#34;http://redis.io/topics/persistence&#34;&gt;AOF&lt;/a&gt;
to minimize the chance of lost messages if Redis were to fail.&lt;/p&gt;

&lt;p&gt;There is a document describing &lt;a href=&#34;http://logstash.net/docs/1.2.2/life-of-an-event&#34;&gt;the life of an event&lt;/a&gt;
that discusses some of the failure modes and how Logstash addresses them.  One important point is
that outputs are responsible for retrying events in the case of errors.  There are also internal,
ephemeral queues within Logstash that can hold up to 20 events.  Depending on the failure, there is
a window for messages to be lost.&lt;/p&gt;

&lt;p&gt;If you absolutely cannot risk losing messages, make sure you investigate all the failure modes and
whether the plugins you are using are implemented correctly to handle them.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Update: &lt;a href=&#34;https://logstash.jira.com/browse/LOGSTASH-1631&#34;&gt;LOGSTASH-1631&lt;/a&gt; is a bug that
demonstrates one way messages can be lost. It appears the internal messaging is going to be
replaced with a more reliable implementation in the future.&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&#34;conclusion:d94954b9a471ac6eb86d0c66c558309a&#34;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Both Logstash and Fluentd are viable centralized logging frameworks that can transfer logs from
multiple hosts to a central location.  Logstash is incredibly flexible with many input and output
plugins whereas fluentd provides fewer input and output sources but provides multiple options
for reliably and robust transport.&lt;/p&gt;
</description>
        </item>
        
        <item>
            <title>Realtime Web Server Log Metrics</title>
            <link>http://jasonwilder.com/blog/2013/07/22/realtime-web-server-log-metrics/</link>
            <pubDate>Mon, 22 Jul 2013 00:00:00 UTC</pubDate>
            
            <guid>http://jasonwilder.com/blog/2013/07/22/realtime-web-server-log-metrics/</guid>
            <description>&lt;p&gt;This is a sample config that uses &lt;a href=&#34;http://nxlog-ce.sourceforge.net&#34;&gt;nxlog&lt;/a&gt; to tail web access logs in
Combined Log Format, pull out the status code and bytes sent and send them to statsd so they can be graphed
using Graphite.&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s a simple way to see if your web server is returning errors over time or how much data it&amp;rsquo;s sending.  The same
concept could be used for other log files.&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://github.com/etsy/logster&#34;&gt;Logster&lt;/a&gt; lets you do similar things but custom parsing
is accomplished by writing Python plugins which can be a little more complicated than using configuration
files.&lt;/p&gt;

&lt;p&gt;nxlog works by defining inputs, processors, outputs and routes that tie the inputs to processers and finally to outputs.&lt;/p&gt;

&lt;p&gt;For this example, I use the &lt;a href=&#34;http://nxlog-ce.sourceforge.net/nxlog-docs/en/nxlog-reference-manual.html#im_file&#34;&gt;im&lt;em&gt;file&lt;/a&gt;
module which will tail one or more files send each line along for processing.  nxlog will remember the last line read
by default so restarts or connectivity issues are handled gracefully.  After each line is read, the
line is passed to a _Exec&lt;/em&gt; statement that parses each field into variables.&lt;/p&gt;

&lt;p&gt;The parsing could be done in the processor but because of how the routes are setup, I chose to do it during input so
it only happens once.&lt;/p&gt;

&lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span class=&#34;c&#34;&gt;# Tail access log in Combined Log Format and parse out the fields.&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;&amp;lt;Input&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;in_nginx&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;Module&lt;/span&gt;  im_file
    &lt;span class=&#34;nb&#34;&gt;File&lt;/span&gt;	&lt;span class=&#34;s2&#34;&gt;&amp;quot;/var/log/nginx/access.log&amp;quot;&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;Exec&lt;/span&gt;    if $raw_event =~ /^(\S+) (\S+) (\S+) \[([^\]]+)\] \&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;(\S+) (.+) HTTP.\d\.\d\&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt; (\d+) (\d+) \&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;([^\&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;]+)\&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt; \&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;([^\&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;]+)\&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;/\
                { \
                  $Hostname = $1; \
                  if $3 != &amp;#39;-&amp;#39; $AccountName = $3; \
                  $EventTime = parsedate($4); \
                  $HTTPMethod = $5; \
                  $HTTPURL = $6; \
                  $HTTPResponseStatus = $7; \
                  $HTTPBytesSent = $8; \
                  $HTTPReferer = $9; \
                  $HTTPUserAgent = $10; \
                }
&lt;span class=&#34;nt&#34;&gt;&amp;lt;/Input&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;There are two processors configured &lt;em&gt;http_status&lt;/em&gt; and &lt;em&gt;http_bytes&lt;/em&gt;.  Each one checks to make sure the required
data has been parsed and then rewrites the event into a &lt;a href=&#34;https://github.com/b/statsd_spec&#34;&gt;statsd protocol&lt;/a&gt;
metric.  Both processors create a counter metric that statsd will sum up and roll-over at every interval.&lt;/p&gt;

&lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span class=&#34;c&#34;&gt;# Rewrite the log message to a statsd counter event using the HTTP status code.&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;&amp;lt;Processor&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;http_status&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;Module&lt;/span&gt;      pm_null
    &lt;span class=&#34;nb&#34;&gt;Exec&lt;/span&gt;        if defined($HTTPResponseStatus) { \
		          $raw_event = &lt;span class=&#34;s2&#34;&gt;&amp;quot;http.status.&amp;quot;&lt;/span&gt; + $HTTPResponseStatus + &lt;span class=&#34;s2&#34;&gt;&amp;quot;:1|c&amp;quot;&lt;/span&gt;; \
                } else { \
                  drop(); \
                }
&lt;span class=&#34;nt&#34;&gt;&amp;lt;/Processor&amp;gt;&lt;/span&gt;

&lt;span class=&#34;c&#34;&gt;# Rewrite the log message to a statsd counter event using the bytes sent.&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;&amp;lt;Processor&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;http_bytes&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;Module&lt;/span&gt;      pm_null
    &lt;span class=&#34;nb&#34;&gt;Exec&lt;/span&gt;        if defined($HTTPBytesSent) { \
		          $raw_event = &lt;span class=&#34;s2&#34;&gt;&amp;quot;http.bytes.&amp;quot;&lt;/span&gt; + $HTTPBytes + &lt;span class=&#34;s2&#34;&gt;&amp;quot;:&amp;quot;&lt;/span&gt; + $HTTPBytesSent + &lt;span class=&#34;s2&#34;&gt;&amp;quot;|c&amp;quot;&lt;/span&gt;; \
                } else { \
                  drop(); \
                }
&lt;span class=&#34;nt&#34;&gt;&amp;lt;/Processor&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;The output is a &lt;a href=&#34;http://nxlog-ce.sourceforge.net/nxlog-docs/en/nxlog-reference-manual.html#om_udp&#34;&gt;om_udp&lt;/a&gt;
that forwards the re-written log event to a statsd instance.&lt;/p&gt;

&lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span class=&#34;c&#34;&gt;# Statsd uses UDP&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;&amp;lt;Output&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;out_statsd&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;Module&lt;/span&gt;	om_udp
    &lt;span class=&#34;nb&#34;&gt;Host&lt;/span&gt;	&lt;span class=&#34;m&#34;&gt;127.0.0.1&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;Port&lt;/span&gt;	&lt;span class=&#34;m&#34;&gt;8125&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;&amp;lt;/Output&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;Finally, two routes are created that originate from the same input file but are sent to separate processors and back
to the same output.  Since processors are normally chained together and I&amp;rsquo;m re-writing the event, chaining them
together doesn&amp;rsquo;t work.  Instead I need a new copy of the log message for each processor.&lt;/p&gt;

&lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span class=&#34;c&#34;&gt;# Route nginx access log through status processor and out to statsd&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;&amp;lt;Route&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;web_status_statsd&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;Path&lt;/span&gt;        in_nginx =&amp;gt; http_status =&amp;gt; out_statsd
&lt;span class=&#34;nt&#34;&gt;&amp;lt;/Route&amp;gt;&lt;/span&gt;

&lt;span class=&#34;c&#34;&gt;# Since we re-wrote the log event, define a new route for bytes sent&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;&amp;lt;Route&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;web_bytes_statsd&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;Path&lt;/span&gt;        in_nginx =&amp;gt; http_bytes =&amp;gt; out_statsd
&lt;span class=&#34;nt&#34;&gt;&amp;lt;/Route&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;And the whole thing put together:&lt;/p&gt;

&lt;p&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;pre&gt;&lt;span class=&#34;c&#34;&gt;# Tail access log in Combined Log Format and parse out the fields.&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;&amp;lt;Input&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;in_nginx&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;Module&lt;/span&gt;  im_file
    &lt;span class=&#34;nb&#34;&gt;File&lt;/span&gt;	&lt;span class=&#34;s2&#34;&gt;&amp;quot;/var/log/nginx/access.log&amp;quot;&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;Exec&lt;/span&gt;    if $raw_event =~ /^(\S+) (\S+) (\S+) \[([^\]]+)\] \&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;(\S+) (.+) HTTP.\d\.\d\&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt; (\d+) (\d+) \&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;([^\&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;]+)\&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt; \&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;([^\&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;]+)\&lt;span class=&#34;err&#34;&gt;&amp;quot;&lt;/span&gt;/\
                { \
                  $Hostname = $1; \
                  if $3 != &amp;#39;-&amp;#39; $AccountName = $3; \
                  $EventTime = parsedate($4); \
                  $HTTPMethod = $5; \
                  $HTTPURL = $6; \
                  $HTTPResponseStatus = $7; \
                  $HTTPBytesSent = $8; \
                  $HTTPReferer = $9; \
                  $HTTPUserAgent = $10; \
                }
&lt;span class=&#34;nt&#34;&gt;&amp;lt;/Input&amp;gt;&lt;/span&gt;

&lt;span class=&#34;c&#34;&gt;# Rewrite the log message to a statsd counter event using the HTTP status code.&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;&amp;lt;Processor&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;http_status&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;Module&lt;/span&gt;      pm_null
    &lt;span class=&#34;nb&#34;&gt;Exec&lt;/span&gt;        if defined($HTTPResponseStatus) { \
		          $raw_event = &lt;span class=&#34;s2&#34;&gt;&amp;quot;http.status.&amp;quot;&lt;/span&gt; + $HTTPResponseStatus + &lt;span class=&#34;s2&#34;&gt;&amp;quot;:1|c&amp;quot;&lt;/span&gt;; \
                } else { \
                  drop(); \
                }
&lt;span class=&#34;nt&#34;&gt;&amp;lt;/Processor&amp;gt;&lt;/span&gt;

&lt;span class=&#34;c&#34;&gt;# Rewrite the log message to a statsd counter event using the bytes sent.&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;&amp;lt;Processor&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;http_bytes&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;Module&lt;/span&gt;      pm_null
    &lt;span class=&#34;nb&#34;&gt;Exec&lt;/span&gt;        if defined($HTTPBytesSent) { \
		          $raw_event = &lt;span class=&#34;s2&#34;&gt;&amp;quot;http.bytes.&amp;quot;&lt;/span&gt; + $HTTPBytes + &lt;span class=&#34;s2&#34;&gt;&amp;quot;:&amp;quot;&lt;/span&gt; + $HTTPBytesSent + &lt;span class=&#34;s2&#34;&gt;&amp;quot;|c&amp;quot;&lt;/span&gt;; \
                } else { \
                  drop(); \
                }
&lt;span class=&#34;nt&#34;&gt;&amp;lt;/Processor&amp;gt;&lt;/span&gt;

&lt;span class=&#34;c&#34;&gt;# Statsd uses UDP&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;&amp;lt;Output&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;out_statsd&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;Module&lt;/span&gt;	om_udp
    &lt;span class=&#34;nb&#34;&gt;Host&lt;/span&gt;	&lt;span class=&#34;m&#34;&gt;127.0.0.1&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;Port&lt;/span&gt;	&lt;span class=&#34;m&#34;&gt;8125&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;&amp;lt;/Output&amp;gt;&lt;/span&gt;

&lt;span class=&#34;c&#34;&gt;# Route nginx access log through status processor and out to statsd&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;&amp;lt;Route&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;web_status_statsd&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;Path&lt;/span&gt;        in_nginx =&amp;gt; http_status =&amp;gt; out_statsd
&lt;span class=&#34;nt&#34;&gt;&amp;lt;/Route&amp;gt;&lt;/span&gt;

&lt;span class=&#34;c&#34;&gt;# Since we re-wrote the log event, define a new route for bytes sent&lt;/span&gt;
&lt;span class=&#34;nt&#34;&gt;&amp;lt;Route&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;web_bytes_statsd&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&#34;nb&#34;&gt;Path&lt;/span&gt;        in_nginx =&amp;gt; http_bytes =&amp;gt; out_statsd
&lt;span class=&#34;nt&#34;&gt;&amp;lt;/Route&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
