<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Realm of Chaos</title>
    <subtitle>Welcome to my notebook! I’m a Site Reliability Engineer who is curious, loves to learn and discover the nature of things.</subtitle>
    <link rel="self" type="application/atom+xml" href="https://realmofchaos.xyz/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://realmofchaos.xyz"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2022-05-10T00:00:00+00:00</updated>
    <id>https://realmofchaos.xyz/atom.xml</id>
    <entry xml:lang="en">
        <title>The art of extracting metrics</title>
        <published>2022-05-10T00:00:00+00:00</published>
        <updated>2022-05-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Thomas Cuthbert
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://realmofchaos.xyz/tech/performance-analysis/extracting-metrics/"/>
        <id>https://realmofchaos.xyz/tech/performance-analysis/extracting-metrics/</id>
        
        <content type="html" xml:base="https://realmofchaos.xyz/tech/performance-analysis/extracting-metrics/">&lt;h2 id=&quot;awk&quot;&gt;Awk&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;filtering-between-log-timestamps&quot;&gt;filtering between log timestamps&lt;&#x2F;h3&gt;
&lt;p&gt;second precision&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;awk \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -v from=&amp;quot;$(date +&amp;#39;%s&amp;#39; -d &amp;#39;2021-10-29 02:34&amp;#39; --utc)&amp;quot; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -v to=&amp;quot;$(date +&amp;#39;%s&amp;#39; -d &amp;#39;2021-10-29 02:36&amp;#39; --utc)&amp;quot; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  split($0, parts, &#x2F;[\- :]&#x2F;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    linefmt=&amp;quot;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    for(i=1;i&amp;lt;=6;i++) linefmt = sprintf(&amp;quot;%s %s&amp;quot;,linefmt, parts[i]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ts=mktime(sprintf(&amp;quot;%s UTC&amp;quot;, linefmt))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    if (ts &amp;gt; from &amp;amp;&amp;amp; ts &amp;lt; to) print&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &amp;#39;&amp;lt;&amp;lt;&amp;lt;&amp;#39;2021-10-29 04:50:00 172.31.43.164&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;awk \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -v from=&amp;quot;$(date +&amp;#39;%s&amp;#39; -d &amp;#39;2021-11-27 04:15:00 UTC&amp;#39; --utc)&amp;quot; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -v to=&amp;quot;$(date +&amp;#39;%s&amp;#39; -d &amp;#39;now UTC&amp;#39; --utc)&amp;quot; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  patsplit($1, p, &#x2F;[0-9]+&#x2F;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ts=mktime(sprintf(&amp;quot;%d %d %d %d %d %d&amp;quot;, p[1], p[2], p[3], p[4], p[5], p[6]), 1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    if (ts &amp;gt; from &amp;amp;&amp;amp; ts &amp;lt; to) print&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &amp;#39; &amp;lt;(tac &#x2F;var&#x2F;log&#x2F;frr&#x2F;frr.log)|head&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;perl-alternative&quot;&gt;perl alternative&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;from=&amp;quot;$(date -Is -d &amp;#39;2021-11-27T04:15:00 UTC&amp;#39; --utc)&amp;quot; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;to=&amp;quot;$(date -Is -d &amp;#39;now UTC&amp;#39; --utc)&amp;quot; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;perl \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -MDate::Parse \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -lane \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  $ts=str2time($F[0]);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  $f=str2time($ENV{from});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  $t=str2time($ENV{to});&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  print if ($ts &amp;gt;= $f &amp;amp;&amp;amp; $ts &amp;lt;= $t )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &amp;#39; &amp;lt;(zcat -f &#x2F;var&#x2F;log&#x2F;syslog*) | tee &amp;quot;&#x2F;syslog-$(date -Im)&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;from-ms-precision-unix-timestamp&quot;&gt;from ms precision unix timestamp&lt;&#x2F;h2&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;awk \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -v format=&amp;quot;%F %T&amp;quot; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -v from=&amp;quot;$(date +&amp;#39;%s&amp;#39; -d &amp;#39;2021-10-29 02:34&amp;#39; --utc)&amp;quot; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  -v to=&amp;quot;$(date +&amp;#39;%s&amp;#39; -d &amp;#39;2021-10-29 02:36&amp;#39; --utc)&amp;quot; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &amp;#39;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ts=substr($0, 0, index($0, &amp;quot;.&amp;quot;)-1)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  if (ts &amp;gt; from &amp;amp;&amp;amp; ts &amp;lt; to) print strftime(format, ts), substr($0,index($0,$1))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  &amp;#39; &amp;lt;&amp;lt;&amp;lt;&amp;#39;2021-10-29 04:50:00 172.31.43.164&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;sed&quot;&gt;Sed&lt;&#x2F;h2&gt;
&lt;p&gt;Filtering interesting lines for nxos. Note, NXOS has an ancient version of sed, it only supports the &lt;code&gt;-n&lt;&#x2F;code&gt; flag.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;monitoring-procfs&quot;&gt;monitoring procfs&lt;&#x2F;h2&gt;
&lt;p&gt;Continuously monitor a procfs file, output is tabular.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;cat &#x2F;proc&#x2F;pressure&#x2F;cpu&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;some avg10=1.34 avg60=1.63 avg300=2.33 total=2483371233&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;full avg10=0.18 avg60=0.03 avg300=0.06 total=827064553&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;ul&gt;
&lt;li&gt;sleep trap: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;65644307&#x2F;ctrl-c-doesnt-always-terminate-a-shell-script&quot;&gt;https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;65644307&#x2F;ctrl-c-doesnt-always-terminate-a-shell-script&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;getline summary: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gnu.org&#x2F;software&#x2F;gawk&#x2F;manual&#x2F;gawk.html#Getline-Summary&quot;&gt;https:&#x2F;&#x2F;www.gnu.org&#x2F;software&#x2F;gawk&#x2F;manual&#x2F;gawk.html#Getline-Summary&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;printf formatting: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;bl831.als.lbl.gov&#x2F;~gmeigs&#x2F;scripting_help&#x2F;printf_awk_notes.txt&quot;&gt;https:&#x2F;&#x2F;bl831.als.lbl.gov&#x2F;~gmeigs&#x2F;scripting_help&#x2F;printf_awk_notes.txt&lt;&#x2F;a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gnu.org&#x2F;software&#x2F;gawk&#x2F;manual&#x2F;html_node&#x2F;Printf.html&quot;&gt;https:&#x2F;&#x2F;www.gnu.org&#x2F;software&#x2F;gawk&#x2F;manual&#x2F;html_node&#x2F;Printf.html&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;!-- --&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;awk -F&amp;#39;[ =]&amp;#39; -vlinefmt=&amp;quot;%-8s%-8s%-10s%-10s%-8s\n&amp;quot; -vcpu_pressure=&amp;quot;&#x2F;proc&#x2F;pressure&#x2F;cpu&amp;quot; &amp;#39;BEGIN {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    printf linefmt, &amp;quot;avg10&amp;quot;, &amp;quot;avg60&amp;quot;, &amp;quot;avg300&amp;quot;, &amp;quot;increase&amp;quot;, &amp;quot;total&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    do {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        if (system(&amp;quot;trap true INT; sleep 1&amp;quot;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            exit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        if ($1==&amp;quot;full&amp;quot;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            printf linefmt, $3, $5, $7, int($9-prev_tot), $9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            prev_tot = $9&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } while ((getline &amp;lt; cpu_pressure) || (close(cpu_pressure) == 0))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;avg10   avg60   avg300    increase  total&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0.36    0.17    0.07      829472174 829472174&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0.36    0.17    0.07      0         829472174&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;0.24    0.16    0.07      24957     829497131&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;collect metrics for all PSI.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;awk -F&amp;#39;[ =\t]&amp;#39; -vlinefmt=&amp;quot;%-14s&amp;quot; -vfields=&amp;#39;&amp;quot;cpuavg10&amp;quot;, &amp;quot;cpuavg60&amp;quot;, &amp;quot;cpuavg300&amp;quot;, &amp;quot;cputotal&amp;quot;, &amp;quot;cpuincrease&amp;quot;, &amp;quot;ioavg10&amp;quot;, &amp;quot;ioavg60&amp;quot;, &amp;quot;ioavg300&amp;quot;, &amp;quot;iototal&amp;quot;, &amp;quot;ioincrease&amp;quot;, &amp;quot;memavg10&amp;quot;, &amp;quot;memavg60&amp;quot;, &amp;quot;memavg300&amp;quot;, &amp;quot;memtotal&amp;quot;,&amp;quot;memincrease&amp;quot;&amp;#39; -vcpu_pressure=&amp;quot;bash -c &amp;#39;paste &#x2F;proc&#x2F;pressure&#x2F;{cpu,io,memory}&amp;#39;&amp;quot; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;#39;BEGIN { patsplit(fields, fmts, &#x2F;[^&amp;quot;, ]+&#x2F;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    do {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        if (system(&amp;quot;trap true INT; sleep 1&amp;quot;)) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            exit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        if ($1==&amp;quot;some&amp;quot;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            for(x in fmts) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                printf linefmt, fmts[x]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            printf &amp;quot;\n&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            for(i=3;i&amp;lt;=NF;i+=2) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                if(i%9 == 0 &amp;amp;&amp;amp; i%3 == 0) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    printf linefmt&amp;quot;&amp;quot;linefmt, $(i), int($(i)-increase[i]) &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    increase[i]=$i&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    i+=1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                } else {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    printf linefmt, $i&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            printf &amp;quot;\n\n&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    } while ((cpu_pressure|getline) || (close(cpu_pressure) == 0))&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;histograms&quot;&gt;histograms&lt;&#x2F;h2&gt;
&lt;p&gt;The .1 decimal for size helps tie breakers when min == max.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;while :; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ss -n -t -o $(printf &amp;quot; state %s&amp;quot; {fin-wait-1,fin-wait-2,time-wait,close-wait,last-ack,closing}) |\&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    awk -v bmin=0 -vsize=10000.1 &amp;#39;BEGIN{tm[&amp;quot;sec&amp;quot;] = 1000;tm[&amp;quot;min&amp;quot;] = &amp;quot;60000&amp;quot;} match($6,&#x2F;,([0-9.]+)(sec|ms|min)&#x2F;,m){t=(m[2]==&amp;quot;ms&amp;quot;?int(m[1]):int(tm[m[2]]*m[1]) );b=int(t&#x2F;size);a[b]++;bmax=b&amp;gt;bmax?b:bmax; bmin=b&amp;lt;bmin?b:bmin} END{for(i=bmin;i&amp;lt;=bmax;++i) printf &amp;quot;%d %d %d\n&amp;quot;, (i*size)&#x2F;tm[&amp;quot;sec&amp;quot;],((i+1)*size)&#x2F;tm[&amp;quot;sec&amp;quot;],a[i]}&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  sleep 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Using time functions.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;LC_ALL=C awk -v bmin=0 -vsize=10.1 -v date=&amp;quot;2022 03 06&amp;quot; &amp;#39;split($4,p,&#x2F;[: ]&#x2F;){t=mktime(date&amp;quot; &amp;quot;p[2]&amp;quot; &amp;quot;p[3]&amp;quot; &amp;quot;p[4]); b=int(t&#x2F;size);a[b]++;bmax=b&amp;gt;bmax?b:bmax; bmin=b&amp;lt;bmin?b:bmin} END{for(i=bmin;i&amp;lt;=bmax;++i) if(a[i]) printf &amp;quot;%s %s %d\n&amp;quot;, strftime(&amp;quot;%T&amp;quot;,(i*size)),strftime(&amp;quot;%T&amp;quot;,((i+1)*size)),a[i]}&amp;#39; gopkg.in-access.log-2022-03-06T13\:00.log&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Useful squid one&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;for i in $(awk &amp;#39;!s[$4]++{print $4}&amp;#39; squid-access.log); do  LC_ALL=C awk -v bmin=0 -vsize=300.1 -vhist=&amp;quot;$i&amp;quot; &amp;#39;$0 !~ hist{next} {t=int($1);b=int(t&#x2F;size);a[b]++;bmax=b&amp;gt;bmax?b:bmax; bmin=b&amp;lt;bmin?b:bmin} END{printf &amp;quot;%s 300s histogram\n&amp;quot;, hist;for(i=bmin;i&amp;lt;=bmax;++i) if(a[i]) printf &amp;quot;%s %s %d\n&amp;quot;, strftime(&amp;quot;%T&amp;quot;,(i*size)),strftime(&amp;quot;%T&amp;quot;,((i+1)*size)),a[i] &amp;gt; &amp;quot;histograms.sout&amp;quot;}&amp;#39; squid-access.log; done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;LC_ALL=C awk -v bmin=0 -vsize=10.1 -v date=&amp;quot;2022 03 06&amp;quot; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;#39;split($4, p, &#x2F;[: ]&#x2F;) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  t = mktime(date &amp;quot; &amp;quot; p[2] &amp;quot; &amp;quot; p[3] &amp;quot; &amp;quot; p[4])&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  b = int(t &#x2F; size)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  a[b]++&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  bmax = b &amp;gt; bmax ? b : bmax&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  bmin = b &amp;lt; bmin ? b : bmin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;END {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  for (i = bmin; i &amp;lt;= bmax; ++i) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    if (a[i]) {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      printf &amp;quot;%s %s %d\n&amp;quot;, strftime(&amp;quot;%T&amp;quot;, (i * size)), strftime(&amp;quot;%T&amp;quot;, ((i + 1) * size)), a[i]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;iptables filtering&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo iptables -t nat  -nL |awk -vrgxp=&amp;quot;$(rgxg cidr 10.131.31.0&#x2F;24)&amp;quot; &amp;#39;&#x2F;^(Chain|target)&#x2F;{f=1} f==1||$0 ~ rgxp{s[NR]=$0;f++}; length($0)==0{if(f&amp;gt;2){for(i in s) print s[i]};split(&amp;quot;&amp;quot;,s);f=0}&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>networking</title>
        <published>2022-04-20T00:00:00+00:00</published>
        <updated>2022-04-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Thomas Cuthbert
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://realmofchaos.xyz/tech/networking/"/>
        <id>https://realmofchaos.xyz/tech/networking/</id>
        
        <content type="html" xml:base="https://realmofchaos.xyz/tech/networking/">&lt;h2 id=&quot;linux-tcp-tuning&quot;&gt;Linux TCP tuning&lt;&#x2F;h2&gt;
&lt;p&gt;These are example Netflix TCP kernel parameters.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;net.core.default_qdisc = fq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;net.core.netdev_max_backlog = 5000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;net.core.rmem_max = 16777216&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;net.core.somaxconn = 1024&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;net.core.wmem_max = 16777216&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;net.ipv4.ip_local_port_range = 10240 65535&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;net.ipv4.tcp_abort_on_overflow = 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;net.ipv4.tcp_congestion_control = bbr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;net.ipv4.tcp_max_syn_backlog = 8192&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;net.ipv4.tcp_rmem = 4096 12582912 16777216&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;net.ipv4.tcp_slow_start_after_idle = 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;net.ipv4.tcp_syn_retries = 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;net.ipv4.tcp_tw_reuse = 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;net.ipv4.tcp_wmem = 4096 12582912 16777216&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;These are some examples I came up with for an apache2 site running moin via wsgi.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# WSGIDaemonProcess moin processes=12 threads=1 maximum-requests=5000 queue-timeout=20&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;net.core.somaxconn = 256 # observed max number of requests on the scoreboard&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# consider being more aggressive with flaky connections&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# try this first&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#net.ipv4.tcp_slow_start_after_idle = 0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# aggressively reap flakey connections. avoid queue saturation from slow&#x2F;flakey&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# clients&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#net.ipv4.tcp_fin_timeout = 5&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#net.ipv4.tcp_syn_retries = 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#net.ipv4.tcp_synack_retries = 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# then maybe this&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#net.ipv4.tcp_tw_reuse = 1 # this should only be enabled if we are seeing a high rate of time-wait connections&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# needs further investigation, but potentially some of the below could be used&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#net.core.rmem_max = 16777216&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#net.core.wmem_max = 16777216&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#net.ipv4.tcp_rmem = 4096 12582912 16777216&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#net.ipv4.tcp_wmem = 4096 12582912 16777216&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#net.ipv4.tcp_mem = 1638400 1638400 1638400&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# &#x2F;etc&#x2F;systemd&#x2F;system&#x2F;apache2.service.d&#x2F;prlimits.conf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#[Service]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#LimitNOFILE=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;#LimitNOFILE=infinity&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Application Performance Analysis</title>
        <published>2022-03-22T00:00:00+00:00</published>
        <updated>2022-03-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Thomas Cuthbert
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://realmofchaos.xyz/tech/incident-response/"/>
        <id>https://realmofchaos.xyz/tech/incident-response/</id>
        
        <content type="html" xml:base="https://realmofchaos.xyz/tech/incident-response/">&lt;p&gt;In this post I will detail the investigation process I followed while responding to a request backlog alert.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;High level overview of the alerting service&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;mermaid&quot;&gt;
flowchart TD
    HAProxy --&gt; App --&gt; Storage
&lt;&#x2F;pre&gt;
&lt;script src=&quot;https:&#x2F;&#x2F;realmofchaos.xyz&#x2F;js&#x2F;mermaid-init.js&quot;&gt;&lt;&#x2F;script&gt;
&lt;p&gt;I’ve redacted any identifiable information, however the methodolgy remains the same.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;frontend-haproxy&quot;&gt;Frontend (HAProxy)&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;halog&lt;&#x2F;code&gt; tool can generate lots of useful reports. Adjust the time slice so you have a decent buffer before and after the time of the incident.&lt;&#x2F;p&gt;
&lt;p&gt;The snippet below will generate a series of reports:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;URL averages&lt;&#x2F;li&gt;
&lt;li&gt;URL total times OK averages&lt;&#x2F;li&gt;
&lt;li&gt;Connect&#x2F;response histogram &lt;sup&gt;&lt;a href=&quot;javascript:;&quot; onclick=&quot;document.location.hash=&amp;#39;#fn1&amp;#39;;&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The &lt;code&gt;-e&lt;&#x2F;code&gt; flag filters by errors.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo cat &#x2F;var&#x2F;log&#x2F;haproxy.log|halog -time &amp;quot;$(date &amp;#39;+%s&amp;#39; -d &amp;#39;6 hour ago&amp;#39;)&amp;quot; -H -ua|awk &amp;#39;NR==1;NR&amp;gt;1{print $0 | &amp;quot;sort -rnk4&amp;quot;}&amp;#39;|head -n25|column -t&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo cat &#x2F;var&#x2F;log&#x2F;haproxy.log|halog -e -time &amp;quot;$(date &amp;#39;+%s&amp;#39; -d &amp;#39;6 hour ago&amp;#39;)&amp;quot; -H -uto|awk &amp;#39;NR==1;NR&amp;gt;1{print $0 | &amp;quot;sort -rnk4&amp;quot;}&amp;#39;|head -n25|column -t&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo cat &#x2F;var&#x2F;log&#x2F;haproxy.log|halog -time &amp;quot;$(date &amp;#39;+%s&amp;#39; -d &amp;#39;6 hour ago&amp;#39;)&amp;quot; -pct -q&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sudo cat &#x2F;var&#x2F;log&#x2F;haproxy.log|halog  -time &amp;quot;$(date &amp;#39;+%s&amp;#39; -d &amp;#39;6 hour ago&amp;#39;)&amp;quot; -H -srv|awk &amp;#39;NR==1;NR&amp;gt;1{print $0 | &amp;quot;sort -rnk12&amp;quot;}&amp;#39;|column -t&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;application-server&quot;&gt;Application server&lt;&#x2F;h2&gt;
&lt;p&gt;Capture 5 minutes worth of TCP header data. Limit pcap file size to 500M. Absolute sequence numbers &lt;sup&gt;&lt;a href=&quot;javascript:;&quot; onclick=&quot;document.location.hash=&amp;#39;#fn2&amp;#39;;&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; .&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;intf=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;timeout 300s tcpdump -i &amp;quot;${intf?}&amp;quot; -vvvSs 1500 -C500 -w cap_5m.pcap &amp;#39;tcp &amp;amp;&amp;amp; net 10.0.0.0&#x2F;16&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Analyse the data with &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.wireshark.org&#x2F;docs&#x2F;man-pages&#x2F;tshark.html&quot;&gt;tshark&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;gt; cap.analysis \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  tshark -r cap_5m.pcap -t ud \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    -z \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    endpoints,tcp \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    -z \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    expert,comment,tcp \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    -T \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    fields \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    -e \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _ws.col.Time \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    -e \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ip.src \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    -e \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ip.dst \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    -e \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    tcp.dstport \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    -e \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _ws.expert.message \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    -e \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _ws.expert.severity \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    -e \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _ws.expert.group \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    -e \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    _ws.col.Info&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Identify any problematic flows from the &lt;code&gt;cap.analysis&lt;&#x2F;code&gt; file tshark generated. In my case, I observed a high rate of TCP Window Full responses from the server, indicating that the application was pushing too much data to it, or the server may be having systemic overload issues.&lt;&#x2F;p&gt;
&lt;p&gt;You can confirm your theory by monitoring tcp statistics over time.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;System level tcp stats.&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;while sleep 300; stdbuf -o0 nstat -p; done tee nstat.sout&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;Endpoint level statistics&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;ip -s tcpmetrics&lt;&#x2F;code&gt; provides similar data, I prefer the socket stats tool &lt;code&gt;ss&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;for i in {0..300}; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  echo === ; ss -in state synchronized &amp;#39;dst 10.0.0.10 &amp;#39;; echo ===&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  sleep 1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;done | tee sockets2.sout&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;awk &amp;#39;&#x2F;ESTAB&#x2F;&amp;amp;&amp;amp;&#x2F;10.0.0&#x2F;&amp;amp;&amp;amp;and($4,$5){print &amp;quot;&amp;quot;;print;print &amp;quot;&amp;quot;;getline;l=patsplit($0,f,&#x2F;[^:[:blank:]]*&#x2F;);for(i=1;i&amp;lt;=l;i+=2) printf &amp;quot;%24s %24s\n&amp;quot;, f[i],f[i+1]}&amp;#39; sockets2.sout&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;From the output I observed the following:&lt;&#x2F;p&gt;
&lt;p&gt;The application server misses too many acknowledgements and backs off from sending data (&lt;code&gt;backoff 1&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                     rto                      208&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                     rtt              4.714&#x2F;0.643&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                     ato                       40&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                     mss                     1374&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    pmtu                     1426&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                  rcvmss                      536&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                  advmss                     1374&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    cwnd                      143&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    send                333.4Mbps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;             pacing_rate                400.1Mbps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;           delivery_rate                257.2Mbps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    busy                  11672ms&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            rwnd_limited           11388ms(97.6%)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                 unacked                      126&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                 retrans                     0&#x2F;12&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              reordering                       74&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                 notsent                  1051110&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                  minrtt                    0.993&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                     rto                      216&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                 backoff                        1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                     rtt            14.491&#x2F;16.568&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                     ato                       40&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                     mss                     1374&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    pmtu                     1426&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                  rcvmss                      536&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                  advmss                     1374&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    cwnd                      143&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    send                108.5Mbps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;             pacing_rate                130.2Mbps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;           delivery_rate                  3.3Mbps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    busy                  12680ms&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            rwnd_limited           12360ms(97.5%)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                 retrans                     0&#x2F;16&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              reordering                       74&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                 notsent                  1023662&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                  minrtt                    0.993&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                     rto                      208&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                     rtt              5.519&#x2F;0.312&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                     ato                       40&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                     mss                     1374&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    pmtu                     1426&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                  rcvmss                      536&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                  advmss                     1374&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    cwnd                      217&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    send                432.2Mbps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;             pacing_rate                518.6Mbps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;           delivery_rate                254.7Mbps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    busy                  15700ms&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            rwnd_limited           15324ms(97.6%)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                 unacked                      133&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                 retrans                     0&#x2F;17&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;              reordering                       74&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                 notsent                  1719216&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                  minrtt                    0.993&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can get richer statistics by analysing the packet capture with tshark. The output is easily grep’d. My favourite statistic report is the io,stat table, you pass it packet fields to aggregate over and produce a configurable histogram. In my example below I created a per second packet rate and window size histogram.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tshark  -r cap_5m.pcap -q -z http_srv,tree&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tshark  -r cap_5m.pcap -q -z http_srv,tree -z conv,tcp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;grep -P &amp;#39;Window Full|PUT&amp;#39; cap.analysis|head;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;tshark -n -q -r *.pcap -z io,stat,1,&amp;quot;COUNT(tcp.window_size_value)tcp.window_size_value and ip.addr==10.0.0.10 &amp;amp;&amp;amp; tcp.dstport == 8080&amp;quot;,&amp;quot;MIN(tcp.window_size_value)tcp.window_size_value and ip.addr==10.0.0.10 &amp;amp;&amp;amp; tcp.dstport == 8080&amp;quot;,&amp;quot;MAX(tcp.window_size_value)tcp.window_size_value and ip.addr==10.0.0.10 &amp;amp;&amp;amp; tcp.dstport == 8080&amp;quot;,&amp;quot;AVG(tcp.window_size_value)tcp.window_size_value and ip.addr==10.0.0.10 &amp;amp;&amp;amp; tcp.dstport == 8080&amp;quot; |grep -v &amp;#39; 0 &amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2022-03-22 09:45:08.845938      10.0.1.100      10.0.0.10       8080    PUT &#x2F;api&#x2F;resource HTTP&#x2F;1.1\r\n   2097152 33554432        PUT &#x2F;api&#x2F;resource HTTP&#x2F;1.1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2022-03-22 09:45:09.116693      10.0.1.100      10.0.0.10       8080    PUT &#x2F;api&#x2F;resource HTTP&#x2F;1.1  [TCP segment of a reassembled PDU]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2022-03-22 09:45:09.245875      10.0.1.100      10.0.0.10       8080    TCP window specified by the receiver is now completely full     6291456 33554432        [TCP Window Full] Continuation[Packet size limited during capture]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2022-03-22 09:45:09.250035      10.0.1.100      10.0.0.10       8080    TCP window specified by the receiver is now completely full     6291456 33554432        [TCP Window Full] Continuation[Packet size limited during capture]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2022-03-22 09:45:09.250133      10.0.1.100      10.0.0.10       8080    TCP window specified by the receiver is now completely full     6291456 33554432        [TCP Window Full] Continuation[Packet size limited during capture]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2022-03-22 09:45:09.253985      10.0.1.100      10.0.0.10       8080    TCP window specified by the receiver is now completely full     6291456 33554432        [TCP Window Full] Continuation[Packet size limited during capture]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2022-03-22 09:45:09.255907      10.0.1.100      10.0.0.10       8080    TCP window specified by the receiver is now completely full     6291456 33554432        [TCP Window Full] Continuation[Packet size limited during capture]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2022-03-22 09:45:09.257952      10.0.1.100      10.0.0.10       8080    TCP window specified by the receiver is now completely full     6291456 33554432        [TCP Window Full] Continuation[Packet size limited during capture]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2022-03-22 09:45:09.262310      10.0.1.100      10.0.0.10       8080    TCP window specified by the receiver is now completely full     6291456 33554432        [TCP Window Full] Continuation[Packet size limited during capture]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2022-03-22 09:45:09.268328      10.0.1.100      10.0.0.10       8080    TCP window specified by the receiver is now completely full     6291456 33554432        [TCP Window Full] Continuation[Packet size limited during capture]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;======================================================================================================&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| IO Statistics                                                                                      |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|                                                                                                    |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| Duration: 270.938461 secs                                                                          |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| Interval:   1 secs                                                                                 |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|                                                                                                    |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| Col 1: COUNT(tcp.window_size_value)tcp.window_size_value and ip.addr==10.0.0.10 &amp;amp;&amp;amp; tcp.dstport     |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|        == 8080                                                                                     |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|     2: MIN(tcp.window_size_value)tcp.window_size_value and ip.addr==10.0.0.10 &amp;amp;&amp;amp; tcp.dstport ==    |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|        8080                                                                                        |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|     3: MAX(tcp.window_size_value)tcp.window_size_value and ip.addr==10.0.0.10 &amp;amp;&amp;amp; tcp.dstport ==    |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|        8080                                                                                        |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|     4: AVG(tcp.window_size_value)tcp.window_size_value and ip.addr==10.0.0.10 &amp;amp;&amp;amp; tcp.dstport ==    |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|        8080                                                                                        |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|----------------------------------------------------------------------------------------------------|&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|            |1      |2      |3      |4      |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| Interval   | COUNT |  MIN  |  MAX  |  AVG  |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|--------------------------------------------|                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|   9 &amp;lt;&amp;gt;  10 |   898 |   508 | 65142 |   651 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  10 &amp;lt;&amp;gt;  11 |   849 |   508 |   508 |   508 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  11 &amp;lt;&amp;gt;  12 |     5 |   507 |   508 |   507 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  24 &amp;lt;&amp;gt;  25 |     6 |   508 | 65142 | 11280 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  25 &amp;lt;&amp;gt;  26 |    51 |   507 | 65142 |  3042 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  32 &amp;lt;&amp;gt;  33 |     6 |   486 | 62314 | 10791 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  33 &amp;lt;&amp;gt;  34 |    91 |   486 | 62314 |  1844 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  34 &amp;lt;&amp;gt;  35 |     5 |   485 |   486 |   485 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  38 &amp;lt;&amp;gt;  39 |     6 |   508 | 65142 | 11280 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  47 &amp;lt;&amp;gt;  48 |   121 |   508 | 65142 |  2110 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  48 &amp;lt;&amp;gt;  49 |    80 |   507 |   508 |   507 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  56 &amp;lt;&amp;gt;  57 |     4 |   508 | 65142 | 16667 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  57 &amp;lt;&amp;gt;  58 |    22 |   507 | 65142 |  6383 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  82 &amp;lt;&amp;gt;  83 |     6 |   508 | 65142 | 11280 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  83 &amp;lt;&amp;gt;  84 |    43 |   507 | 65142 |  3514 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  98 &amp;lt;&amp;gt;  99 |     6 |   508 | 65142 | 11280 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;|  99 &amp;lt;&amp;gt; 100 |    42 |   507 | 65142 |  3585 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 100 &amp;lt;&amp;gt; 101 |     6 |   508 | 65142 | 11280 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 102 &amp;lt;&amp;gt; 103 |     7 |   508 | 65142 | 18975 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 103 &amp;lt;&amp;gt; 104 |   164 |   507 |   508 |   507 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 105 &amp;lt;&amp;gt; 106 |    13 |   508 | 65142 | 15424 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 106 &amp;lt;&amp;gt; 107 |    34 |   507 |   508 |   507 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 115 &amp;lt;&amp;gt; 116 |     6 |   508 | 65142 | 11280 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 117 &amp;lt;&amp;gt; 118 |   556 |   508 | 65142 |   740 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 118 &amp;lt;&amp;gt; 119 |     5 |   507 |   508 |   507 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 127 &amp;lt;&amp;gt; 128 |     6 |   508 | 65142 | 11280 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 128 &amp;lt;&amp;gt; 129 |     4 |   508 | 65142 | 16667 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 129 &amp;lt;&amp;gt; 130 |   501 |   508 | 65142 |   637 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 131 &amp;lt;&amp;gt; 132 |     5 |   507 |   508 |   507 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 159 &amp;lt;&amp;gt; 160 |     6 |   508 | 65142 | 11280 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 161 &amp;lt;&amp;gt; 162 |     4 |   508 | 65142 | 16667 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 162 &amp;lt;&amp;gt; 163 |   149 |   507 | 65142 |   941 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 187 &amp;lt;&amp;gt; 188 |     4 |   508 | 65142 | 16667 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 188 &amp;lt;&amp;gt; 189 |     2 |   508 |   508 |   508 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 225 &amp;lt;&amp;gt; 226 |    10 |   508 | 65142 | 13435 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 226 &amp;lt;&amp;gt; 227 |    76 |   507 | 65142 |  1358 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 240 &amp;lt;&amp;gt; 241 |     6 |   508 | 65142 | 11280 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 242 &amp;lt;&amp;gt; 243 |   444 |   508 | 65142 |   799 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 243 &amp;lt;&amp;gt; 244 |     7 |   508 | 65142 | 18975 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 244 &amp;lt;&amp;gt; 245 |   898 |   507 |   508 |   507 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 245 &amp;lt;&amp;gt; 246 |   496 |   508 |   508 |   508 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 246 &amp;lt;&amp;gt; 247 |   516 |   508 |   508 |   508 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 247 &amp;lt;&amp;gt; 248 |   496 |   508 | 65142 |   638 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 248 &amp;lt;&amp;gt; 249 |   482 |   508 | 65142 |   776 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 249 &amp;lt;&amp;gt; 250 |   485 |   507 |   508 |   507 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 250 &amp;lt;&amp;gt; 251 |   602 |   508 |   508 |   508 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 251 &amp;lt;&amp;gt; 252 |   629 |   508 |   508 |   508 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 252 &amp;lt;&amp;gt; 253 |   664 |   508 |   508 |   508 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 253 &amp;lt;&amp;gt; 254 |   519 |   508 |   508 |   508 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 254 &amp;lt;&amp;gt; 255 |   719 |   508 |   508 |   508 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 255 &amp;lt;&amp;gt; 256 |   646 |   508 |   508 |   508 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 256 &amp;lt;&amp;gt; 257 |   764 |   508 |   508 |   508 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 257 &amp;lt;&amp;gt; 258 |   376 |   508 |   508 |   508 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 260 &amp;lt;&amp;gt; 261 |    11 |   507 | 65142 |  6383 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 263 &amp;lt;&amp;gt; 264 |    51 |   508 | 65142 |  4310 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 264 &amp;lt;&amp;gt; 265 |    19 |   507 |   508 |   507 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 267 &amp;lt;&amp;gt; 268 |     3 |   509 | 65142 | 22053 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 268 &amp;lt;&amp;gt; 269 |     7 |   508 | 65142 |  9741 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 269 &amp;lt;&amp;gt; 270 |    80 |   507 | 65142 |  2123 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;| 270 &amp;lt;&amp;gt; Dur |    17 |   507 | 65142 |  8112 |                                                       |&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;======================================================================================================&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;next-steps&quot;&gt;Next steps&lt;&#x2F;h2&gt;
&lt;p&gt;At this point it’s best to raise a bug with the developers. In the mean time, spawning additional application workers to spread the queue around may help ungrease the wheel a bit.&lt;&#x2F;p&gt;
&lt;p&gt;Longterm we should confirm the retransmissions aren’t caused by poor network conditions. The application could be patched to establish a long lived connection while pushing data into object storage. It currently creates a new session per push. Longer connection life-times would ensure the TCP congestion algorithm heuristics have time to stabilise.&lt;&#x2F;p&gt;
&lt;p&gt;Footnotes&lt;&#x2F;p&gt;
&lt;p&gt;1.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;percentile&amp;gt; &amp;lt;request count&amp;gt; &amp;lt;Request Time*&amp;gt; &amp;lt;Connect Time**&amp;gt; &amp;lt;Response Time***&amp;gt; &amp;lt;Data Time****&amp;gt;&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;2.&lt;&#x2F;p&gt;
&lt;p&gt;TCP sequence numbers are generally unhelpful when capturing packets from a server. This is due to segment offloading to the NIC.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>TCP state meanings</title>
        <published>2022-03-18T00:00:00+00:00</published>
        <updated>2022-03-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Thomas Cuthbert
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://realmofchaos.xyz/tech/refs/tcp-stats/"/>
        <id>https://realmofchaos.xyz/tech/refs/tcp-stats/</id>
        
        <content type="html" xml:base="https://realmofchaos.xyz/tech/refs/tcp-stats/">&lt;p&gt;More details can be found here&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blog.karatos.in&#x2F;a?ID=01150-2167abb2-4213-4a7e-a8c2-39ac05a54a5d&quot;&gt;TCP SNMP counters netstat -s each parameter meaning&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.kernel.org&#x2F;doc&#x2F;html&#x2F;latest&#x2F;networking&#x2F;snmp_counter.html&quot;&gt;Linux SNMP counters&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;knowledgebase.paloaltonetworks.com&#x2F;KCSArticleDetail?id=kA10g000000ClWFCA0&quot;&gt;TCP slow and fast path meaning&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;linux&#x2F;snmp.h&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;tcp-basic&quot;&gt;TCP Basic&lt;&#x2F;h2&gt;
&lt;table&gt;
&lt;colgroup&gt;
&lt;col style=&quot;width: 33%&quot; &#x2F;&gt;
&lt;col style=&quot;width: 33%&quot; &#x2F;&gt;
&lt;col style=&quot;width: 33%&quot; &#x2F;&gt;
&lt;&#x2F;colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;category&lt;&#x2F;th&gt;
&lt;th&gt;name&lt;&#x2F;th&gt;
&lt;th&gt;description&lt;&#x2F;th&gt;
&lt;&#x2F;tr&gt;
&lt;&#x2F;thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tcp&lt;&#x2F;td&gt;
&lt;td&gt;ActiveOpens&lt;&#x2F;td&gt;
&lt;td&gt;tcp_connect(), when sending SYN, add 1&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;Tcp&lt;&#x2F;td&gt;
&lt;td&gt;PassiveOpens&lt;&#x2F;td&gt;
&lt;td&gt;tcp_create_openreq_child(), passive three-way handshake is completed, add 1&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;Tcp&lt;&#x2F;td&gt;
&lt;td&gt;AttemptFails&lt;&#x2F;td&gt;
&lt;td&gt;tcp_done(): If you end a connection in the SYN_SENT&#x2F;SYN_RECV state, add 1&lt;br &#x2F;&gt;
&lt;br &#x2F;&gt;
tcp_check_req(): If there is an RST|SYN flag in the input packet in the last stage of the passive three-way handshake, add 1&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;Tcp&lt;&#x2F;td&gt;
&lt;td&gt;CurrEstab&lt;&#x2F;td&gt;
&lt;td&gt;tcp_set_state(), according to ESTABLISHED is the new&#x2F;old state, plus or minus one respectively.&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;Tcp&lt;&#x2F;td&gt;
&lt;td&gt;EstabResets&lt;&#x2F;td&gt;
&lt;td&gt;tcp_set_state(), the new state is TCP_CLOSE, if the old state is ESTABLISHED&#x2F;TCP_CLOSE_WAIT, add 1&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;Tcp&lt;&#x2F;td&gt;
&lt;td&gt;ListenOverflows&lt;&#x2F;td&gt;
&lt;td&gt;tcp_v4_syn_recv_sock(): After the last step of the three-way handshake is completed, add 1 when the Accept queue exceeds the upper limit&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;Tcp&lt;&#x2F;td&gt;
&lt;td&gt;ListenDrops&lt;&#x2F;td&gt;
&lt;td&gt;tcp_v4_syn_recv_sock(): For any reason, including Accept queue exceeding limit, creating new connection, failure to inherit port, etc., add 1&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;Tcp&lt;&#x2F;td&gt;
&lt;td&gt;MaxConn&lt;&#x2F;td&gt;
&lt;td&gt;0&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;Tcp&lt;&#x2F;td&gt;
&lt;td&gt;InSegs&lt;&#x2F;td&gt;
&lt;td&gt;tcp_v4_rcv(), receive a skb, add 1&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;Tcp&lt;&#x2F;td&gt;
&lt;td&gt;InErrs&lt;&#x2F;td&gt;
&lt;td&gt;tcp_rcv_established() -&amp;gt; tcp_validate_incoming(): If there is SYN and seq &amp;gt;= rcv_nxt, add 1&lt;br &#x2F;&gt;
&lt;br &#x2F;&gt;
In the following function, if the checksum is wrong or the packet length is less than the TCP header, add 1: tcp_v4_do_rcv()tcp_rcv_established()tcp_v4_rcv()&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;Tcp&lt;&#x2F;td&gt;
&lt;td&gt;OutSegs&lt;&#x2F;td&gt;
&lt;td&gt;tcp_v4_send_reset(), tcp_v4_send_ack(), add 1tcp_transmit_skb(), tcp_make_synack(), add tcp_skb_pcount(skb) (see TCP_COOKIE_TRANSACTIONS)&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;Tcp&lt;&#x2F;td&gt;
&lt;td&gt;OutRsts&lt;&#x2F;td&gt;
&lt;td&gt;tcp_v4_send_reset(), tcp_send_active_reset() plus 1&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;
&lt;&#x2F;table&gt;
&lt;h2 id=&quot;tcp-congestion-processing&quot;&gt;TCP Congestion Processing&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;category&lt;&#x2F;th&gt;&lt;th&gt;name&lt;&#x2F;th&gt;&lt;th&gt;description&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;TW&lt;&#x2F;td&gt;&lt;td&gt;inet_twdr_do_twkill_work(): The number of sockets with TIME_WAIT timeout (timeout &amp;gt;= 4s). The reason why timewait sockets are treated as timeouts may be because the timeout time distribution of long timeout sockets is relatively scattered, and different search methods are required.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;TWKilled&lt;&#x2F;td&gt;&lt;td&gt;inet_twdr_twcal_tick(): TIME_WAIT timeout socket number. (timeout &amp;lt;4s), only when sysctl_tw_recycle is enabled, and TCP timestamp option is used, this will happen. At this time, 3.5x RTO is used as timewait timeout, and the default timeout is 60s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;TWRecycled&lt;&#x2F;td&gt;&lt;td&gt;tcp_v4_connect() -&amp;gt; __inet_check_established(): During establishment, if the port is reused from the TIME_WAIT socket, add 1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;TCPTimeWaitOverflow&lt;&#x2F;td&gt;&lt;td&gt;tcp_time_wait(): When the system cannot allocate new tcp_timewait_socket, or tw_count (scheduled timewait sockets) exceeds sysctl_max_tw_buckets, add 1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;table&gt;
&lt;colgroup&gt;
&lt;col style=&quot;width: 33%&quot; &#x2F;&gt;
&lt;col style=&quot;width: 33%&quot; &#x2F;&gt;
&lt;col style=&quot;width: 33%&quot; &#x2F;&gt;
&lt;&#x2F;colgroup&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;category&lt;&#x2F;th&gt;
&lt;th&gt;name&lt;&#x2F;th&gt;
&lt;th&gt;description&lt;&#x2F;th&gt;
&lt;&#x2F;tr&gt;
&lt;&#x2F;thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TcpExt&lt;&#x2F;td&gt;
&lt;td&gt;TCPDSACKUndo&lt;&#x2F;td&gt;
&lt;td&gt;tcp_ack() -&amp;gt; tcp_fastretrans_alrt() -&amp;gt; tcp_try_undo_dsack()In the Disorder state, the number of undo completion (undo_retrans == 0).&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;TcpExt&lt;&#x2F;td&gt;
&lt;td&gt;TCPFullUndo&lt;&#x2F;td&gt;
&lt;td&gt;tcp_ack() -&amp;gt; tcp_fastretrans_alrt() -&amp;gt; tcp_try_undo_recovery()In Recovery state, the number of times that all confirmations (snd_una &amp;gt;= high_seq) have been received and undo has been completed (undo_retrans == 0).&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;TcpExt&lt;&#x2F;td&gt;
&lt;td&gt;TCPPartialUndo&lt;&#x2F;td&gt;
&lt;td&gt;tcp_ack() -&amp;gt; tcp_fastretrans_alrt() -&amp;gt; tcp_undo_partial()In Recovery state, the number of times that a partial confirmation (snd_una &amp;lt;high_seq) has been received but the undo has been completed (undo_retrans == 0).&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;TcpExt&lt;&#x2F;td&gt;
&lt;td&gt;TCPLossUndo&lt;&#x2F;td&gt;
&lt;td&gt;tcp_ack() -&amp;gt; tcp_fastretrans_alrt() -&amp;gt; tcp_try_undo_loss()In Loss state, the number of times that all confirmations (snd_una &amp;gt;= high_seq) have been received and undo has been completed (undo_retrans == 0).&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;TcpExt&lt;&#x2F;td&gt;
&lt;td&gt;TCPRenoReorder&lt;&#x2F;td&gt;
&lt;td&gt;Update in tcp_update_reordering(). When metric &amp;gt; tp -&amp;gt; reordering and SACK is not enabled, this counter is incremented by 1.&lt;br &#x2F;&gt;
&lt;br &#x2F;&gt;
In summary, when sacked_out is “unreliable”, tp -&amp;gt; reordering is updated to the “used seg” in the current window. “Number, including unconfirmed (and confirmed?) data, but not lost_out.&lt;br &#x2F;&gt;
&lt;br &#x2F;&gt;
A. tcp_ack() -&amp;gt; tcp_fastretrans_alert() -&amp;gt; tcp_add_reno_sack() -&amp;gt; tcp_check_reno_reordering() -&amp;gt; tcp_update_reordering(): When receiving dupACK in the Open&#x2F;Recovery&#x2F;Disorder&#x2F;CWR state , use the sacked_out + lost_metric&amp;gt; (= packets_out) call tcp_update_reordering()&lt;br &#x2F;&gt;
&lt;br &#x2F;&gt;
B. tcp_ack() -&amp;gt; tcp_clean_rtx_queue() -&amp;gt; tcp_remove_reno_sacks() -&amp;gt; tcp_check_reno_reordering() -&amp;gt; tcp_update_reordering() : When clearing rtx queues, lost_outets_out will be subtracted from lost_packets_out The number of confirmed segs , if sacked_out + lost_out&amp;gt; packets_out, call tcp_update_reordering() with metric( = packets_out + acked_pcount)&lt;br &#x2F;&gt;
&lt;br &#x2F;&gt;
Note:&lt;br &#x2F;&gt;
&lt;br &#x2F;&gt;
sacked_out: the number of dupACK receivedlost_out: Limit the minimum value to 1 and the maximum value to packets_outtp -&amp;gt; reordering: When creating a socket, passively establishing a connection, and entering the Loss state, it is initialized to sysctl_tcp_reordering &lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;TcpExt&lt;&#x2F;td&gt;
&lt;td&gt;TCPSACKReorder&lt;&#x2F;td&gt;
&lt;td&gt;Update in tcp_update_reordering(). When metric &amp;gt; tp -&amp;gt; reordering and SACK is enabled but FACK is disabled, this counter is incremented by 1.&lt;br &#x2F;&gt;
&lt;br &#x2F;&gt;
A. tcp_ack() -&amp;gt; tcp_sacktag_write_queue() -&amp;gt; tcp_update_reordering() will calculate faxes_out in tcp_sacktag_walk() By accumulating state.fack_count), this value is the number of segs from the beginning of snd_una to the highest sequence number of SACK (including those that are not covered by SACK). The conditions for judging the disorder are: (1) D-SACK for retransmission messages is found; (2) The currently received SACK sequence number is smaller than the largest SACK sequence number previously received. state.reord is the smallest fack_count when disorder occurs, that is, disorder occurs at “snd_una + fack_count”. metric = tp -&amp;gt; fackets_out-state.reord, that is, the maximum number of packets that may be out of order.&lt;br &#x2F;&gt;
&lt;br &#x2F;&gt;
B. tcp_ack() -&amp;gt; tcp_clean_rtx_queue() -&amp;gt; tcp_update_reordering() is similar to A. tcp_clean_rtx_queue() calculates the hole in the data (non-retransmitted) that has been SACKed in the rtx queue, and the reord saves the position of the “smallest number” hole ( “Seats” in the retransmission queue). Prior_fackets-reord is the number of TCP segments that may be out of order. If there is no SACK, reorder = prior_fackets = 0 metric = prior_fackets - reord&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;TcpExt&lt;&#x2F;td&gt;
&lt;td&gt;TCPFACKReorder&lt;&#x2F;td&gt;
&lt;td&gt;Similar to TCPSACKReorder, if SACK and FACK are enabled at the same time, this counter is increased.&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;tr&gt;
&lt;td&gt;TcpExt&lt;&#x2F;td&gt;
&lt;td&gt;TCPTSReorder&lt;&#x2F;td&gt;
&lt;td&gt;tcp_ack() -&amp;gt; tcp_fastretrans_alrt() -&amp;gt; tcp_undo_partial() -&amp;gt; tcp_update_reordering() In the Recovery state, the number of times that a partial confirmation (snd_una &amp;lt;high_seq) has been received but the undo has been completed (undo_retrans == 0). The number is equal to TCPPartialUndo.
r&lt;br &#x2F;&gt;
&lt;&#x2F;td&gt;
&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;
&lt;&#x2F;table&gt;
&lt;h2 id=&quot;tcp-loss-retrans&quot;&gt;TCP Loss &amp;amp; Retrans&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;category&lt;&#x2F;th&gt;&lt;th&gt;name&lt;&#x2F;th&gt;&lt;th&gt;description&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Tcp&lt;&#x2F;td&gt;&lt;td&gt;TCPTimeouts&lt;&#x2F;td&gt;&lt;td&gt;In the RTO timer, the number of times from the first timeout in the CWR&#x2F;Open state, the remaining states are not counted in this counter. The number of SYN-ACK timeouts.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Tcp&lt;&#x2F;td&gt;&lt;td&gt;RtoAlgorithm&lt;&#x2F;td&gt;&lt;td&gt;1, tcp_mib_init() initialization&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Tcp&lt;&#x2F;td&gt;&lt;td&gt;RtoMax&lt;&#x2F;td&gt;&lt;td&gt;120000, tcp_mib_init() initialization: TCP_RTO_MAX&lt;em&gt;1000&#x2F;HZ, TCP_RTO_MAX=120&lt;&#x2F;em&gt;HZ&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Tcp&lt;&#x2F;td&gt;&lt;td&gt;RtoMin&lt;&#x2F;td&gt;&lt;td&gt;200, tcp_mib_init() initialization: TCP_RTO_MIN*1000&#x2F;HZ, TCP_RTO_MIN=HZ&#x2F;5&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Tcp&lt;&#x2F;td&gt;&lt;td&gt;RetransSegs&lt;&#x2F;td&gt;&lt;td&gt;The number of retransmissions, including RTO timer and regular retransmissions, that is, tcp_transmit_skb() is called in tcp_retransmit_skb(), and the successful return is +1.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Tcp&lt;&#x2F;td&gt;&lt;td&gt;TCPForwardRetrans&lt;&#x2F;td&gt;&lt;td&gt;(Non-RTO timer) The number of times to send new data, that is, in tcp_fastretrans_alrt()&#x2F;tcp_simple_retransmit()-&amp;gt;tcp_xmit_retransmit_queue(), If it is found that skb-&amp;gt;seq&amp;gt; tp-&amp;gt;retransmit_high (usually snd_una), if the current state is Recovery, SACK is enabled, and the sending conditions allow, then send new data in this function.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Tcp&lt;&#x2F;td&gt;&lt;td&gt;TCPFastRetrans&lt;&#x2F;td&gt;&lt;td&gt;(Non-RTO timer) The number of fast retransmissions, ie tcp_fastretrans_alrt()&#x2F;tcp_simple_retransmit()-&amp;gt;tcp_xmit_retransmit_queue(), if it is not in the LOSS state, add 1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Tcp&lt;&#x2F;td&gt;&lt;td&gt;TCPSlowStartRetrans&lt;&#x2F;td&gt;&lt;td&gt;(Non-RTO timer) retransmission times: ie tcp_fastretrans_alrt()&#x2F;tcp_simple_retransmit()-&amp;gt;tcp_xmit_retransmit_queue(), if it is in the state of LOSS, add 1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Tcp&lt;&#x2F;td&gt;&lt;td&gt;TCPLostRetransmit&lt;&#x2F;td&gt;&lt;td&gt;Resegment packet loss counter inferred from SACK data: in tcp_sacktag_write_queue()-&amp;gt;tcp_mark_lost_retrans(), if tcp_highest_sack_seq(tp) is found to exceed the snd_nxt(TCB-&amp;gt;ack_seq) of a certain skb during retransmission, it is considered that this retransmitted packet If it has been lost, add 1 (not the number of segments). tcp_highest_sack_seq(tp) is the seq of the skb with the highest SEQ number that has been SACKed.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Tcp&lt;&#x2F;td&gt;&lt;td&gt;TCPSpuriousRTOs&lt;&#x2F;td&gt;&lt;td&gt;Resegment packet loss counter inferred from SACK data: in tcp_sacktag_write_queue()-&amp;gt;tcp_mark_lost_retrans(), if tcp_highest_sack_seq(tp) is found to exceed the snd_nxt(TCB-&amp;gt;ack_seq) of a certain skb during retransmission, it is considered that this retransmitted packet If it has been lost, add 1 (not the number of segments). tcp_highest_sack_seq(tp) is the seq of the skb with the highest SEQ number that has been SACKed.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;tcp-others&quot;&gt;TCP Others&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;category&lt;&#x2F;th&gt;&lt;th&gt;name&lt;&#x2F;th&gt;&lt;th&gt;description&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;TCPRenoRecoveryFail&lt;&#x2F;td&gt;&lt;td&gt;“tcp_retransmit_timer(): RTO occurs in the Reovery state, and SACK is not enabled, add 1”&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;TCPRenoFailures&lt;&#x2F;td&gt;&lt;td&gt;“tcp_retransmit_timer(): In the Reorder state, or when sacked_out is not 0, RTO occurs and SACK is not enabled, add 1”&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;TCPRenoRecovery&lt;&#x2F;td&gt;&lt;td&gt;tcp_fastretrans_alrt(): The number of times that TCP without SACK enters the Reovery state&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;ArpFilter&lt;&#x2F;td&gt;&lt;td&gt;“arp_rcv() -&amp;gt; NETFILTER(ARP_IN) -&amp;gt; arp_process()It has nothing to do with TCP. When an ARP packet is received, an output route search (sip, tip) is performed. If the device of the route item found is different from the input device, the counter is increased by 1”&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;EmbryonicRsts&lt;&#x2F;td&gt;&lt;td&gt;tcp_v4_do_rcv() -&amp;gt; tcp_v4_hnd_req() -&amp;gt; tcp_check_req(): The number of RST or SYN received in the SYN_RECV state during the three-handed handshake.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;LockDroppedIcmps&lt;&#x2F;td&gt;&lt;td&gt;“tcp_v4_err(): ICMP error message is received, but the tcp socket is locked by the user”&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpEx&lt;&#x2F;td&gt;&lt;td&gt;OfoPruned&lt;&#x2F;td&gt;&lt;td&gt;“tcp_data_queue() -&amp;gt; tcp_try_rmem_schedule()In the slow path, if the data cannot be copied directly to the user space, it needs to be added to the sk_receive_queue, and the receiver side memory is checked whether it is allowed. If the rcv_buf is insufficient, it may be prune ofo queue. At this time the counter is incremented by 1”&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;OutOfWindowIcmps&lt;&#x2F;td&gt;&lt;td&gt;“tcp_v4_err(): ICMP received, but the number of times the TCP header sequence number in ICMP is not within the receiving window. There are two possible situations: (1) In the LISTEN state, the sequence number does not wait for ISN; (2) In other states, the sequence number Not between SND_UNA .. SND_NXT”&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;PAWSActive&lt;&#x2F;td&gt;&lt;td&gt;“tcp_rcv_synsent_state_process(): After sending SYN, ACK is received, but the number of PAWS check failures.”&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;PAWSEstab&lt;&#x2F;td&gt;&lt;td&gt;“tcp_validate_incoming()tcp_timewait_state_process()tcp_check_req() enters the number of PAWS failures in the package.”&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;PAWSPassive&lt;&#x2F;td&gt;&lt;td&gt;tcp_v4_conn_request(): The number of PAWS check failures for the last ACK of the three-way handshake.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;PruneCalled&lt;&#x2F;td&gt;&lt;td&gt;“tcp_data_queue() -&amp;gt; tcp_try_rmem_schedule()In the slow path, if the data cannot be copied directly to the user space, it needs to be added to the sk_receive_queue, and the receiver side memory is checked whether it is allowed. If the rcv_buf is insufficient, it may be prune ofo queue. At this time the counter is incremented by 1”&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;RcvPruned&lt;&#x2F;td&gt;&lt;td&gt;“tcp_data_queue() -&amp;gt; tcp_try_rmem_schedule()In the slow path, if the data cannot be copied directly to the user space, it needs to be added before sk_receive_queue, and the receiver side memory is checked whether it is allowed. If the rcv_buf is insufficient, the prune receive queue may be prune. If prune fails, this counter is increased by 1.”&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;SyncookiesFailed&lt;&#x2F;td&gt;&lt;td&gt;cookie_v4_check(): SYN cookie check failed times.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;SyncookiesRecv&lt;&#x2F;td&gt;&lt;td&gt;cookie_v4_check(): The number of times of receiving SYN cookie.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;SyncookiesSent&lt;&#x2F;td&gt;&lt;td&gt;cookie_v4_init_sequence(): The number of times the SYN cookie is generated.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;TCPAbortFailed&lt;&#x2F;td&gt;&lt;td&gt;tcp_send_active_reset(): alloc_skb() or tcp_transmit_skb() failed.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;TCPAbortOnClose&lt;&#x2F;td&gt;&lt;td&gt;tcp_close(): The number of times there is still data in sk_receive_queue.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;TCPAbortOnData&lt;&#x2F;td&gt;&lt;td&gt;“tcp_rcv_state_process(): Receive subsequent data in the FIN_WAIT_1&#x2F;FIN_WAIT_2 state (serial number&amp;gt; RCV_NXT); or, if the TCP_LINGER2 setting value is &amp;lt;0, the counter is incremented by 1tcp_close(): There is no unread data, but SO_LINGER is set and linger timeout=0, the counter is incremented by 1, and the TCP is normally disconnected sk_prot-&amp;gt;disconnect()”&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;TCPAbortOnLinger&lt;&#x2F;td&gt;&lt;td&gt;tcp_close(): The number of times that FIN_WAIT_2 immediately switches to CLOSE due to the TCP_LINGER2 setting value &amp;lt;0.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;TCPAbortOnMemory&lt;&#x2F;td&gt;&lt;td&gt;“When executing tcp_close()&#x2F;probe timer&#x2F;keepalive timer, whether the number of orphan sockets and tcp_memory_allocated exceed the maximum number of times.”&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;TCPAbortOnSyn&lt;&#x2F;td&gt;&lt;td&gt;tcp_validate_incoming(): The number of occurrences of SYN and the sequence number is greater than RCV_NXT.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;TCPAbortOnTimeout&lt;&#x2F;td&gt;&lt;td&gt;RTO&#x2F;probe&#x2F;keepalive timer reaches the maximum number of retries or the maximum number of retries&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;tcp-time-wait&quot;&gt;TCP TIME_WAIT&lt;&#x2F;h2&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;category&lt;&#x2F;th&gt;&lt;th&gt;name&lt;&#x2F;th&gt;&lt;th&gt;description&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;TW&lt;&#x2F;td&gt;&lt;td&gt;inet_twdr_do_twkill_work(): The number of sockets with TIME_WAIT timeout (timeout &amp;gt;= 4s). The reason why timewait sockets are treated as timeouts may be because the timeout time distribution of long timeout sockets is relatively scattered, and different search methods are required.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;TWKilled&lt;&#x2F;td&gt;&lt;td&gt;inet_twdr_twcal_tick(): TIME_WAIT timeout socket number. (timeout &amp;lt;4s), only when sysctl_tw_recycle is enabled, and TCP timestamp option is used, this will happen. At this time, 3.5x RTO is used as timewait timeout, and the default timeout is 60s&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;TWRecycled&lt;&#x2F;td&gt;&lt;td&gt;tcp_v4_connect() -&amp;gt; __inet_check_established(): During establishment, if the port is reused from the TIME_WAIT socket, add 1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;TcpExt&lt;&#x2F;td&gt;&lt;td&gt;TCPTimeWaitOverflow&lt;&#x2F;td&gt;&lt;td&gt;tcp_time_wai(): When the system cannot allocate new tcp_timewait_socket, or tw_count (scheduled timewait sockets) exceeds sysctl_max_tw_buckets, add 1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Linux Networking</title>
        <published>2022-03-15T00:00:00+00:00</published>
        <updated>2022-03-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Thomas Cuthbert
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://realmofchaos.xyz/tech/refs/linux-networking/"/>
        <id>https://realmofchaos.xyz/tech/refs/linux-networking/</id>
        
        <content type="html" xml:base="https://realmofchaos.xyz/tech/refs/linux-networking/">&lt;h2 id=&quot;packet-flow&quot;&gt;Packet flow&lt;&#x2F;h2&gt;
&lt;img src=&quot;&#x2F;img&#x2F;netfilter-packet-flow.svg&quot; alt=&quot;Netfilter packet flow&quot; style=&quot;background: #fff; padding: 1rem;&quot; &#x2F;&gt;
&lt;p&gt;Attribution: &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;creativecommons.org&#x2F;licenses&#x2F;by-sa&#x2F;3.0&#x2F;deed.en&quot;&gt;CC BY-SA 3.0&lt;&#x2F;a&gt;,
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;commons.wikimedia.org&#x2F;wiki&#x2F;User_talk:Jengelh&quot;&gt;Jan Engelhardt&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>HTTP References</title>
        <published>2022-03-12T00:00:00+00:00</published>
        <updated>2022-03-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Thomas Cuthbert
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://realmofchaos.xyz/tech/refs/http/"/>
        <id>https://realmofchaos.xyz/tech/refs/http/</id>
        
        <content type="html" xml:base="https://realmofchaos.xyz/tech/refs/http/">&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;developer.mozilla.org&#x2F;en-US&#x2F;docs&#x2F;Web&#x2F;HTTP&quot;&gt;Mozilla HTTP reference guide&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;haproxy&quot;&gt;HAProxy&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;halog -pct headers&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;percentile request_count request_time connect_time response_time data_time&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>WordPress Charm for k8s</title>
        <published>2020-12-02T00:00:00+00:00</published>
        <updated>2020-12-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Thomas Cuthbert
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://realmofchaos.xyz/tech/wordpress-k8s-charm/"/>
        <id>https://realmofchaos.xyz/tech/wordpress-k8s-charm/</id>
        
        <content type="html" xml:base="https://realmofchaos.xyz/tech/wordpress-k8s-charm/">&lt;p&gt;Canonical uses the WordPress blogging system for all our company blogs. Earlier this year I was tasked with updating our WordPress charm from a Services Framework Juju Charm on OpenStack to a Kubernetes based Operator Framework Charm.&lt;&#x2F;p&gt;
&lt;p&gt;The WordPress Operator Charm is simple by design, the goal of the charm is to just provide the various configuration options for our WordPress Kubernetes image, which does all the heavy lifting. See the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;git.launchpad.net&#x2F;charm-k8s-wordpress&#x2F;tree&#x2F;config.yaml&quot;&gt;config.yaml&lt;&#x2F;a&gt; file for details on what is supported, one option that can be useful during testing is &lt;code&gt;container_config&lt;&#x2F;code&gt;, which gives you the ability to pass through custom Kubernetes spec environment variables. For example, to enable debug level logging and ensuring you always have the latest image, you would set:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;microk8s.juju config wordpress container_config=&amp;#39;WORDPRESS_DEBUG: &amp;quot;1&amp;quot; imagePullPolicy: &amp;quot;always&amp;quot;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The image build process downloads the latest WordPress codebase and installs it behind an Apache web server, it then downloads the plugins all of our blogs depend on, such as, akismet anti-spam support, SSO with the openid teams plugin, and a variety of Canonical Open Source themes. By default the charm will use the current stable build here, however if you wish to customise the image you can fork the code and update the &lt;code&gt;image&lt;&#x2F;code&gt; charm config option to point to the location of your custom image.&lt;&#x2F;p&gt;
&lt;p&gt;To get started with the Operator Framework WordPress charm you will need a MySQL database running locally. As I write this post there is no Kubernetes MySQL charm, so deploy one to an IaaS model with &lt;code&gt;juju deploy cs:mysql&lt;&#x2F;code&gt;. Initialise the database as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;CREATE DATABASE wordpress CHARACTER SET utf8 COLLATE utf8_unicode_ci;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;CREATE USER &amp;#39;wordpress&amp;#39;@&amp;#39;%&amp;#39; IDENTIFIED BY &amp;#39;wordpress&amp;#39;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;GRANT ALL PRIVILEGES ON wordpress.* TO &amp;#39;wordpress&amp;#39;@&amp;#39;%&amp;#39;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;FLUSH PRIVILEGES;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Once the database is prepared we are now able to deploy the WordPress charm. The easiest way to get started with a local Kubernetes cluster is to have MicroK8s installed, reference the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;git.launchpad.net&#x2F;charm-k8s-wordpress&#x2F;tree&#x2F;README.md&quot;&gt;README&lt;&#x2F;a&gt; of the charm for details on how to get one setup. Deploy the charm as follows.&lt;&#x2F;p&gt;
&lt;p&gt;Deploy the charm into your Kubernetes Juju model.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;microk8s.juju deploy cs:~wordpress-charmers&#x2F;wordpress&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The charm requires Kubernetes TLS secrets to be pre-configured to ensure logins are kept secure. Create a self-signed certificate and upload it as a Kubernetes secret.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;openssl req -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout server.key -out server.crt&lt;&#x2F;code&gt; &lt;code&gt;microk8s.kubectl create secret tls -n wordpress tls-wordpress --cert=server.crt --key=server.key&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Tell the charm where the database is and provide some initial setup.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;DB_HOST=$IP_OF_YOUR_MYSQL_DATABASE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;microk8s.juju config wordpress db_host=$DB_HOST db_user=wordpress db_password=wordpress tls_secret_name=tls-wordpress \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            initial_settings=&amp;quot;user_name: admin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            admin_email: devnull@example.com&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            weblog_title: Test Blog&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            blog_public: False&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;From there you can test the site by updating your &lt;code&gt;&#x2F;etc&#x2F;hosts&lt;&#x2F;code&gt; file and creating a static entry for the IP address of the Kubernetes ingress gateway.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    App        Version                  Status   Scale  Charm      Store  Rev  OS          Address  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    Messagewordpress  wordpress:bionic-stable  waiting      1  wordpress  local    0  kubernetes  10.152.183.140 &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;echo &#x27;10.152.183.140 myblog.example.com&#x27; | sudo tee -a &#x2F;etc&#x2F;hosts&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It will take about 5 to 10 minutes for Juju hooks to discover the site is live and perform the initial setup for you. Look for this line in the output of &lt;code&gt;juju debug-log&lt;&#x2F;code&gt; to confirm.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;unit.wordpress&#x2F;0.juju-log Wordpress configured and initialised&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is due to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;canonical&#x2F;operator&#x2F;issues&#x2F;166&quot;&gt;issue #166&lt;&#x2F;a&gt; and will be fixed once Juju supports a Kubernetes pod ready hook.&lt;&#x2F;p&gt;
&lt;p&gt;To retrieve the random admin password, run the following.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;microk8s kubectl exec -ti -n wordpress wordpress-operator-0 -- cat &#x2F;root&#x2F;initial.passwd&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You should now be able to browse to &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;myblog.example.com&#x2F;wp-admin&quot;&gt;https:&#x2F;&#x2F;myblog.example.com&#x2F;wp-admin&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We’ve been using this charm in production for five months now, but recently updated it to bring it up to date with a current version of the Operator Framework. We’d be interested in any feedback on the charm itself, either here or via bugs against the &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;bugs.launchpad.net&#x2F;charm-k8s-wordpress&quot;&gt;charm project on Launchpad&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Managing Multi Cloud Services With Juju</title>
        <published>2018-10-24T00:00:00+00:00</published>
        <updated>2018-10-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Thomas Cuthbert
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://realmofchaos.xyz/tech/managing-multi-cloud-services-with-juju/"/>
        <id>https://realmofchaos.xyz/tech/managing-multi-cloud-services-with-juju/</id>
        
        <content type="html" xml:base="https://realmofchaos.xyz/tech/managing-multi-cloud-services-with-juju/">&lt;p&gt;Managing a service with deployments in multi-cloud environments can be a challenge in terms of troubleshooting and scalability due to the complexity of dealing with different public cloud providers. An effective way to manage services deployed cross-cloud is to use tools that allow you to define your service once and deploy anywhere: in the cloud, on bare metal, or locally inside containers. In this blog post I am going to describe how the Canonical SRE team has achieved this, the tools that we use and the way we apply them to manage the Ubuntu Archive Mirror service.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;historical-archive-mirror-setup&quot;&gt;Historical Archive Mirror Setup&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;Archive-Mirror-Diagram-2.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It’s no secret that Ubuntu is a popular OS for running applications in the cloud. It was clear from the beginning that the increased adoption of Ubuntu in the cloud would cause a significant amount of stress on the master Ubuntu Archive Mirror service due to an increased rate of requests from Ubuntu instances running in public clouds. This was not a new problem for us, the Ubuntu Archive Mirror Network was originally conceived to protect the master Ubuntu Archives from getting over saturated with requests. The network architecture is a globally distributed system of web servers and caches that are operated by the community. The goal of this network is to improve response times for community users by directing traffic destined for the master Ubuntu Archive repositories to repositories geographically closer to the request’s origin. Without this distributed cache the millions of apt requests we receive every day would cause a denial of service to the master repository servers. Ubuntu updates would then be significantly degraded, which is unacceptable for any system running production grade services.&lt;&#x2F;p&gt;
&lt;p&gt;The nice thing about the Ubuntu Archive Mirror architecture is how extensible it is. Within each cloud region we have a deployment of the Ubuntu Archive Mirror service. Each regional deployment keeps in sync with the master repositories. When an Ubuntu instance is started in the cloud its apt sources are configured to point to the deployment servicing the region of which the instance is currently running. We apply this pattern to every public and private cloud we manage. This includes AWS, GCE, Azure and OpenStack.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;identifying-the-challenges&quot;&gt;Identifying the Challenges&lt;&#x2F;h1&gt;
&lt;p&gt;After understanding our architectural requirements, the next step was to figure out how to manage each individual Ubuntu Archive deployment. A non exhaustive list of challenges we needed to address were:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;How do we manage the lifecycle of each Ubuntu Archive Mirror service?&lt;&#x2F;li&gt;
&lt;li&gt;Can we be sure that each environment is consistent and that the user experience remains the same no matter which Archive Mirror environment you are working on?&lt;&#x2F;li&gt;
&lt;li&gt;How can we test proposed changes before upgrading production services?&lt;&#x2F;li&gt;
&lt;li&gt;How do we respond to incidents when things go wrong with any of our environments and how do we ensure each environment is isolated from each other to avoid unnecessary outages?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Our engineers can’t get bogged down with the semantics of each cloud. The best approach is to have a uniform interface that applies to any platform. This saves engineering time by making our playbooks more succinct and easier to digest, there is less room for error when there are minimal commands to run, a consistent UX reduces mean time to recovery as an engineer can be confident that the same troubleshooting methodology can be applied no matter which environment they are in, finally, environment specifications stored in version control allow us to keep track of changes, and easily test and rollback revisions that do not work.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;the-solution&quot;&gt;The Solution&lt;&#x2F;h1&gt;
&lt;p&gt;Our Ubuntu Archive mirror services are modeled with Mojo which orchestrates deployments with Juju. “Automate once, deploy anywhere” is an approach we have taken in developing our environment automation solution. We define what our environments look like once and have the tooling take care of the boring details. Juju&lt;&#x2F;p&gt;
&lt;p&gt;Juju is the component which drives each deployment. It is responsible for talking to the cloud APIs, installation and configuration of each application, provisioning cloud services, such as security, networking, storage, and user access control. Juju enables us to deploy and scale services quickly and efficiently to a variety of providers: public clouds, physical servers, OpenStack, and local containers. Juju is responsible for provisioning instances and installing the application (a charm in Juju context) onto them. It is also responsible for managing services, such as ensuring ACLs are configured, configuring advanced networking, and allocating storage.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;deployment-control&quot;&gt;Deployment Control&lt;&#x2F;h1&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;img&#x2F;mojo-brand.png&quot; alt=&quot;&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;All our Archive Mirror deployments are centrally managed. We have a deployment host from which all SREs connect to environments we manage. An internally developed tool allows SREs to search for the environment they need to connect to (such as “Azure Archive Mirror for Japan East region”), and then configures for them everything they need to connect to that environment in a consistent way.&lt;&#x2F;p&gt;
&lt;p&gt;The Ubuntu Archive Mirror service itself is modeled as a Mojo specification. Mojo is a system of configuration and tools for verifying the success of Juju environment deployments. It allows us to define what an Archive Mirror is in a revision-controlled configuration repository, and a means of validating whether what we deployed is as we intended.&lt;&#x2F;p&gt;
&lt;p&gt;To deploy a new environment we use Mojo to run a manifest file which tells it which operations (phases) to perform and in what order. The manifest file looks similar to this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;collect&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;deploy config=services&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;deploy config=relations&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;script config=post-deploy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;sleep config=10&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nagios-check skip-checks-extra=&amp;quot;check_ksplice,check_total_procs&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;juju-check-wait&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;verify config=verify-deploy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Mojo recognises different phases as different actions to perform. The three main phases to be concerned about are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;collection
&lt;ul&gt;
&lt;li&gt;Mojo will download the charms (service modules) required as per the file specified in the collect call.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;deployment
&lt;ul&gt;
&lt;li&gt;The deploy phase is fairly self explanatory, it takes the artefacts from the collection phase and deploys them into the Juju model.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;verification
&lt;ul&gt;
&lt;li&gt;A script can be called once the deploy phase is complete. The script is configured to run some verification commands to make sure the deployment is in the desired state.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;We define a collect file that contains an inventory of each component, known as a charm. This file looks like the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;ubuntu-repository-cache lp:ubuntu-repository-cache;overwrite=True&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;haproxy                 cs:haproxy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nrpe                    cs:nrpe&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The actual service and relation specifications detail how each charm is related and any configuration options, i.e. Squid cache size and HAProxy monitor settings. For a look at the specification please see the appendix at the end of the post. Mojo uses codetree to pull down the charms, from either the charmstore or version control (e.g. launchpad.net or github.com), to the host and copies them to a charm repository for deployment. A phased approach protects us from incorrectly configured specifications as Mojo will not proceed if a phase fails. At the end of this process we have a new validated environment deployed and ready for use.&lt;&#x2F;p&gt;
&lt;p&gt;You can try this out for yourself, download the example mojo spec.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Before we begin you will need to have Juju, Mojo and a Juju controller bootstrapped. You can find a tutorial on how to set this up here.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Configure a Mojo project and workspace which we will use to build and test our archive mirror environment locally before it gets deployed into our cloud.&lt;&#x2F;p&gt;
&lt;p&gt;export MOJO_STAGE=production export MOJO_WORKSPACE=archive-mirror export MOJO_PROJECT=mojo-archive-mirror-proj export MOJO_SERIES=xenial export MOJO_SPEC=&lt;del&gt;&#x2F;mojo&#x2F;mojo-archive-mirror-spec&#x2F; export MOJO_LOCAL=&lt;&#x2F;del&gt;&#x2F;mojo&#x2F;LOCAL&#x2F;mojo-archive-mirror-spec&#x2F;&lt;&#x2F;p&gt;
&lt;p&gt;juju bootstrap&lt;&#x2F;p&gt;
&lt;p&gt;mkdir -p ${MOJO_SPEC}; mkdir -p ${MOJO_LOCAL}; (cd ~&#x2F;mojo; curl &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;admin.insights.ubuntu.com&#x2F;wp-content&#x2F;uploads&#x2F;db69&#x2F;mojo-archive-mirror-spec.tar.gz&quot;&gt;https:&#x2F;&#x2F;admin.insights.ubuntu.com&#x2F;wp-content&#x2F;uploads&#x2F;db69&#x2F;mojo-archive-mirror-spec.tar.gz&lt;&#x2F;a&gt; | tar xv)&lt;&#x2F;p&gt;
&lt;p&gt;mojo project-new -s $MOJO_SERIES -c lxd mojo workspace-new –project $MOJO_PROJECT -s $MOJO_SERIES $MOJO_SPEC $MOJO_WORKSPACE mojo run&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Mojo has now orchestrated a deployment of our Archive Mirror environment. Below details the instances that were created and the applications installed onto them.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$ juju status&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We know our new Archive Mirror is functioning because the verify phase in our manifest has curl’d the HAProxy unit and downloaded the list of supported Ubuntu series.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2018-07-16 06:53:34 [INFO] Running script verify-deploy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2018-07-16 06:53:35 [INFO] &#x2F;ubuntu&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;artful-backports&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;artful-proposed&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;artful-security&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;artful-updates&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;artful&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bionic-backports&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bionic-proposed&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bionic-security&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bionic-updates&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;bionic&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[...]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;2018-07-16 06:53:35 [INFO] Completed script verify-deploy in 0s (0.31s)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We keep track of each Archive Mirror deployment that we manage with stages embedded in the root of the Mojo spec directory. These stages are nothing more than sub-directories that Mojo looks out for. Under each stage is the information used by each Mojo phase.&lt;&#x2F;p&gt;
&lt;p&gt;The directory layout looks a little something like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mojo-archive-mirror-spec # repository root.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── manifest # the manifest script, this is what mojo run is looking for.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;└── production&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── collect # Contains the list of charms that the collect phase will download.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── haproxy-services.yaml&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── relations # Specifies the contracts between each service.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;└── services # Details how each service should be configured.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Mojo uses this approach when sourcing local significant configuration. This comes in handy when you want to do something like configure a service with dummy credentials for the CI deployment. If we wanted to add a new stage, like ci to the list of deployments we manage, we only need to create a new directory and populate the required files:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mojo-archive-mirror-spec&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── manifest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;└── production&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── collect&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[...]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;└── ci&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;├── collect&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Any changes made to the Archive Mirror specification are tested. Our testing environment is a mixture of technologies: Jenkins, Openstack, Mojo and Juju. The testing procedure is broken down as follows:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Jenkins job pulls the latest Mojo specification from version control.&lt;&#x2F;li&gt;
&lt;li&gt;A new juju model is created for the revision of the specification. The model is deployed into one of our private OpenStack clouds.&lt;&#x2F;li&gt;
&lt;li&gt;The Jenkins script then executes a Mojo run which deploys the Archive Mirror service to the new Juju model.&lt;&#x2F;li&gt;
&lt;li&gt;Jenkins monitors the progress and provides feedback on any errors.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This process gives us assurance that the changes we have made are deployable albeit only within an Openstack context.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;closing-comments&quot;&gt;Closing Comments&lt;&#x2F;h1&gt;
&lt;p&gt;So far our current solution has worked well. The time taken for an SRE to redeploy an Archive Mirror environment is under an hour. If an environment is sick and we start receiving alerts we can be confident that if all else fails, and troubleshooting is taking too long, we can destroy the environment and redeploy a fresh baseline. The process is as simple as failing over DNS, recreating the Juju model, running Mojo, and configuring DNS and monitoring.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
