<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Jérôme Pin</title>
    <link rel="self" type="application/atom+xml" href="https://jeromepin.fr/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://jeromepin.fr"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2024-07-19T00:00:00+00:00</updated>
    <id>https://jeromepin.fr/atom.xml</id>
    
    <entry xml:lang="en">
        <title>Terraform at LumApps: Part 4 - Chasing performance</title>
        <published>2026-04-03T11:14:00+02:00</published>
        <updated>2026-04-03T11:14:00+02:00</updated>
        <author>
          <name>Jérôme Pin</name>
        </author>
        <link rel="alternate" type="text/html" href="https://medium.com/lumapps-engineering/terraform-at-lumapps-part-4-8da59590ea0d"/>
        <id>https://medium.com/lumapps-engineering/terraform-at-lumapps-part-4-8da59590ea0d</id>
        
        <content type="html" xml:base="https://medium.com/lumapps-engineering/terraform-at-lumapps-part-4-8da59590ea0d">
          
          <p>I authored or co-authored this post : <a href="https://medium.com/lumapps-engineering/terraform-at-lumapps-part-4-8da59590ea0d">https:&#x2F;&#x2F;medium.com&#x2F;lumapps-engineering&#x2F;terraform-at-lumapps-part-4-8da59590ea0d</a></p>.
          
        </content>
        
    </entry>
    <entry xml:lang="en">
        <title>Moments d&#x27;inertie d&#x27;une raquette de tennis</title>
        <published>2024-07-19T00:00:00+00:00</published>
        <updated>2024-07-19T00:00:00+00:00</updated>
        <author>
          <name>Jérôme Pin</name>
        </author>
        <link rel="alternate" type="text/html" href="https://jeromepin.fr/articles/moment-inertie-raquette/"/>
        <id>https://jeromepin.fr/articles/moment-inertie-raquette/</id>
        
        <content type="html" xml:base="https://jeromepin.fr/articles/moment-inertie-raquette/">
          
          &lt;p&gt;Le &lt;em&gt;moment d&#x27;inertie&lt;&#x2F;em&gt; (exprimé en &lt;script type=&quot;math&#x2F;tex&quot;&gt;kg.m^{2}&lt;&#x2F;script&gt;
) est une mesure de la résistance d&#x27;un objet à changer sa vitesse de rotation autour d&#x27;un axe (au même titre que l&#x27;&lt;em&gt;inertie&lt;&#x2F;em&gt; est la résistance d&#x27;un objet à changer sa vitesse de translation).
Il varie avec la masse et la distance de la-dite masse par rapport à l&#x27;axe de rotation.&lt;&#x2F;p&gt;
&lt;figure&gt;
    &lt;img src=&quot;https:&amp;#x2F;&amp;#x2F;www.ncbi.nlm.nih.gov&amp;#x2F;pmc&amp;#x2F;articles&amp;#x2F;instance&amp;#x2F;3827573&amp;#x2F;bin&amp;#x2F;jssm-05-304-g001.jpg&quot; &#x2F;&gt;
    &lt;figcaption&gt;
        Axes de rotations d&amp;#x27;une raquette de tennis
    &lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Une raquette de tennis possède 3 moments d&#x27;inertie principaux (passant par le centre de masse) :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;transversal&lt;&#x2F;em&gt;: la raquette tourne autour de l&#x27;aze &lt;em&gt;x&lt;&#x2F;em&gt; (Fig. 1).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;lateral&lt;&#x2F;em&gt;: la raquette tourne autour de l&#x27;axe &lt;em&gt;y&lt;&#x2F;em&gt; (Fig. 1) de façon similaire à un coup droit (le réel moment d&#x27;inertie pour ce genre de coup est toutefois mesuré là où la main se place sur le manche plutôt qu&#x27;au centre de masse pour être plus représentatif de l&#x27;effort à fournir dans la réalité).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;polaire&lt;&#x2F;em&gt;: la raquette tourne autour de l&#x27;axe &lt;em&gt;z&lt;&#x2F;em&gt; (Fig. 1), comme par exemple lorsqu&#x27;une balle est frappée décentrée.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Le &lt;em&gt;moment de rotation polaire&lt;&#x2F;em&gt; est généralement appelé &lt;em&gt;twistweight&lt;&#x2F;em&gt;. C&#x27;est lui qui est impliqué lorsqu&#x27;une balle est frappée de façon décentrée par rapport à l&#x27;axe de rotation &lt;em&gt;z&lt;&#x2F;em&gt;. L&#x27;augmenter permet donc de rendre une raquette moins sensible au décentrage, en placant des masses à 3h et 9h.&lt;&#x2F;p&gt;
&lt;p&gt;Le &lt;em&gt;moment de rotation lateral&lt;&#x2F;em&gt; est généralement appelé &lt;em&gt;swingweight&lt;&#x2F;em&gt;. Il est impliqué dès lors que la raquette entre en mouvement. L&#x27;augmenter (en ajoutant une masse à 12h par exemple) va permettre d&#x27;augmenter la puissance de frappe.&lt;&#x2F;p&gt;
&lt;p&gt;Plus on ajoute de la masse à distance de l&#x27;axe de rotation, plus le moment d&#x27;inertie augmente, plus il va être difficile de faire tourner la raquette autour de ce même axe.&lt;&#x2F;p&gt;

          
        </content>
        
    </entry>
    <entry xml:lang="en">
        <title>Terraform at LumApps: Part 3 - Handling our Terraform breaking changes at scale</title>
        <published>2024-06-10T16:32:00+02:00</published>
        <updated>2024-06-10T16:32:00+02:00</updated>
        <author>
          <name>Jérôme Pin</name>
        </author>
        <link rel="alternate" type="text/html" href="https://medium.com/lumapps-engineering/terraform-at-lumapps-part-3-daa3c869f0f4"/>
        <id>https://medium.com/lumapps-engineering/terraform-at-lumapps-part-3-daa3c869f0f4</id>
        
        <content type="html" xml:base="https://medium.com/lumapps-engineering/terraform-at-lumapps-part-3-daa3c869f0f4">
          
          <p>I authored or co-authored this post : <a href="https://medium.com/lumapps-engineering/terraform-at-lumapps-part-3-daa3c869f0f4">https:&#x2F;&#x2F;medium.com&#x2F;lumapps-engineering&#x2F;terraform-at-lumapps-part-3-daa3c869f0f4</a></p>.
          
        </content>
        
    </entry>
    <entry xml:lang="en">
        <title>Terraform at LumApps: Part 2 - Managing terragrunt.hcl files at scale</title>
        <published>2023-12-18T00:00:00+01:00</published>
        <updated>2023-12-18T00:00:00+01:00</updated>
        <author>
          <name>Jérôme Pin</name>
        </author>
        <link rel="alternate" type="text/html" href="https://medium.com/lumapps-engineering/terraform-at-lumapps-part-2-27494897def4"/>
        <id>https://medium.com/lumapps-engineering/terraform-at-lumapps-part-2-27494897def4</id>
        
        <content type="html" xml:base="https://medium.com/lumapps-engineering/terraform-at-lumapps-part-2-27494897def4">
          
          <p>I authored or co-authored this post : <a href="https://medium.com/lumapps-engineering/terraform-at-lumapps-part-2-27494897def4">https:&#x2F;&#x2F;medium.com&#x2F;lumapps-engineering&#x2F;terraform-at-lumapps-part-2-27494897def4</a></p>.
          
        </content>
        
    </entry>
    <entry xml:lang="en">
        <title>Terraform at LumApps: Part 1 - A huge Terraform monorepo</title>
        <published>2022-05-23T00:00:00+01:00</published>
        <updated>2022-05-23T00:00:00+01:00</updated>
        <author>
          <name>Jérôme Pin</name>
        </author>
        <link rel="alternate" type="text/html" href="https://medium.com/lumapps-engineering/terraform-at-lumapps-part-1-f37660b4ed95"/>
        <id>https://medium.com/lumapps-engineering/terraform-at-lumapps-part-1-f37660b4ed95</id>
        
        <content type="html" xml:base="https://medium.com/lumapps-engineering/terraform-at-lumapps-part-1-f37660b4ed95">
          
          <p>I authored or co-authored this post : <a href="https://medium.com/lumapps-engineering/terraform-at-lumapps-part-1-f37660b4ed95">https:&#x2F;&#x2F;medium.com&#x2F;lumapps-engineering&#x2F;terraform-at-lumapps-part-1-f37660b4ed95</a></p>.
          
        </content>
        
    </entry>
    <entry xml:lang="en">
        <title>Drop ALT led configuration using bitmask</title>
        <published>2020-08-23T12:23:13+02:00</published>
        <updated>2020-08-23T12:23:13+02:00</updated>
        <author>
          <name>Jérôme Pin</name>
        </author>
        <link rel="alternate" type="text/html" href="https://jeromepin.fr/articles/drop-alt-led-configuration/"/>
        <id>https://jeromepin.fr/articles/drop-alt-led-configuration/</id>
        
        <content type="html" xml:base="https://jeromepin.fr/articles/drop-alt-led-configuration/">
          
          &lt;p&gt;I recently purchased an &lt;a href=&quot;https:&#x2F;&#x2F;drop.com&#x2F;buy&#x2F;drop-alt-high-profile-mechanical-keyboard&quot;&gt;ALT mechanical keyboard&lt;&#x2F;a&gt; from Drop (formerly Massdrop).&lt;&#x2F;p&gt;
&lt;p&gt;After going through the mandatory modding (changing &lt;em&gt;Halo Trues&lt;&#x2F;em&gt; for &lt;em&gt;Aliaz&lt;&#x2F;em&gt; switches, changing stabilizers, lubbing what needed to be lubed, etc...), I started compiling and flashing my own custom &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;qmk&#x2F;qmk_firmware&quot;&gt;QMK firmware&lt;&#x2F;a&gt;. It worked pretty great, but I was stuck at backlight configuration. I could not understand or guess how to configure it.&lt;&#x2F;p&gt;
&lt;p&gt;I ended up &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;qmk&#x2F;qmk_firmware&#x2F;blob&#x2F;master&#x2F;keyboards&#x2F;massdrop&#x2F;alt&#x2F;config_led.h#L52-L169&quot;&gt;reading code&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;qmk&#x2F;qmk_firmware&#x2F;blob&#x2F;master&#x2F;keyboards&#x2F;massdrop&#x2F;alt&#x2F;keymaps&#x2F;default_md&#x2F;keymap.c#L183-L221&quot;&gt;examples&lt;&#x2F;a&gt; provided by QMK. The keyboard is built upon a 105 LED matrix.&lt;&#x2F;p&gt;
&lt;p&gt;A particular example caught my attention : &lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;c&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-c &quot;&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;font-style:italic;color:#abb0b6;&quot;&gt;&#x2F;&#x2F;Specific LEDs use specified RGB values while all others are off
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;flags &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; LED_FLAG_MATCH_ID &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; LED_FLAG_USE_RGB&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; \
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;id0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;0xFF&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; \
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;id1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;0x00FF&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; \
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;id2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;0x0000FF00&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; \
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;id3 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;0xFF000000&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; \
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;r &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;75&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; \
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;g &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;150&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; \
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;b &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;225&lt;&#x2F;span&gt;&lt;span&gt; \
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And it struck me ! Bitmask ! The only thing that can select -- at the same time -- both a single address and multiple ones is a &lt;em&gt;bitmask&lt;&#x2F;em&gt; !&lt;&#x2F;p&gt;
&lt;p&gt;By converting hexadecimal values to decimal, we get familiar-looking numbers. They belong to the &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;1_%2B_2_%2B_4_%2B_8_%2B_%E2%8B%AF&quot;&gt;&lt;em&gt;successive power of two&lt;&#x2F;em&gt;&lt;&#x2F;a&gt; serie :&lt;&#x2F;p&gt;
&lt;p&gt;$$
\mathrm{0xFF} = 255 = 1 + 2 + 4 + 8 + 16 + 32 + 64 + 128 = \displaystyle\sum_{i=0}^{7} 2^{i}
$$&lt;&#x2F;p&gt;
&lt;p&gt;$$
\mathrm{0x0000FF00} = 65280 = 1 + 2 + \ldots = \displaystyle\sum_{i=8}^{15} 2^{i}
$$&lt;&#x2F;p&gt;
&lt;p&gt;$$
\mathrm{0xFF000000} = 4278190080 = 16 777 216 + 33 554 432 + \ldots = \displaystyle\sum_{i=24}^{31} 2^{i}
$$&lt;&#x2F;p&gt;
&lt;p&gt;The keyboard is separated in 4 groups of 32 LEDs (except the last one of 9 LEDs) :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.id0&lt;&#x2F;code&gt;: from &lt;code&gt;Esc&lt;&#x2F;code&gt; to &lt;code&gt;a&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;.id1&lt;&#x2F;code&gt;: from &lt;code&gt;s&lt;&#x2F;code&gt; to &lt;code&gt;fn&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;.id2&lt;&#x2F;code&gt;: from &lt;code&gt;Left Arrow&lt;&#x2F;code&gt; to &lt;em&gt;Underglow LED above &lt;code&gt;5&lt;&#x2F;code&gt;&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;.id3&lt;&#x2F;code&gt;: from &lt;em&gt;Underglow LED above &lt;code&gt;4&lt;&#x2F;code&gt;&lt;&#x2F;em&gt; to the end (&lt;em&gt;Underglow LED left of &lt;code&gt;Ctrl&lt;&#x2F;code&gt;&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Each LED is assigned a number from &lt;code&gt;0&lt;&#x2F;code&gt; to &lt;code&gt;31&lt;&#x2F;code&gt; based on its position in the group.&lt;&#x2F;p&gt;
&lt;p&gt;Let say we want to display a green color on the first four letters of every row (&lt;code&gt;Q(16)&lt;&#x2F;code&gt;, &lt;code&gt;W(17)&lt;&#x2F;code&gt;, &lt;code&gt;E(18)&lt;&#x2F;code&gt;, &lt;code&gt;R(19)&lt;&#x2F;code&gt;, &lt;code&gt;A(31)&lt;&#x2F;code&gt;, &lt;code&gt;S(0)&lt;&#x2F;code&gt;, &lt;code&gt;D(1)&lt;&#x2F;code&gt;, &lt;code&gt;F(2)&lt;&#x2F;code&gt;, &lt;code&gt;Z(13)&lt;&#x2F;code&gt;, &lt;code&gt;X(14)&lt;&#x2F;code&gt;, &lt;code&gt;C(15)&lt;&#x2F;code&gt;, &lt;code&gt;V(16)&lt;&#x2F;code&gt;). We just need to add every value as a power of two : &lt;&#x2F;p&gt;
&lt;p&gt;$$ .id0 = 2^{16} + 2^{17} + 2^{18} + 2^{19} + 2^{31} = 2 148 466 688 $$
$$ .id1 = 2^0 + 2^1 + 2^2 + 2^{13} + 2^{14} + 2^{15} + 2^{16} = 122 887 $$&lt;&#x2F;p&gt;
&lt;p&gt;And we get :&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;c&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-c &quot;&gt;&lt;code class=&quot;language-c&quot; data-lang=&quot;c&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;flags &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; LED_FLAG_MATCH_ID &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|&lt;&#x2F;span&gt;&lt;span&gt; LED_FLAG_USE_RGB&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; \
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;id0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;2148466688&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; \
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;id1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;122887&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; \
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;id2 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; \
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;id3 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; \
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;r &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; \
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;g &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;255&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; \
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;b &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,&lt;&#x2F;span&gt;&lt;span&gt; \
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;While being a smart way to target both one and multiple LEDs, it&#x27;s not very easy to understand and even less to change.&lt;&#x2F;p&gt;
&lt;p&gt;Fortunately, someone very nice created a bitmask generator &lt;a href=&quot;http:&#x2F;&#x2F;daedalusrising.com&#x2F;maskdrop&#x2F;&quot;&gt;online&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;

          
        </content>
        
    </entry>
    <entry xml:lang="en">
        <title>Graphes : Le danger des séries empilées</title>
        <published>2020-05-03T11:33:00+01:00</published>
        <updated>2020-05-03T11:33:00+01:00</updated>
        <author>
          <name>Jérôme Pin</name>
        </author>
        <link rel="alternate" type="text/html" href="https://jeromepin.fr/articles/graphes-le-danger-des-series-empilees/"/>
        <id>https://jeromepin.fr/articles/graphes-le-danger-des-series-empilees/</id>
        
        <content type="html" xml:base="https://jeromepin.fr/articles/graphes-le-danger-des-series-empilees/">
          
          &lt;p&gt;Le graphe suivant montre un nombre de requêtes en fonction du temps sur 4 serveurs. Les séries sont empilées afin de pouvoir facilement lire la somme de ces requêtes sur l&#x27;ensemble de l&#x27;infrastructure.&lt;&#x2F;p&gt;
&lt;figure&gt;
    &lt;img src=&quot;&amp;#x2F;images&amp;#x2F;graphes-le-danger-des-series-empilees&amp;#x2F;mischievous_node_first.svg&quot; &#x2F;&gt;
    &lt;figcaption&gt;
        Exemple typiques de séries empilées : nombre de requêtes en fonction du temps sur 4 serveurs
    &lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Il est très facile d&#x27;extraire quelques informations : &lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;3 des 4 serveurs reçoivent chacun une dizaine de requêtes par seconde;&lt;&#x2F;li&gt;
&lt;li&gt;L&#x27;un des serveurs reçoit plus de requêtes que les autres;&lt;&#x2F;li&gt;
&lt;li&gt;L&#x27;ensemble de l&#x27;infrastructure encaisse une soixantaine de requêtes par seconde;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;pourquoi-les-series-empilees-sont-dangereuses&quot;&gt;Pourquoi les séries empilées sont dangereuses ?&lt;&#x2F;h2&gt;
&lt;p&gt;Il semble aussi évident que l&#x27;infrastructure a vu une chute massive des requêtes sur chacun des noeuds.&lt;&#x2F;p&gt;
&lt;p&gt;En réordonnant les séries en plaçant le serveur le plus chargé en haut, une différence intéréssante se dessine :&lt;&#x2F;p&gt;
&lt;figure&gt;
    &lt;img src=&quot;&amp;#x2F;images&amp;#x2F;graphes-le-danger-des-series-empilees&amp;#x2F;mischievous_node_last.svg&quot; &#x2F;&gt;
    &lt;figcaption&gt;
        Le même exemple avec les séries ordonnées différement
    &lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Toute l&#x27;infrastructure n&#x27;est pas affectée par la diminution brutale du nombre de requêtes mais seulement un des serveurs !&lt;&#x2F;p&gt;
&lt;figure&gt;
    &lt;img src=&quot;https:&amp;#x2F;&amp;#x2F;media.giphy.com&amp;#x2F;media&amp;#x2F;3o7btW7VDxqrhJEnqE&amp;#x2F;giphy.gif&quot; &#x2F;&gt;
    &lt;figcaption&gt;
        Denis Brogniart est stupéfait de cette découverte
    &lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;&lt;h3 id=&quot;est-ce-un-probleme-avec-les-donnees-avec-le-graphe&quot;&gt;Est-ce un problème avec les données ? Avec le graphe ?&lt;&#x2F;h3&gt;
&lt;p&gt;Les séries inférieures influencent la forme des séries supérieures. L&#x27;ordre des séries change donc la perception que l&#x27;on a d&#x27;un graphe et, par conséquent, les conclusions qu&#x27;on en tire ! &lt;&#x2F;p&gt;
&lt;p&gt;Le fait de pouvoir facilement lire une somme pousse à ne plus prendre en compte les différences entre les séries mais seulement lire la série la plus haute et ainsi voir, de façon erronée, une baisse sur toute l&#x27;infrastructure.&lt;&#x2F;p&gt;
&lt;p&gt;Ce ne sont ni les données ni leur représentation qui sont erronées, mais bien la lecture que nous en avons. Sans être vigilant, il est facile de penser que la baisse du nombre de requêtes affecte tout l&#x27;infrastructure.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;comment-s-en-premunir&quot;&gt;Comment s&#x27;en prémunir ?&lt;&#x2F;h2&gt;
&lt;p&gt;Il est très facile de se prémunir d&#x27;une telle erreur d&#x27;interprétation : ne pas empiler les séries. Pour pouvoir quand même lire un total, il suffit d&#x27;ajouter une série représentant leur somme :&lt;&#x2F;p&gt;
&lt;figure&gt;
    &lt;img src=&quot;&amp;#x2F;images&amp;#x2F;graphes-le-danger-des-series-empilees&amp;#x2F;unstacked.svg&quot; &#x2F;&gt;
    &lt;figcaption&gt;
        Le même exemple sans empiler les séries et avec une somme des séries (noir)
    &lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Avec cette représentation, il apparait de façon très évidente que les variations d&#x27;une série ont bien un effet sur le total (puisqu&#x27;il s&#x27;agit de la somme des points des séries) mais pas sur les autres séries.&lt;&#x2F;p&gt;

          
        </content>
        
    </entry>
    <entry xml:lang="en">
        <title>Timeseries : Cardinalité et explosion</title>
        <published>2020-01-04T21:12:00+01:00</published>
        <updated>2020-01-04T21:12:00+01:00</updated>
        <author>
          <name>Jérôme Pin</name>
        </author>
        <link rel="alternate" type="text/html" href="https://jeromepin.fr/articles/timeseries-cardinalite-et-explosion/"/>
        <id>https://jeromepin.fr/articles/timeseries-cardinalite-et-explosion/</id>
        
        <content type="html" xml:base="https://jeromepin.fr/articles/timeseries-cardinalite-et-explosion/">
          
          &lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;fr.wikipedia.org&#x2F;wiki&#x2F;Cardinalit%C3%A9_(math%C3%A9matiques)&quot;&gt;Wikipédia&lt;&#x2F;a&gt; indique :&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;En mathématiques, la cardinalité est une notion de taille pour les ensembles. Lorsqu&#x27;un ensemble est fini, c&#x27;est-à-dire si ses éléments peuvent être listés par une suite finie, son cardinal est la longueur de cette suite, autrement dit il s&#x27;agit du nombre d&#x27;éléments de l&#x27;ensemble.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;C&#x27;est donc le nombre de valeurs uniques d&#x27;un ensemble.&lt;&#x2F;p&gt;
&lt;p&gt;Dans le cas de Prometheus, la cardinalité d&#x27;une métrique $M$ est le produit de la cardinalité de ses $n$ labels $L_{n}$ tel que :&lt;&#x2F;p&gt;
&lt;p&gt;$$ Card(M) = \prod_{n=0}^{X}Card(L_n) $$&lt;&#x2F;p&gt;
&lt;p&gt;Ainsi, il est facile d&#x27;imaginer une métrique &lt;code&gt;http_request_duration_seconds&lt;&#x2F;code&gt; ayant les caractéristiques suivantes :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Un label &lt;code&gt;verb&lt;&#x2F;code&gt; qui représente les méthodes HTTP et qui a pour valeurs possibles : &lt;code&gt;GET&lt;&#x2F;code&gt;, &lt;code&gt;POST&lt;&#x2F;code&gt;, &lt;code&gt;PUT&lt;&#x2F;code&gt; et &lt;code&gt;DELETE&lt;&#x2F;code&gt; ($Card = 4$);&lt;&#x2F;li&gt;
&lt;li&gt;Un label &lt;code&gt;le&lt;&#x2F;code&gt; qui est le bucket dans lequel la mesure tombe. Il a pour valeurs possibles : 0.1, 0.2, 0.5, 1, &lt;code&gt;+Inf&lt;&#x2F;code&gt; ($Card = 5$);&lt;&#x2F;li&gt;
&lt;li&gt;Un label &lt;code&gt;browser&lt;&#x2F;code&gt; qui indique le navigateur utilisé par le client : Chrome, Firefox, IE, Edge, Safari, Opera, Others ($Card = 7$);&lt;&#x2F;li&gt;
&lt;li&gt;Un label &lt;code&gt;device&lt;&#x2F;code&gt; qui représente la famille de périphérique utilisé par le client : Desktop, Mobile, Tablet ($Card = 3$);&lt;&#x2F;li&gt;
&lt;li&gt;En enfin, un label &lt;code&gt;os&lt;&#x2F;code&gt; qui indique la &amp;quot;marque&amp;quot; de l&#x27;OS utilisé par le client : Linux, Microsoft, Apple ($Card = 3$);&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Si la métrique n&#x27;avait qu&#x27;un seul label, voire deux, la cardinalité serait faible. Le problème survient lorsque un label est ajouté ou lorsque la cardinalité d&#x27;un label augmente subitement. La métrique fini innévitablement par arriver à une &lt;a href=&quot;https:&#x2F;&#x2F;fr.wikipedia.org&#x2F;wiki&#x2F;Explosion_combinatoire&quot;&gt;explosion combinatoire&lt;&#x2F;a&gt; : un petit changement du nombre de données rend la cardinalité de notre métrique irraisonable.&lt;&#x2F;p&gt;
&lt;p&gt;Au début, tout commence de manière raisonnable : il n&#x27;y a que 2 verbes et 5 buckets. Puis on se dit qu&#x27;il faudrait séparer par OS. Puis par famille de client. Puis par navigateur. Puis par... Et la cardinalité est passée de $2 \cdot 5 = 10$ à $4 \cdot 5 \cdot 7 \cdot 3 \cdot 3 = 1260$ !&lt;&#x2F;p&gt;
&lt;p&gt;Le plus surprenant c&#x27;est que l&#x27;augmentation de la cardinalité des labels augmente considérablement la cardinalité de la métrique ! Admettons que chaque cardinalité augmente de 1 (ce qui est peu), la cardinalité de la métrique passe de $1260$ à $5 \cdot 6 \cdot 8 \cdot 4 \cdot 4 = 3840$, soit plus du triple de la valeur initiale !&lt;&#x2F;p&gt;
&lt;p&gt;Que va-t&#x27;il se passer si l&#x27;on décide d&#x27;ajouter un label &lt;code&gt;customer&lt;&#x2F;code&gt; qui a pour valeur un UUID ? D&#x27;après &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Universally_unique_identifier#Version_4_(random)&quot;&gt;Wikipédia&lt;&#x2F;a&gt;, un UUID dans sa version 4 a 122 bits générés aléatoirement à 0 ou 1, soit $2^{122}$ possiblités !&lt;&#x2F;p&gt;
&lt;figure&gt;
    &lt;img src=&quot;https:&amp;#x2F;&amp;#x2F;media.giphy.com&amp;#x2F;media&amp;#x2F;O3GqAYR9jFxLi&amp;#x2F;source.gif&quot; &#x2F;&gt;
    &lt;figcaption&gt;
        Boooooom
    &lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Il semble évident que demander une granularité aussi fine à un tel système est impossible. Les timeseries sont conçues pour traiter et afficher des données en temps réel. Malheureusement, le temps réel est quelque chose de très coûteux, il faut donc faire quelques compromis. Limiter la précision (et donc la cardinalité) est un bon moyen d&#x27;équilibrer le cout. Il faudrait alors se tourner vers un second système dédié à de la précision, tel que l&#x27;analyse de logs, pour compléter les mesures.&lt;&#x2F;p&gt;
&lt;p&gt;Les timeseries servent à donner une vue d&#x27;ensemble d&#x27;un système (que ce soit au niveau d&#x27;un serveur, d&#x27;une application, d&#x27;un cluster, d&#x27;un datacenter...) mais ne peuvent pas servir à débugger et à trouver l&#x27;origine d&#x27;un problème. Une fois qu&#x27;un problème est détecté, c&#x27;est vers les logs qu&#x27;il faut se tourner.&lt;&#x2F;p&gt;

          
        </content>
        
    </entry>
    <entry xml:lang="en">
        <title>Esctl: managing elasticsearch from the command line</title>
        <published>2019-09-22T22:08:00+01:00</published>
        <updated>2019-09-22T22:08:00+01:00</updated>
        <author>
          <name>Jérôme Pin</name>
        </author>
        <link rel="alternate" type="text/html" href="https://jeromepin.fr/articles/esctl-managing-elasticsearch-from-command-line/"/>
        <id>https://jeromepin.fr/articles/esctl-managing-elasticsearch-from-command-line/</id>
        
        <content type="html" xml:base="https://jeromepin.fr/articles/esctl-managing-elasticsearch-from-command-line/">
          
          &lt;p&gt;During my month of unemployment, I spent time thinking on how I had tackled technical problems in my last year-and-half of work. The best part of my day-to-day mission was to ensure our Elasticsearch clusters were healthy, secured and efficient. To that end, I was using a combination of tools:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;raw &lt;code&gt;curl&lt;&#x2F;code&gt; commands,&lt;&#x2F;li&gt;
&lt;li&gt;bash scripts I wrote,&lt;&#x2F;li&gt;
&lt;li&gt;graphical interfaces,&lt;&#x2F;li&gt;
&lt;li&gt;Prometheus monitoring and alerting,&lt;&#x2F;li&gt;
&lt;li&gt;Some automation,&lt;&#x2F;li&gt;
&lt;li&gt;commands embedded in SaltStack&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It&#x27;s easy to see there is no common way to manage those clusters, and I was relying on a bunch of disparate stuff.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-problem&quot;&gt;The problem&lt;&#x2F;h2&gt;
&lt;p&gt;The issue does not come from Elasticsearch itself but is inherent to any software that exposes an HTTP API to manage itself: curl-of-the-death.&lt;&#x2F;p&gt;
&lt;p&gt;Here are some commands I used to run on a regular basis (examples come from &lt;a href=&quot;https:&#x2F;&#x2F;www.elastic.co&#x2F;guide&#x2F;en&#x2F;elasticsearch&#x2F;reference&#x2F;current&#x2F;index.html&quot;&gt;Elasticsearch&#x27;s documentation&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;h4 id=&quot;list-indices&quot;&gt;List indices&lt;&#x2F;h4&gt;
&lt;pre data-linenos data-lang=&quot;bash&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; curl&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt; -X&lt;&#x2F;span&gt;&lt;span&gt; GET &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;localhost:9200&#x2F;_cat&#x2F;indices&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;yellow&lt;&#x2F;span&gt;&lt;span&gt; open foo VrIiXmIRRA6BNP5JWaXKqA 1 1 0 0 283b 283b
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;change-the-number-of-replicas-of-a-given-index&quot;&gt;Change the number of replicas of a given index&lt;&#x2F;h4&gt;
&lt;pre data-linenos data-lang=&quot;bash&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; curl&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt; -X&lt;&#x2F;span&gt;&lt;span&gt; PUT &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;localhost:9200&#x2F;twitter&#x2F;_settings?pretty&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt; -H &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;#39;Content-Type: application&#x2F;json&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt; -d&lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;{
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;    &amp;quot;index&amp;quot; : {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;        &amp;quot;number_of_replicas&amp;quot; : 2
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;    }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;reset-a-index-s-refresh-interval-to-its-default-value&quot;&gt;Reset a index&#x27;s refresh interval to its default value&lt;&#x2F;h4&gt;
&lt;pre data-linenos data-lang=&quot;bash&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; curl&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt; -X&lt;&#x2F;span&gt;&lt;span&gt; PUT &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;localhost:9200&#x2F;twitter&#x2F;_settings?pretty&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt; -H &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;#39;Content-Type: application&#x2F;json&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt; -d&lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;{
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;    &amp;quot;index&amp;quot; : {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;        &amp;quot;refresh_interval&amp;quot; : null
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;    }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;pretty-print-cluster-stats&quot;&gt;Pretty-print cluster stats&lt;&#x2F;h4&gt;
&lt;pre data-linenos data-lang=&quot;bash&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; curl&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt; -X&lt;&#x2F;span&gt;&lt;span&gt; GET &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;localhost:9200&#x2F;_cluster&#x2F;stats&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;_nodes&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;total&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: 1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;successful&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: 1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;failed&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: 0
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    },
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;nodes&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;count&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;total&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: 1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;data&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: 1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;coordinating_only&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: 0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;master&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: 1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;15&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;ingest&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: 1
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;16&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;17&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;versions&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;18&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;7.2.1&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;19&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        ]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;20&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;jvm&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;21&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;max_uptime_in_millis&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: 1565394&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;22&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;versions&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: [
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;23&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;                {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;24&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;                    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;version&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;12.0.1&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;25&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;                    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;vm_name&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;OpenJDK 64-Bit Server VM&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;26&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;                    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;vm_version&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;12.0.1+12&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;27&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;                    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;vm_vendor&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;Oracle Corporation&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;28&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;                    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;bundled_jdk&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: true&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;29&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;                    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;using_bundled_jdk&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: true&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;30&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;                    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;count&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: 1
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;31&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;                }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;32&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;            ]&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;33&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;mem&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;34&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;heap_used_in_bytes&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: 128029720&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;35&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;heap_max_in_bytes&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: 1056309248
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;36&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;37&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;threads&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;: 31
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;38&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;39&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        ...
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;40&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;41&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;reroute-shard-0-of-index-test-from-node1-to-node2&quot;&gt;Reroute shard 0 of index &#x27;test&#x27; from node1 to node2&lt;&#x2F;h4&gt;
&lt;pre data-linenos data-lang=&quot;bash&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; curl&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt; -X&lt;&#x2F;span&gt;&lt;span&gt; POST &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;localhost:9200&#x2F;_cluster&#x2F;reroute?pretty&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt; -H &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;#39;Content-Type: application&#x2F;json&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt; -d&lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;{
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;    &amp;quot;commands&amp;quot; : [
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;        {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;            &amp;quot;move&amp;quot; : {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;                &amp;quot;index&amp;quot; : &amp;quot;test&amp;quot;, &amp;quot;shard&amp;quot; : 0,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;                &amp;quot;from_node&amp;quot; : &amp;quot;node1&amp;quot;, &amp;quot;to_node&amp;quot; : &amp;quot;node2&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;            }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;        }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;    ]
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;change-cluster-s-transient-setting-indices-recovery-max-bytes-per-sec-to-20mb&quot;&gt;Change cluster&#x27;s transient setting &#x27;indices.recovery.max_bytes_per_sec&#x27; to 20mb&lt;&#x2F;h4&gt;
&lt;pre data-linenos data-lang=&quot;bash&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; curl&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt; -X&lt;&#x2F;span&gt;&lt;span&gt; PUT &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;localhost:9200&#x2F;_cluster&#x2F;settings?flat_settings=true&amp;amp;pretty&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt; -H &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;#39;Content-Type: application&#x2F;json&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt; -d&lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;{
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;    &amp;quot;transient&amp;quot; : {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;        &amp;quot;indices.recovery.max_bytes_per_sec&amp;quot; : &amp;quot;20mb&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;    }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;#39;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Commands are short, but if I need to pass URL parameters, content type, HTTP verb and a full JSON body, they are no longer short...&lt;&#x2F;p&gt;
&lt;p&gt;Of course, I could use some bash alias to hide the &lt;code&gt;-H &#x27;Content-Type: application&#x2F;json&#x27;&lt;&#x2F;code&gt;, or maybe use the excellent &lt;a href=&quot;https:&#x2F;&#x2F;httpie.org&#x2F;&quot;&gt;HTTPie&lt;&#x2F;a&gt; but the biggest pain comes from the JSON body!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;requirements&quot;&gt;Requirements&lt;&#x2F;h2&gt;
&lt;p&gt;I needed a tool which could abstract all those long curl commands and could be flexible enough. After looking on the Internet, it appeared the few tools already written didn&#x27;t support commands I needed. Thus, I decided to write my own, and I came with a list of requirements:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Requirement&lt;&#x2F;th&gt;&lt;th&gt;Solution&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Easy and fast to write&lt;&#x2F;td&gt;&lt;td&gt;Python : high-level, easy to read and write, I know it well&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Fast to use&lt;&#x2F;td&gt;&lt;td&gt;Command-line&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Abstract&#x2F;hide params&lt;&#x2F;td&gt;&lt;td&gt;Command-line params and integrated help ! I don&#x27;t want to remember what verb to use, what URL params to give, what to put in the JSON body, etc...&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Don&#x27;t spend time on building CLI&lt;&#x2F;td&gt;&lt;td&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;openstack&#x2F;cliff&quot;&gt;Openstack&#x27;s Cliff&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Easy to switch cluster, without remembering long server name&lt;&#x2F;td&gt;&lt;td&gt;Config file&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Each cluster may have different setup (ssl, auth, etc...)&lt;&#x2F;td&gt;&lt;td&gt;Config file&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Nice and pretty output&lt;&#x2F;td&gt;&lt;td&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;openstack&#x2F;cliff&quot;&gt;Cliff&lt;&#x2F;a&gt; comes with &lt;a href=&quot;https:&#x2F;&#x2F;pypi.org&#x2F;project&#x2F;PrettyTable&#x2F;&quot;&gt;PrettyTable&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Inspiration&lt;&#x2F;td&gt;&lt;td&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;openstack&#x2F;python-openstackclient&quot;&gt;Openstack&#x27;s CLI&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;kubernetes.io&#x2F;docs&#x2F;reference&#x2F;kubectl&#x2F;overview&#x2F;&quot;&gt;kubectl&lt;&#x2F;a&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;h2 id=&quot;the-solution&quot;&gt;The solution&lt;&#x2F;h2&gt;
&lt;p&gt;I ended up writing &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jeromepin&#x2F;esctl&quot;&gt;esctl&lt;&#x2F;a&gt;. It checks all my requirements and it&#x27;s very easy to add new features by inheriting a class based on the output type.&lt;&#x2F;p&gt;
&lt;figure&gt;
    &lt;img src=&quot;&amp;#x2F;images&amp;#x2F;esctl-CLI-design-tree.svg&quot; &#x2F;&gt;
    &lt;figcaption&gt;
        Esctl subcommands taxonomy
    &lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;It relies on a config file (inspired by &lt;code&gt;kubectl&lt;&#x2F;code&gt;) to declare settings (global and cluster-wide), clusters, users and contexts (an association of a user and a cluster) :&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;yaml&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-yaml &quot;&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;settings&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;no_check_certificate&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;true
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;max_retries&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;timeout&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;20
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;clusters&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;localhost&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;servers&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;http:&#x2F;&#x2F;localhost:9200
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;foo01-prd-sfo&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;servers&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;https:&#x2F;&#x2F;master01-foo01-prd-sfo1.example.com
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;https:&#x2F;&#x2F;master02-foo01-prd-sfo2.example.com
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;15&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;https:&#x2F;&#x2F;master03-foo01-prd-sfo3.example.com
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;16&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;settings&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;17&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;timeout&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;60
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;18&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;19&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;users&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;20&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;jerome&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;21&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;username&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;jerome
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;22&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;password&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;P@ssw0rD
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;23&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;24&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;contexts&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;25&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;localhost&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;26&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;cluster&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;localhost
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;27&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;28&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;production&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;29&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;user&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;jerome
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;30&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;cluster&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;foo01-prd-sfo
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;31&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;32&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;default-context&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;localhost
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Esctl provides a lot of commands and subcommands to manage Elasticsearch:&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#fafafa;color:#61676c;&quot;&gt;&lt;code&gt;&lt;span&gt;usage: esctl [--version] [-v | -q] [--log-file LOG_FILE] [-h] [--debug] [--context CONTEXT]
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;esctl
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;optional arguments:
&lt;&#x2F;span&gt;&lt;span&gt;  --version            show program&amp;#39;s version number and exit
&lt;&#x2F;span&gt;&lt;span&gt;  -v, --verbose        Increase verbosity of output. Can be repeated.
&lt;&#x2F;span&gt;&lt;span&gt;  -q, --quiet          Suppress output except warnings and errors.
&lt;&#x2F;span&gt;&lt;span&gt;  --log-file LOG_FILE  Specify a file to log output. Disabled by default.
&lt;&#x2F;span&gt;&lt;span&gt;  -h, --help           Show help message and exit.
&lt;&#x2F;span&gt;&lt;span&gt;  --debug              Show tracebacks on errors.
&lt;&#x2F;span&gt;&lt;span&gt;  --context CONTEXT    Context to use
&lt;&#x2F;span&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;span&gt;Commands:
&lt;&#x2F;span&gt;&lt;span&gt;  cat allocation                     Show shard allocation.
&lt;&#x2F;span&gt;&lt;span&gt;  cluster allocation explain         Provide explanations for shard allocations in the cluster.
&lt;&#x2F;span&gt;&lt;span&gt;  cluster health                     Retrieve the cluster health.
&lt;&#x2F;span&gt;&lt;span&gt;  cluster routing allocation enable  Change the routing allocation status.
&lt;&#x2F;span&gt;&lt;span&gt;  cluster stats                      Retrieve the cluster status.
&lt;&#x2F;span&gt;&lt;span&gt;  complete                           print bash completion command (cliff)
&lt;&#x2F;span&gt;&lt;span&gt;  config context list                List all contexts.
&lt;&#x2F;span&gt;&lt;span&gt;  help                               print detailed help for another command (cliff)
&lt;&#x2F;span&gt;&lt;span&gt;  index close                        Close an index.
&lt;&#x2F;span&gt;&lt;span&gt;  index create                       Create an index.
&lt;&#x2F;span&gt;&lt;span&gt;  index delete                       Delete an index.
&lt;&#x2F;span&gt;&lt;span&gt;  index list                         List all indices.
&lt;&#x2F;span&gt;&lt;span&gt;  index open                         Open an index.
&lt;&#x2F;span&gt;&lt;span&gt;  logging get                        Get a logger value.
&lt;&#x2F;span&gt;&lt;span&gt;  logging reset                      Reset a logger value.
&lt;&#x2F;span&gt;&lt;span&gt;  logging set                        Set a logger value.
&lt;&#x2F;span&gt;&lt;span&gt;  node hot-threads                   Print hot threads on each nodes.
&lt;&#x2F;span&gt;&lt;span&gt;  node list                          List nodes.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It allows to dramatically shorten previously shown commands :&lt;&#x2F;p&gt;
&lt;h4 id=&quot;list-indices-1&quot;&gt;List indices&lt;&#x2F;h4&gt;
&lt;pre data-linenos data-lang=&quot;bash&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; esctl index list
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;+-------+--------+--------+------------------------+---------+---------+------------+--------------+------------+--------------------+
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;Index &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;Health &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;Status &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;UUID                   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;Primary &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;Replica &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;Docs&lt;&#x2F;span&gt;&lt;span&gt; Count &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;Docs&lt;&#x2F;span&gt;&lt;span&gt; Deleted &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;Store&lt;&#x2F;span&gt;&lt;span&gt; Size &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;Primary&lt;&#x2F;span&gt;&lt;span&gt; Store Size &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;+-------+--------+--------+------------------------+---------+---------+------------+--------------+------------+--------------------+
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;foo   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;yellow &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;open   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;VrIiXmIRRA6BNP5JWaXKqA &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;1       &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;1       &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;0          &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;0            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;283b       &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;283b               &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;+-------+--------+--------+------------------------+---------+---------+------------+--------------+------------+--------------------+
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;change-the-number-of-replicas-of-a-given-index-1&quot;&gt;Change the number of replicas of a given index&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;em&gt;Not implemented yet. Would look like :&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;bash&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; esctl index settings set number_of_replicas 2&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt; --index&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;twitter
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;reset-a-index-s-refresh-interval-to-its-default-value-1&quot;&gt;Reset a index&#x27;s refresh interval to its default value&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;em&gt;Not implemented yet. Would look like :&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;bash&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; esctl index settings reset refresh_interval&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt; --index&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;twitter
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;pretty-print-cluster-stats-1&quot;&gt;Pretty-print cluster stats&lt;&#x2F;h4&gt;
&lt;pre data-linenos data-lang=&quot;bash&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; esctl cluster stats
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;+------------------------------------------------+------------------------------+
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;Attribute                                      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;Value &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;+------------------------------------------------+------------------------------+
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;_nodes.failed                                  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;_nodes.successful                              &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;_nodes.total                                   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;nodes.count.coordinating_only                  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;0 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;nodes.count.data                               &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;nodes.count.ingest                             &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;nodes.count.master                             &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;nodes.count.total                              &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;nodes.discovery_types.single-node              &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;15&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;nodes.fs.available_in_bytes                    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;48388599808 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;16&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;nodes.fs.free_in_bytes                         &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;51605315584 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;17&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;nodes.fs.total_in_bytes                        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;62725623808 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;18&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;nodes.jvm.max_uptime_in_millis                 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;1565394 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;19&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;nodes.jvm.mem.heap_max_in_bytes                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;1056309248 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;20&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;nodes.jvm.mem.heap_used_in_bytes               &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;128029720 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;21&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;nodes.jvm.threads                              &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                           &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;31 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;22&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;nodes.jvm.versions[0].bundled_jdk              &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                         &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;True &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;23&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;nodes.jvm.versions[0].count                    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                            &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;24&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;nodes.jvm.versions[0].using_bundled_jdk        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                         &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;True &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;25&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;nodes.jvm.versions[0].version                  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                       &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;12.0.1 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;26&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;nodes.jvm.versions[0].vm_name                  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|     &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;OpenJDK&lt;&#x2F;span&gt;&lt;span&gt; 64-Bit Server VM &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;27&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;nodes.jvm.versions[0].vm_vendor                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|           &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;Oracle&lt;&#x2F;span&gt;&lt;span&gt; Corporation &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;28&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;nodes.jvm.versions[0].vm_version               &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;12.0.1+12 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;29&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;...
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;30&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;status                                         &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                       &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;yellow &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;31&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;timestamp                                      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|                &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;1565893455640 &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;32&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;+------------------------------------------------+------------------------------+
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h4 id=&quot;reroute-shard-0-of-index-test-from-node1-to-node2-1&quot;&gt;Reroute shard 0 of index &#x27;test&#x27; from node1 to node2&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;em&gt;Not implemented yet&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;change-cluster-s-transient-setting-indices-recovery-max-bytes-per-sec-to-20mb-1&quot;&gt;Change cluster&#x27;s transient setting &#x27;indices.recovery.max_bytes_per_sec&#x27; to 20mb&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;em&gt;Not implemented yet. Would look like :&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;bash&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; esctl cluster settings set&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt; --transient&lt;&#x2F;span&gt;&lt;span&gt; indices.recovery.max_bytes_per_sec 20mb
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;what-a-subcommand-look-likes&quot;&gt;What a subcommand look likes&lt;&#x2F;h2&gt;
&lt;p&gt;I created 3 output class based on Cliff&#x27;s ones:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;EsctlCommand&lt;&#x2F;code&gt; : Doesn&#x27;t expect any output&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;EsctlLister&lt;&#x2F;code&gt; : Expect a list of elements in order to create a multi-columns table&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;EsctlShowOne&lt;&#x2F;code&gt; : Expect a key-value list to create a two-columns table&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;To add a new subcommand, I only need to choose the output class (and inherit my class from it) and write the &lt;code&gt;take_action&lt;&#x2F;code&gt; method:&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;python&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#fa6e32;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;take_action&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;parsed_args&lt;&#x2F;span&gt;&lt;span&gt;):
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#abb0b6;&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Generate or retrieve data to be displayed.
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;font-style:italic;color:#abb0b6;&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;font-style:italic;color:#abb0b6;&quot;&gt;    Arguments:
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;font-style:italic;color:#abb0b6;&quot;&gt;        parsed_args {argparse.Namespace} -- Arguments from the command line.
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;font-style:italic;color:#abb0b6;&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;font-style:italic;color:#abb0b6;&quot;&gt;    Returns:
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;font-style:italic;color:#abb0b6;&quot;&gt;        Any -- The data to be displayed, as specified by Cliff
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;font-style:italic;color:#abb0b6;&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa6e32;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;data
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Here is, as a sample, the class associated to the &lt;code&gt;esctl cluster health&lt;&#x2F;code&gt; command:&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;python&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-python &quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#fa6e32;&quot;&gt;class &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;ClusterHealth&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;text-decoration:underline;color:#399ee6;&quot;&gt;EsctlShowOne&lt;&#x2F;span&gt;&lt;span&gt;):
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#abb0b6;&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Retrieve the cluster health.&amp;quot;&amp;quot;&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa6e32;&quot;&gt;def &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;take_action&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;parsed_args&lt;&#x2F;span&gt;&lt;span&gt;):
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#abb0b6;&quot;&gt;# Retrieve the cluster health using the appropriate elasticsearch-py function. Then order the output and sort it
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        health &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#55b4d4;&quot;&gt;self&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;_sort_and_order_dict&lt;&#x2F;span&gt;&lt;span&gt;(Esctl&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;_es&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;cluster&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;health&lt;&#x2F;span&gt;&lt;span&gt;())
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#abb0b6;&quot;&gt;# Add coloration of the &amp;quot;status&amp;quot; (RED, YELLOW, GREEN) key based on it&amp;#39;s value
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        health[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;status&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;] &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;Color&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;colorize&lt;&#x2F;span&gt;&lt;span&gt;(
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;            health&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;status&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f07171;&quot;&gt;getattr&lt;&#x2F;span&gt;&lt;span&gt;(Color&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span&gt;health&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;get&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;status&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;upper&lt;&#x2F;span&gt;&lt;span&gt;())
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        )
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#abb0b6;&quot;&gt;# Return a tuple of tuple. It will lead to a two-column table : &amp;quot;Attribute&amp;quot; and &amp;quot;Value&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;        &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa6e32;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#55b4d4;&quot;&gt;tuple&lt;&#x2F;span&gt;&lt;span&gt;(health&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;keys&lt;&#x2F;span&gt;&lt;span&gt;())&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;font-style:italic;color:#55b4d4;&quot;&gt;tuple&lt;&#x2F;span&gt;&lt;span&gt;(health&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;values&lt;&#x2F;span&gt;&lt;span&gt;()))
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Which will display :&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#fafafa;color:#61676c;&quot;&gt;&lt;code&gt;&lt;span&gt;+----------------------------------+----------------+
&lt;&#x2F;span&gt;&lt;span&gt;| Field                            | Value          |
&lt;&#x2F;span&gt;&lt;span&gt;+----------------------------------+----------------+
&lt;&#x2F;span&gt;&lt;span&gt;| active_primary_shards            | 0              |
&lt;&#x2F;span&gt;&lt;span&gt;| active_shards                    | 0              |
&lt;&#x2F;span&gt;&lt;span&gt;| active_shards_percent_as_number  | 100.0          |
&lt;&#x2F;span&gt;&lt;span&gt;| cluster_name                     | docker-cluster |
&lt;&#x2F;span&gt;&lt;span&gt;| delayed_unassigned_shards        | 0              |
&lt;&#x2F;span&gt;&lt;span&gt;| initializing_shards              | 0              |
&lt;&#x2F;span&gt;&lt;span&gt;| number_of_data_nodes             | 1              |
&lt;&#x2F;span&gt;&lt;span&gt;| number_of_in_flight_fetch        | 0              |
&lt;&#x2F;span&gt;&lt;span&gt;| number_of_nodes                  | 1              |
&lt;&#x2F;span&gt;&lt;span&gt;| number_of_pending_tasks          | 0              |
&lt;&#x2F;span&gt;&lt;span&gt;| relocating_shards                | 0              |
&lt;&#x2F;span&gt;&lt;span&gt;| status                           | green          |
&lt;&#x2F;span&gt;&lt;span&gt;| task_max_waiting_in_queue_millis | 0              |
&lt;&#x2F;span&gt;&lt;span&gt;| timed_out                        | False          |
&lt;&#x2F;span&gt;&lt;span&gt;| unassigned_shards                | 0              |
&lt;&#x2F;span&gt;&lt;span&gt;+----------------------------------+----------------+
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Instead of :&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;json&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;cluster_name&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;docker-cluster&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;status&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;green&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;timed_out&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;false&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;number_of_nodes&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;number_of_data_nodes&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;active_primary_shards&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;active_shards&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;relocating_shards&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;initializing_shards&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;unassigned_shards&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;delayed_unassigned_shards&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;number_of_pending_tasks&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;number_of_in_flight_fetch&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;15&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;task_max_waiting_in_queue_millis&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;16&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;active_shards_percent_as_number&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;100&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;0
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;17&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;

          
        </content>
        
    </entry>
    <entry xml:lang="en">
        <title>PATCH-er selon la RFC</title>
        <published>2019-04-02T16:08:00+01:00</published>
        <updated>2019-04-02T16:08:00+01:00</updated>
        <author>
          <name>Jérôme Pin</name>
        </author>
        <link rel="alternate" type="text/html" href="https://jeromepin.fr/articles/patcher-selon-la-rfc/"/>
        <id>https://jeromepin.fr/articles/patcher-selon-la-rfc/</id>
        
        <content type="html" xml:base="https://jeromepin.fr/articles/patcher-selon-la-rfc/">
          
          &lt;h2 id=&quot;put-mise-a-jour-totale&quot;&gt;PUT: mise à jour totale&lt;&#x2F;h2&gt;
&lt;p&gt;La plupart des APIs REST proposent des mécanismes pour modifier des ressources, notamment grâce au verbe &lt;em&gt;PUT&lt;&#x2F;em&gt; qui permet d&#x27;envoyer la ressource à mettre à jour. &lt;em&gt;PUT&lt;&#x2F;em&gt; pose tout de même 3 problèmes :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Il est nécéssaire de faire un &lt;em&gt;GET&lt;&#x2F;em&gt; au préalable afin d&#x27;obtenir la totalité de la ressource&lt;&#x2F;li&gt;
&lt;li&gt;Il faut s&#x27;assurer que la ressource n&#x27;a pas été modifiée côté serveur entre le &lt;em&gt;GET&lt;&#x2F;em&gt; et le &lt;em&gt;PUT&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Il faut envoyer l&#x27;intégralité de la ressource, y compris les champs qui restent inchangés.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;La méthode &lt;em&gt;PUT&lt;&#x2F;em&gt; apparait ne pas être la solution idéale pour effectuer une mise à jour partielle.&lt;&#x2F;p&gt;
&lt;p&gt;Certaines API proposent d&#x27;exposer directement chaque champ de la ressource et d&#x27;utiliser &lt;em&gt;PUT&lt;&#x2F;em&gt; pour faire la mise à jour :&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;json&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;PUT &#x2F;users&#x2F;jeromepin&#x2F;age
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;24
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;C&#x27;est une solution simple mais qui rajoute beaucoup de complexité dans l&#x27;API. Et si le client souhaite mettre à jour plusieurs informations, il doit effectuer plusieurs appels &lt;em&gt;PUT&lt;&#x2F;em&gt;. La solution n&#x27;est toujours pas là. Heureusement, la &lt;a href=&quot;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc5789&quot;&gt;RFC 5789&lt;&#x2F;a&gt; propose un verbe HTTP conçu pour les mises à jour partielles : &lt;em&gt;PATCH&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;patch-mauvais-usage&quot;&gt;PATCH: mauvais usage&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;em&gt;PATCH&lt;&#x2F;em&gt; permet donc de modifier &lt;strong&gt;partiellement&lt;&#x2F;strong&gt; une ressource donnée. Ainsi beaucoup d&#x27;APIs ont ajouté le support de ce verbe au travers d&#x27;appels tels que :&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;json&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;PATCH &#x2F;users&#x2F;jeromepin
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;age=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;25
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;ou encore :&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;json&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;PATCH &#x2F;users&#x2F;jeromepin
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;{ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;age&amp;quot; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;25&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;strong&gt;CE N&#x27;EST PAS LE RÔLE DE &lt;em&gt;PATCH&lt;&#x2F;em&gt; !&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;PATCH&lt;&#x2F;em&gt; ne doit pas envoyer une partie d&#x27;une ressource.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;patch-er-correctement&quot;&gt;PATCH-er correctement&lt;&#x2F;h2&gt;
&lt;p&gt;Le but de &lt;em&gt;PATCH&lt;&#x2F;em&gt; n&#x27;est pas seulement de mettre à jour une ressource. En réalité, ce n&#x27;est pas du tout la façon dont &lt;em&gt;PATCH&lt;&#x2F;em&gt; doit fonctionner. La RFC indique :&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The difference between the PUT and PATCH requests is reflected in the way the server processes the enclosed entity to modify the resource identified by the Request-URI.  In a PUT request, the enclosed entity is considered to be a modified version of the resource stored on the origin server, and the client is requesting that the stored version be replaced.  With PATCH, however, the enclosed entity contains a set of instructions describing how a resource currently residing on the origin server should be modified to produce a new version.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Il est clairement indiqué que &lt;em&gt;PATCH&lt;&#x2F;em&gt;, contrairement à &lt;em&gt;PUT&lt;&#x2F;em&gt; qui envoi la nouvelle ressource dans son intégralité, doit envoyer une &lt;strong&gt;liste d&#x27;instructions décrivant la façon selon laquelle la ressource située sur le serveur doit être modifiée&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Une requête &lt;em&gt;PATCH&lt;&#x2F;em&gt; ressemble à ça :&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;json&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;PATCH &#x2F;users&#x2F;jeromepin HTTP&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;Host: www.example.com
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;Content-Type: application&#x2F;example
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f51818;&quot;&gt;description of changes&lt;&#x2F;span&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;[description of changes]&lt;&#x2F;code&gt; est appelé &amp;quot;&lt;em&gt;patch document&lt;&#x2F;em&gt;&amp;quot; (ou plus simplement &amp;quot;&lt;em&gt;patch&lt;&#x2F;em&gt;&amp;quot;). Le format de ce patch n&#x27;est pas défini dans cette RFC est peut-être de n&#x27;importe quel type comme par exemple la sortie de la commande &lt;code&gt;diff&lt;&#x2F;code&gt; :&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;json&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;PATCH &#x2F;users&#x2F;jeromepin HTTP&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;Host: www.example.com
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;Content-Type: application&#x2F;diff
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;--- old-json	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;2019-04-01 12&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;02&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;50&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;000000000&lt;&#x2F;span&gt;&lt;span&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;0200
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;+++ new-json	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;2019-04-01 12&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;03&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;00&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;000000000&lt;&#x2F;span&gt;&lt;span&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;0200
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;@@ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;-1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt; +&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span&gt; @@
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;{
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;name&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;Jerome Pin&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f51818;&quot;&gt;-   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;age&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;24
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f51818;&quot;&gt;+   &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;age&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;25
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Le &lt;code&gt;Content-Type&lt;&#x2F;code&gt; du &lt;em&gt;PATCH&lt;&#x2F;em&gt; doit être adapté au format du patch envoyé.&lt;&#x2F;p&gt;
&lt;p&gt;Le serveur &lt;strong&gt;DOIT&lt;&#x2F;strong&gt; appliquer la totalité des changements de la requête de façon atomique et ne jamais fournir (c.à.d enregistrer en base ou retourner à un client) la ressource partiellement modifiée. Si le patch ne peut pas être appliqué dans sa totalité, alors il ne doit pas être appliqué du tout.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;quel-format-pour-un-patch&quot;&gt;Quel format pour un patch ?&lt;&#x2F;h3&gt;
&lt;p&gt;La RFC 5789 est très souple et n&#x27;indique pas de type spécifique pour le format du patch, ainsi, c&#x27;est au serveur de veiller à supporter le type de patch approprié aux documents qu&#x27;il manipule.&lt;&#x2F;p&gt;
&lt;p&gt;Heureusement, pour la manipulation de documents JSON (issus par exemple de base de données orientées documents), les RFC &lt;a href=&quot;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc6901&quot;&gt;6901&lt;&#x2F;a&gt; et &lt;a href=&quot;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc6902&quot;&gt;6902&lt;&#x2F;a&gt; définissent respectivement les termes &lt;em&gt;&amp;quot;JSON Pointer&amp;quot;&lt;&#x2F;em&gt; et &lt;em&gt;&amp;quot;JSON Patch&amp;quot;&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Un &lt;em&gt;&amp;quot;JSON Pointer&amp;quot;&lt;&#x2F;em&gt; défini une syntaxe sous forme de chaine de caractères pour identifier une valeur spécifique au sein d&#x27;un objet JSON : &lt;code&gt;&#x2F;users&#x2F;0&#x2F;email&lt;&#x2F;code&gt;.
Un &lt;em&gt;&amp;quot;JSON Patch&amp;quot;&lt;&#x2F;em&gt; défini la structure d&#x27;un document JSON permettant d&#x27;exprimer une série de modifications à appliquer à un document JSON :&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;json&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;[
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;     { &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;op&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;test&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;path&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;&#x2F;a&#x2F;b&#x2F;c&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;value&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;foo&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;     { &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;op&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;remove&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;path&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;&#x2F;a&#x2F;b&#x2F;c&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;     { &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;op&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;add&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;path&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;&#x2F;a&#x2F;b&#x2F;c&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;value&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span&gt;[ &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;foo&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;bar&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;] }&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;     { &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;op&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;replace&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;path&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;&#x2F;a&#x2F;b&#x2F;c&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;value&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;42 &lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;     { &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;op&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;move&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;from&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;&#x2F;a&#x2F;b&#x2F;c&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;path&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;&#x2F;a&#x2F;b&#x2F;d&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;     { &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;op&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;copy&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;from&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;&#x2F;a&#x2F;b&#x2F;d&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;path&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;&#x2F;a&#x2F;b&#x2F;e&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Avec ces deux nouvelles RFC, il est possible d&#x27;effectuer une requête &lt;em&gt;PATCH&lt;&#x2F;em&gt; pour enfin modifier un document JSON :&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;json&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;PATCH &#x2F;users&#x2F;jeromepin HTTP&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;Host: www.example.com
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;Content-Type: application&#x2F;json-patch+json
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;[
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    { &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;op&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;replace&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;path&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;&#x2F;age&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;, &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;value&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;25&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Dans le cas où le serveur manipule du XML, une &lt;a href=&quot;http:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc5261&quot;&gt;RFC&lt;&#x2F;a&gt; décrit un format équivalent au JSON-Patch.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;Cet usage de &lt;em&gt;PATCH&lt;&#x2F;em&gt; reste très peu connu. Il est censé être le standard à utiliser pour des mises à jour partielles, mais il est facile de s&#x27;aperçevoir qu&#x27;un tel fonctionnement complexifie la gestion du serveur et la façon dont nous avons l&#x27;habitude d&#x27;utiliser les verbes plus traditionnels (&lt;em&gt;GET&lt;&#x2F;em&gt;, &lt;em&gt;POST&lt;&#x2F;em&gt;, &lt;em&gt;PUT&lt;&#x2F;em&gt;). La RFC étant très souple, il est tout à fait possible d&#x27;utiliser son propre format de patch, ainsi pour incrémenter l&#x27;age, il est possible de faire quelque chose comme :&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;json&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-json &quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;PATCH &#x2F;users&#x2F;jeromepin HTTP&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;1
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;Host: www.example.com
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;Content-Type: application&#x2F;custom-format+json
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;[
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    { &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;increment&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;age&amp;quot; &lt;&#x2F;span&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;]
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Évidemment, d&#x27;un point de vue conceptuel, il faut alors se demander si cette façon d&#x27;envoyer des actions plutôt que des états est compatible avec la philosophie REST ? N&#x27;est-ce pas plus proche de RPC ?&lt;&#x2F;p&gt;

          
        </content>
        
    </entry>
    <entry xml:lang="en">
        <title>Construire de bons microservices</title>
        <published>2018-09-02T14:51:00+01:00</published>
        <updated>2018-09-02T14:51:00+01:00</updated>
        <author>
          <name>Jérôme Pin</name>
        </author>
        <link rel="alternate" type="text/html" href="https://jeromepin.fr/articles/construire-de-bons-microservices/"/>
        <id>https://jeromepin.fr/articles/construire-de-bons-microservices/</id>
        
        <content type="html" xml:base="https://jeromepin.fr/articles/construire-de-bons-microservices/">
          
          &lt;h2 id=&quot;configuration&quot;&gt;Configuration&lt;&#x2F;h2&gt;
&lt;p&gt;La configuration d&#x27;un service doit être optionnelle et tous ses paramètres doivent avoir une valeur par défaut :&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;javascript&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-javascript &quot;&gt;&lt;code class=&quot;language-javascript&quot; data-lang=&quot;javascript&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#fa6e32;&quot;&gt;const &lt;&#x2F;span&gt;&lt;span&gt;ELASTICSEARCH_HOST &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;= &lt;&#x2F;span&gt;&lt;span&gt;process&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ELASTICSEARCH_HOST &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;|| &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;#39;localhost&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ou encore :&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;bash&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;ELASTICSEARCH_HOST&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;{$ELASTICSEARCH_HOST&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;:-&lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;localhost&lt;&#x2F;span&gt;&lt;span&gt;} 
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Chaque élément de configuration doit être modifiable par une variable d&#x27;environnement correctement nommée. L&#x27;intérêt est de permettre de changer le comportement de l&#x27;application au &lt;em&gt;runtime&lt;&#x2F;em&gt; plutôt qu&#x27;au &lt;em&gt;buildtime&lt;&#x2F;em&gt;. De plus, l&#x27;usage d&#x27;orchestrateurs de conteneurs comme &lt;em&gt;Docker Swarm&lt;&#x2F;em&gt; ou &lt;em&gt;Kubernetes&lt;&#x2F;em&gt; rendent plus pratique le passage de variables d&#x27;environnement que de fichiers de configuration.&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;yaml&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-yaml &quot;&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;apiVersion&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;v1
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;kind&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;Pod
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;metadata&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;foo
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;spec&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;containers&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;  - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;foo
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;image&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;foo:1.0
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;:
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    - &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;name&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;ELASTICSEARCH_HOST
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;      &lt;&#x2F;span&gt;&lt;span style=&quot;color:#399ee6;&quot;&gt;value&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;elasticsearch.example.com&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;signaux-et-fermeture&quot;&gt;Signaux et fermeture&lt;&#x2F;h2&gt;
&lt;p&gt;Une application doit être en mesure de réagir aux &lt;a href=&quot;http:&#x2F;&#x2F;man7.org&#x2F;linux&#x2F;man-pages&#x2F;man7&#x2F;signal.7.html&quot;&gt;signaux&lt;&#x2F;a&gt; envoyés par l&#x27;OS et en tirer parti. Par exemple, &lt;a href=&quot;https:&#x2F;&#x2F;prometheus.io&quot;&gt;Prometheus&lt;&#x2F;a&gt; recharge sa configuration à la réception d&#x27;un SIGHUP :&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;bash&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; kill&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt; -HUP&lt;&#x2F;span&gt;&lt;span&gt; 1234
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;INFO[1234]&lt;&#x2F;span&gt;&lt;span&gt; Loading configuration file prometheus.yml source=main.go:201
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;INFO[1234]&lt;&#x2F;span&gt;&lt;span&gt; Stopping target manager... source=targetmanager.go:281
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;INFO[1234]&lt;&#x2F;span&gt;&lt;span&gt; Target manager stopped. source=targetmanager.go:216
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;INFO[1234]&lt;&#x2F;span&gt;&lt;span&gt; Starting target manager... source=targetmanager.go:122
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;L&#x27;application doit s&#x27;éteindre proprement lorsqu&#x27;elle reçoit un &lt;code&gt;SIGTERM&lt;&#x2F;code&gt;. Elle doit pouvoir nettoyer tous les éléments externes dont elle a eu besoin : connections ouvertes, caches utilisés, fichiers ouverts, fichiers temporaires créés, etc...&lt;&#x2F;p&gt;
&lt;h2 id=&quot;logs&quot;&gt;Logs&lt;&#x2F;h2&gt;
&lt;p&gt;La gestion des logs est souvent bien plus complexe que ce que l&#x27;on pense. Il est donc généralement intéressant de faire usage d&#x27;une librairie dédiée. Cette librairie est en charge de différents paramètres :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;format : JSON, clé-valeur&lt;&#x2F;li&gt;
&lt;li&gt;contexte : date et heure, module émétteur&lt;&#x2F;li&gt;
&lt;li&gt;export : réseau (&lt;code&gt;tcp&#x2F;udp&lt;&#x2F;code&gt;, &lt;code&gt;http&lt;&#x2F;code&gt;, &lt;code&gt;kafka&lt;&#x2F;code&gt;, ...), &lt;code&gt;syslog&lt;&#x2F;code&gt;, fichiers&lt;&#x2F;li&gt;
&lt;li&gt;rotation&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Dans le cas d&#x27;un microservice, l&#x27;application ne doit pas s&#x27;occuper du routage et du stockage de ses logs. Elle doit simplement écrire dans &lt;code&gt;stdout&lt;&#x2F;code&gt; et &lt;code&gt;stderr&lt;&#x2F;code&gt; en fonction des besoins, et laisser un routeur de logs (comme &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;fluent&#x2F;fluentd&quot;&gt;fluentd&lt;&#x2F;a&gt; ou &lt;a href=&quot;https:&#x2F;&#x2F;www.elastic.co&#x2F;products&#x2F;beats&#x2F;filebeat&quot;&gt;filebeat&lt;&#x2F;a&gt;) gérer et acheminer les logs.&lt;&#x2F;p&gt;
&lt;p&gt;Chaque message de log doit être associé au bon niveau (&lt;code&gt;debug&lt;&#x2F;code&gt;, &lt;code&gt;info&lt;&#x2F;code&gt;, &lt;code&gt;warn&lt;&#x2F;code&gt;, &lt;code&gt;error&lt;&#x2F;code&gt;, ...) pour qu&#x27;il puisse être affiché et&#x2F;ou traité de façon optimale. Il peut être intéressant d&#x27;afficher un message pour certains cas :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Message de démarrage de l&#x27;application;&lt;&#x2F;li&gt;
&lt;li&gt;Ports sur lesquels elle écoute;&lt;&#x2F;li&gt;
&lt;li&gt;Services auxquels elle est connectée;&lt;&#x2F;li&gt;
&lt;li&gt;Évènements prévus et imprévus;&lt;&#x2F;li&gt;
&lt;li&gt;Signaux reçus;&lt;&#x2F;li&gt;
&lt;li&gt;Fermeture;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;blockquote&gt;
&lt;p&gt;[foo] [INFO] Listening on port 80&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[foo] [INFO] Connected to mysql:&#x2F;&#x2F;foo:bar@host:port&#x2F;database. Alive and kicking !&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;...&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[foo] [INFO] SIGHUP received. Reloading configuration&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;...&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;[foo] [INFO] Shutting down... Closing connexions, removing temporary files&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;choix-du-langage&quot;&gt;Choix du langage&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;eviter-les-langages-a-machines-virtuelles&quot;&gt;Éviter les langages à machines virtuelles&lt;&#x2F;h3&gt;
&lt;p&gt;Les langages basés sur des machines virtuelles (Java, Clojure, Erlang, .NET) sont plus lents à démarrer et ont nécessairement besoin de plus de ressources. De plus, ces machines virtuelles sont généralement conçues pour gérer de large applications monolithiques qui ont besoin de fonctionnalités avancées de gestion de mémoire, de CPU, de threads, etc... Ces fonctionnalités sont redondantes avec les orchestrateurs et les runtimes et peuvent créer des conflits, comme par exemple la JVM qui ne supporte pas (ou mal) les limites de CPU et de mémoire définies dans un conteneur. Seules les &lt;a href=&quot;https:&#x2F;&#x2F;bugs.openjdk.java.net&#x2F;browse&#x2F;JDK-8196595&quot;&gt;versions les plus récentes du JDK 10&lt;&#x2F;a&gt; permettent une prise en charge correcte de ces paramètres.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;creer-des-binaires-statiques&quot;&gt;Créer des binaires statiques&lt;&#x2F;h3&gt;
&lt;p&gt;Utiliser un langage qui crée des binaires statiques présente plusieurs avantages :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;le binaire est portable : les librairies liées sont distribuées avec le binaire;&lt;&#x2F;li&gt;
&lt;li&gt;il n&#x27;est pas nécessaire d&#x27;avoir une arborescence complète d&#x27;un OS (&lt;code&gt;&#x2F;bin&lt;&#x2F;code&gt;, &lt;code&gt;&#x2F;usr&#x2F;bin&lt;&#x2F;code&gt;, &lt;code&gt;&#x2F;tmp&lt;&#x2F;code&gt;, etc...) pour exécuter le binaire;&lt;&#x2F;li&gt;
&lt;li&gt;la construction du binaire est prévisible;&lt;&#x2F;li&gt;
&lt;li&gt;le binaire est moins sensible aux contaminations de ses librairies par des tierces-parties;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;C&#x27;est avec toutes ces contraintes que des langages comme &lt;a href=&quot;https:&#x2F;&#x2F;golang.org&#x2F;&quot;&gt;Go&lt;&#x2F;a&gt; et &lt;a href=&quot;https:&#x2F;&#x2F;www.rust-lang.org&#x2F;&quot;&gt;Rust&lt;&#x2F;a&gt; ont vu leur popularité croître énormément ces dernière années.&lt;&#x2F;p&gt;
&lt;p&gt;Pour un même programme C++ :&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;cpp&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-cpp &quot;&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#fa6e32;&quot;&gt;#include &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;lt;iostream&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#fa6e32;&quot;&gt;int &lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;main&lt;&#x2F;span&gt;&lt;span&gt;() {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    std&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;::&lt;&#x2F;span&gt;&lt;span&gt;cout &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;&amp;lt;&amp;lt; &lt;&#x2F;span&gt;&lt;span style=&quot;color:#86b300;&quot;&gt;&amp;quot;Foo&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;span style=&quot;color:#fa6e32;&quot;&gt;return &lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color:#61676ccc;&quot;&gt;;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;}
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Le binaire compilé dynamiquement pèse 7.8Ko contre 1.6Mo statiquement. La différence vient de la présence (ou non) des librairies nécessaires au sein du binaire.&lt;&#x2F;p&gt;
&lt;p&gt;La commande &lt;code&gt;ldd&lt;&#x2F;code&gt; permet de connaître les librairies liées au binaire :&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;bash&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; g++&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ff8f40;&quot;&gt; -o&lt;&#x2F;span&gt;&lt;span&gt; foo foo.cpp
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; ldd foo
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;linux-vdso.so.1&lt;&#x2F;span&gt;&lt;span&gt; (0x00007fffc9ff8000)
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;libstdc++.so.6&lt;&#x2F;span&gt;&lt;span&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;usr&#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libstdc++.so.6 (0x00007f6c9c4b6000)
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;libm.so.6&lt;&#x2F;span&gt;&lt;span&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libm.so.6 (0x00007f6c9c1b5000)
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;libgcc_s.so.1&lt;&#x2F;span&gt;&lt;span&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libgcc_s.so.1 (0x00007f6c9bf9f000)
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;libc.so.6&lt;&#x2F;span&gt;&lt;span&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color:#ed9366;&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libc.so.6 (0x00007f6c9bbf4000)
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span&gt;	&lt;&#x2F;span&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;&#x2F;lib64&#x2F;ld-linux-x86-64.so.2&lt;&#x2F;span&gt;&lt;span&gt; (0x00007f6c9c7c1000)
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Mon binaire &lt;code&gt;foo&lt;&#x2F;code&gt; requiert notamment &lt;code&gt;libstdc++.so.6 &lt;&#x2F;code&gt; (&lt;code&gt;&#x2F;usr&#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libstdc++.so.6&lt;&#x2F;code&gt;) et &lt;code&gt;libc.so.6&lt;&#x2F;code&gt; (&lt;code&gt;&#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libc.so.6&lt;&#x2F;code&gt;). Si je distribue ce binaire sur une autre machine, il faudra non seulement qu&#x27;elle tourne sur le même OS, mais aussi que les librairies soient les mêmes (chemin et version) :&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;bash&quot; style=&quot;background-color:#fafafa;color:#61676c;&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; mv &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libc.so.6 &#x2F;lib&#x2F;x86_64-linux-gnu&#x2F;libc.so.6.old
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt; .&#x2F;foo
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span style=&quot;color:#f29718;&quot;&gt;.&#x2F;foo:&lt;&#x2F;span&gt;&lt;span&gt; error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;stateless-vs-stateful&quot;&gt;Stateless vs Stateful&lt;&#x2F;h2&gt;
&lt;p&gt;Un bon conteneur est un conteneur que l&#x27;on peut déplacer et redémarrer à la demande, sans pré-requis. Il faut donc qu&#x27;il soit le plus possible &lt;code&gt;stateless&lt;&#x2F;code&gt; : toutes les données persistantes dont a besoin l&#x27;application doivent être stockées dans des systèmes externes comme une base de données. Il ne doit pas y avoir de différence entre plusieurs instances d&#x27;une application.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;robustesse-healthchecks-et-timeouts&quot;&gt;Robustesse, healthchecks et timeouts&lt;&#x2F;h2&gt;
&lt;p&gt;L&#x27;application doit être en mesure de gérer les erreurs via une dégradation de service ou via du &lt;em&gt;back-off&lt;&#x2F;em&gt; plutôt que de crasher. Elle doit pouvoir non-seulement répondre à des &lt;em&gt;health checks&lt;&#x2F;em&gt; (via une route http par exemple) mais aussi en émettre afin de surveiller la disponibilité des services liés.&lt;&#x2F;p&gt;
&lt;p&gt;À un stade plus avancé, l&#x27;application doit supporter des mécanismes plus complexes comme les &lt;em&gt;timeouts&lt;&#x2F;em&gt;, le &lt;em&gt;throttling&lt;&#x2F;em&gt; et les &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Circuit_breaker_design_pattern&quot;&gt;circuit-breakers&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;

          
        </content>
        
    </entry>
    <entry xml:lang="en">
        <title>Sharding : Propriétés et fonctionnement</title>
        <published>2018-07-12T08:54:00+01:00</published>
        <updated>2018-07-12T08:54:00+01:00</updated>
        <author>
          <name>Jérôme Pin</name>
        </author>
        <link rel="alternate" type="text/html" href="https://jeromepin.fr/articles/sharding-proprietes-et-fonctionnement/"/>
        <id>https://jeromepin.fr/articles/sharding-proprietes-et-fonctionnement/</id>
        
        <content type="html" xml:base="https://jeromepin.fr/articles/sharding-proprietes-et-fonctionnement/">
          
          &lt;p&gt;Le sharding (aussi souvent nommé &lt;em&gt;horizontal partitioning&lt;&#x2F;em&gt;) est une méthode de séparation des données d&#x27;une base de données en plusieurs groupes logiques, généralement répartis sur plusieurs nœuds d&#x27;un cluster.&lt;&#x2F;p&gt;
&lt;p&gt;Le sharding a plusieurs avantages :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;dépasser les limitations d&#x27;une machine seule (CPU, stockage, etc...);&lt;&#x2F;li&gt;
&lt;li&gt;effectuer des traitements concurrents;&lt;&#x2F;li&gt;
&lt;li&gt;limiter la diffusion d&#x27;une requête à un sous-set de données;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Le sharding est souvent implémenté au niveau de la base de donnée elle-même (comme &lt;a href=&quot;https:&#x2F;&#x2F;www.elastic.co&#x2F;guide&#x2F;en&#x2F;elasticsearch&#x2F;reference&#x2F;6.2&#x2F;_basic_concepts.html#getting-started-shards-and-replicas&quot;&gt;Elasticsearch&lt;&#x2F;a&gt;, Cassandra ou &lt;a href=&quot;https:&#x2F;&#x2F;docs.mongodb.com&#x2F;manual&#x2F;sharding&#x2F;&quot;&gt;MongoDB&lt;&#x2F;a&gt;) mais peut aussi l&#x27;être au niveau applicatif pour supporter des bases de données où le sharding n&#x27;est pas natif (comme &lt;a href=&quot;https:&#x2F;&#x2F;redis.io&#x2F;topics&#x2F;partitioning&quot;&gt;Redis&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;Il existe plusieurs stratégies pour distribuer des données dans plusieurs base de données. Chacune a ses avantages et ses inconvénients et doit être choisie avec soin en fonction des besoins et des contraintes. Quelle que soit la stratégie choisie, il faut toujours prendre en compte les possibles &lt;strong&gt;hotspots&lt;&#x2F;strong&gt; : une distribution inégale des données entraine une surutilisation de certains shards et réduit presque à néant l&#x27;intérêt du sharding.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;principes-de-base&quot;&gt;Principes de base&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;notions&quot;&gt;Notions&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;clé de shard : (&lt;em&gt;shard key&lt;&#x2F;em&gt;) Suite de caractères qui identifie de façon unique un shard.&lt;&#x2F;li&gt;
&lt;li&gt;shard logique : (&lt;em&gt;logical shard&lt;&#x2F;em&gt;) Ensemble de données stockées sur un seul nœud et partageant la même clé de shard.&lt;&#x2F;li&gt;
&lt;li&gt;shard physique : (&lt;em&gt;physical shard&lt;&#x2F;em&gt;) Un nœud du cluster, il peut contenir plusieurs shards logiques.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;comment-les-donnees-sont-lues-et-ecrites&quot;&gt;Comment les données sont lues et écrites&lt;&#x2F;h3&gt;
&lt;p&gt;Les bases de données sont utilisées pour stocker des données. Par conséquent le choix de la stratégie de sharding dépend de ces accès. Il s&#x27;agit de définir à l&#x27;avance les &lt;a href=&quot;https:&#x2F;&#x2F;landing.google.com&#x2F;sre&#x2F;sre-book&#x2F;chapters&#x2F;service-level-objectives&#x2F;&quot;&gt;SLOs&lt;&#x2F;a&gt; :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Quelle est la distribution entre la lecture et l&#x27;écriture ? (50&#x2F;50, 80&#x2F;20, etc...)&lt;&#x2F;li&gt;
&lt;li&gt;Quels volumes sont gérés ?&lt;&#x2F;li&gt;
&lt;li&gt;Quels sont les objectifs de performance ? (latence, vitesse, etc...)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;comment-les-donnees-sont-distribuees&quot;&gt;Comment les données sont distribuées&lt;&#x2F;h3&gt;
&lt;p&gt;Les &lt;strong&gt;hotspot&lt;&#x2F;strong&gt; contrebalancent presque totalement l&#x27;intérêt du sharding. Il faut donc choisir avec soin le critère sur lequel les données vont être distribuées. Se baser sur une clé trop commune et non-uniformément distribuée va créer un déséquilibre dans la répartition de nos données.&lt;&#x2F;p&gt;
&lt;p&gt;Par exemple, dans une base de données qui stocke des documents utilisateurs, distribuer les données en se basant sur l&#x27;identifiant de l&#x27;utilisateur est une mauvaise idée. Si un utilisateur enregistre beaucoup plus de documents que les autres, le shard auquel il est associé va croître fortement. Que va-t-il se passer lorsque ce shard dépassera la taille d&#x27;un nœud ? Comment ce shard va impacter les performances du reste du cluster ?&lt;&#x2F;p&gt;
&lt;h3 id=&quot;comment-gerer-la-redistribution-des-donnees&quot;&gt;Comment gérer la redistribution des données&lt;&#x2F;h3&gt;
&lt;p&gt;Une fois que les questions ci-dessus sont traitées, que le cluster fonctionne et que l&#x27;utilisation prend de l&#x27;ampleur, un premier problème survient : comment ajouter&#x2F;modifier&#x2F;supprimer des nœuds sans affecter les performances ?&lt;&#x2F;p&gt;
&lt;p&gt;Lors de la modification de l&#x27;état du cluster, les données stockées vont devoir être redistribuées et il va falloir en déplacer de grandes quantités rapidement sans avoir d&#x27;incidence sur les performances.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sharding-algorithmique&quot;&gt;Sharding algorithmique&lt;&#x2F;h2&gt;
&lt;p&gt;Le sharding algorithmique (aussi nommé &lt;em&gt;Client side partitioning&lt;&#x2F;em&gt;) permet au client de déterminer le shard sans aide extérieure, en se basant uniquement sur une fonction généralement de la forme &lt;code&gt;hash(key) % num_nodes&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.elastic.co&#x2F;guide&#x2F;en&#x2F;elasticsearch&#x2F;reference&#x2F;current&#x2F;mapping-routing-field.html&quot;&gt;Elasticsearch&lt;&#x2F;a&gt; utilise cette stratégie pour définir sur quel shard doit se trouver un document :&lt;&#x2F;p&gt;
&lt;pre style=&quot;background-color:#fafafa;color:#61676c;&quot;&gt;&lt;code&gt;&lt;span&gt;shard_num = hash_murmur3(doc._id) % num_primary_shards
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Le sharding algorithmique distribue les données en se basant uniquement sur cette fonction, et ne prend en compte aucun paramètre extérieur comme le taux d&#x27;utilisation d&#x27;un nœud, la taille de la donnée à traiter, etc...&lt;&#x2F;p&gt;
&lt;p&gt;Redistribuer les données peut s&#x27;avérer complexe : cela requiert non seulement de déplacer les données mais aussi de mettre à jour la fonction utilisée. La fonction idéale ne devrait pas nécessiter de déplacer plus de &lt;code&gt;1&#x2F;n&lt;&#x2F;code&gt; données et ne devrait pas déplacer des données qui n&#x27;ont pas besoin de l&#x27;être.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;sharding-dynamique&quot;&gt;Sharding dynamique&lt;&#x2F;h2&gt;
&lt;p&gt;Le sharding dynamique (parfois nommé &lt;em&gt;Proxy assisted partitioning&lt;&#x2F;em&gt;) nécessite un &lt;strong&gt;service externe&lt;&#x2F;strong&gt; pour déterminer l&#x27;emplacement d&#x27;une donnée. Ce service agit comme un annuaire et indique la correspondance entre une clé (ou un ensemble de clés) et le shard sur lequel cette clé est assignée. Par exemple, &lt;a href=&quot;https:&#x2F;&#x2F;hadoop.apache.org&#x2F;docs&#x2F;current&#x2F;hadoop-project-dist&#x2F;hadoop-hdfs&#x2F;HdfsDesign.html#NameNode_and_DataNodes&quot;&gt;HDFS&lt;&#x2F;a&gt; utilise un &lt;em&gt;Namenode&lt;&#x2F;em&gt; pour stocker ses métadonnnées.&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;range&lt;&#x2F;th&gt;&lt;th&gt;shard&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;0, 3&lt;&#x2F;td&gt;&lt;td&gt;0&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;4, 7&lt;&#x2F;td&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;8, B&lt;&#x2F;td&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;C, F&lt;&#x2F;td&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;Pour lire ou écrire une donnée, les clients ont nécessairement besoin de contacte le service de localisation. Celui va ensuite contacter la base de données elle-même, faisant office de proxy.&lt;&#x2F;p&gt;
&lt;p&gt;Ce service externe permet de mieux gérer les données non-uniformément distribuées puisque les ensembles de clés n&#x27;ont pas besoin d&#x27;être de taille identique mais peuvent varier en fonction des besoins.&lt;&#x2F;p&gt;
&lt;p&gt;En revanche, il devient aussi un point de défaillance unique : chaque lecture ou écriture a besoin d&#x27;y accéder, il faut donc que la stabilité et les performances soient au rendez-vous. Il ne peut pas être caché ni dupliqué  facilement : des données obsolètes causeraient un désastre sur le cluster.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;Le sharding ajoute de la complexité non seulement en termes de développement mais aussi d&#x27;opérations : les données ne sont plus stockées au même endroit, le réseau introduit de la latence, la topologie change, plus de serveurs doivent être configurés, etc...&lt;&#x2F;p&gt;
&lt;p&gt;Le sharding ne doit pas être le premier axe d&#x27;amélioration. Bien connaître les données que à stocker et la façon dont elles vont être utilisées est beaucoup plus important. Utiliser un serveur plus puissant suffit souvent à régler les problèmes de performances tant que l&#x27;échelle reste modérée.&lt;&#x2F;p&gt;
&lt;p&gt;Si l&#x27;application est limitée par les performances de lecture de la base de données, ajouter des &lt;strong&gt;caches&lt;&#x2F;strong&gt; ou des &lt;strong&gt;replicas de lecture&lt;&#x2F;strong&gt; peut corriger le problème sans ajouter trop de complexité.&lt;&#x2F;p&gt;
&lt;p&gt;Enfin, il est important de s&#x27;assurer que les données sont organisées de façon optimale : les blobs sont sur un stockage externe (système de fichier, stockage objets, etc...), l&#x27;analyse et la recherche sont délégués à d&#x27;autres systèmes, etc...&lt;&#x2F;p&gt;

          
        </content>
        
    </entry>
</feed>