<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title>Shadab Ahmed</title>
		<description></description>
		<link>/</link>
		<atom:link href="/feed.xml" rel="self" type="application/rss+xml" />
		
			<item>
				<title>Fan Mod for Meanwell Power Supply</title>
				<description>
&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#parts-required&quot; id=&quot;markdown-toc-parts-required&quot;&gt;Parts Required&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#modding-steps&quot; id=&quot;markdown-toc-modding-steps&quot;&gt;Modding Steps&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#final-result&quot; id=&quot;markdown-toc-final-result&quot;&gt;Final Result&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Working in robotics often means dealing with reliable yet noisy Meanwell power supplies. Unfortunately, the tiny 40mm fans inside the specific models I work with, are incredibly loud, significantly affecting comfort and actually worsened my tinnitus. In an effort to reclaim some sanity, I embarked on a modding adventure to silence my Meanwell PSU. Here’s a straightforward guide on how you can do the same. The specific model I worked with is 
&lt;a href=&quot;https://www.meanwell.com/Upload/PDF/RSP-2000/RSP-2000-SPEC.PDF&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;RSP-2000&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/fan_mod/RSP-2000-483.png&quot; alt=&quot;Meanwell&quot; class=&quot;media-left,&quot; style=&quot;width:300px&quot; /&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;⚠️ Caution:&lt;/strong&gt;&lt;br /&gt;
Meanwell power supplies can retain charge even after power-off. Ensure the unit is unplugged and powered off for at least a few hours before opening it up.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;parts-required&quot;&gt;Parts Required&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Fan Cable Adapters&lt;/strong&gt; (&lt;a href=&quot;https://www.amazon.com/gp/product/B07Q5BTTDX&quot;&gt;2-pack, 4-pin&lt;/a&gt;):
    &lt;ul&gt;
      &lt;li&gt;Allows connection of larger fans to Meanwell’s small fan headers.&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Note:&lt;/strong&gt; You’ll need to re-pin these cables (details below).&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;2 x 120mm CPU Cooling Fans&lt;/strong&gt;:
    &lt;ul&gt;
      &lt;li&gt;Any standard brand works, but for silent operation, I highly recommend:
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;https://www.amazon.com/Noctua-NF-A12x15-PWM-chromax-Black-swap-120x15mm/dp/B0813X9G8T&quot;&gt;Noctua NF-A12x15 PWM chromax&lt;/a&gt; (ultra-quiet &amp;amp; reliable).&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;RGB fans are also an option if you want aesthetics, provided you have a motherboard or RGB controller to power the lights.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Mesh Filters&lt;/strong&gt; (&lt;a href=&quot;https://www.amazon.com/gp/product/B0BN89YW8R&quot;&gt;ATX case dust filters&lt;/a&gt;):
    &lt;ul&gt;
      &lt;li&gt;Protects internal components from dust while maintaining airflow.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;modding-steps&quot;&gt;Modding Steps&lt;/h2&gt;

&lt;h3 id=&quot;1-open-the-meanwell-psu-case&quot;&gt;1. Open the Meanwell PSU Case&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Unscrew and remove the top cover.&lt;/li&gt;
  &lt;li&gt;Remove the two noisy 40mm fans, carefully scraping off any hot glue.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/fan_mod/meanwell_fans.png&quot; alt=&quot;Removing Meanwell Fans&quot; width=&quot;500px&quot; /&gt;&lt;/p&gt;

&lt;p&gt;You’ll see two exposed 4-pin connectors:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/fan_mod/connector_board.png&quot; alt=&quot;4-pin connectors exposed&quot; width=&quot;500px&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;2-prepare-the-fan-adapter-cables&quot;&gt;2. Prepare the Fan Adapter Cables&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;The default adapter pinout &lt;strong&gt;will damage your fans&lt;/strong&gt; if connected directly. You need to pry out the individual wires and re-pin the adapters following this schematic:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/fan_mod/connector_cable.png&quot; alt=&quot;Modified Adapter Schematic&quot; style=&quot;width:600px&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Larger End (for the new fans):&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/fan_mod/connector_big.png&quot; alt=&quot;Adapter Large End&quot; style=&quot;width:300px&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Smaller End (connects to Meanwell PSU):&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/fan_mod/connector_small.png&quot; alt=&quot;Adapter Small End&quot; style=&quot;width:300px&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;3-connect-and-prepare-the-fans&quot;&gt;3. Connect and Prepare the Fans&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Zip-tie the two 120mm fans together for easy mounting:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/fan_mod/fans.png&quot; alt=&quot;Fans Tied Together&quot; style=&quot;width:500px&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;4-connect-fans-to-meanwell-psu&quot;&gt;4. Connect Fans to Meanwell PSU&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Plug fan connectors into the larger ends of adapter cables.&lt;/li&gt;
  &lt;li&gt;Connect smaller adapter ends to Meanwell’s PCB connectors.&lt;/li&gt;
  &lt;li&gt;Route cables neatly through bottom openings for tidy management:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/fan_mod/connected.png&quot; alt=&quot;Fans Connected to PCB&quot; style=&quot;width:500px&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I also used aluminum metal tape (used on dryer vents) to secure loose cables&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;5-cover-psu-with-mesh-filter&quot;&gt;5. Cover PSU with Mesh Filter&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Cut ATX mesh filter to match Meanwell PSU dimensions.&lt;/li&gt;
  &lt;li&gt;Cover PSU top opening to allow airflow yet protect from dust:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/fan_mod/mesh.png&quot; alt=&quot;Mesh Filter on PSU&quot; style=&quot;width:600px&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;6-mount-fans-onto-the-psu&quot;&gt;6. Mount Fans onto the PSU&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Position fans on top of the PSU, aligning carefully.&lt;/li&gt;
  &lt;li&gt;Secure with screws through fan corners. You might need to drill small holes in fan frames for alignment:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/fan_mod/modded.png&quot; alt=&quot;Fans Mounted on PSU&quot; style=&quot;width:600px&quot; /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Optionally, cover side openings and cable gaps using aluminum tape for better airflow management.&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;final-result&quot;&gt;Final Result&lt;/h2&gt;

&lt;p&gt;Enjoy your newly quiet, cool-running Meanwell power supply. My PSU is now effectively unnoticeable and temperatures are good to touch even at load. Here’s my completed mod in it’s full RGB glory powering both the motherboard (via pico-itx) and also the robot arm:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/fan_mod/case.gif&quot; alt=&quot;Meanwell Modded PSU RGB&quot; style=&quot;width:400px&quot; /&gt;&lt;/p&gt;

</description>
				<pubDate>Fri, 02 May 2025 00:00:00 +0000</pubDate>
				<link>/electronics/2025/05/02/fan-mod-meanwell</link>
				<guid isPermaLink="true">/electronics/2025/05/02/fan-mod-meanwell</guid>
			</item>
		
			<item>
				<title>A Smarter TV Mount with Arduino</title>
				<description>

&lt;h3 id=&quot;tldr&quot;&gt;TLDR;&lt;/h3&gt;
&lt;p&gt;Used an Arduino Nano to make a TV Mount smarter. Jump to the &lt;a href=&quot;#final-setup&quot;&gt;Final Setup&lt;/a&gt; section for a demo video.&lt;/p&gt;

&lt;h3 id=&quot;intro&quot;&gt;Intro&lt;/h3&gt;

&lt;p&gt;Since I’m on a break in-between jobs, I thought I’d revisit my old blog and post about something interesting I’ve done during the time. I’ve been wanting to place our TV on the fireplace mantel in our family room. However, it makes the TV too high to watch. To fix this, I installed a motorized above-fireplace TV mount to lower the TV down while watching. This &lt;a href=&quot;https://www.amazon.com/Monoprice-Motorized-Fireplace-Full-Motion-Articulating/dp/B08J9VHTZ6&quot; target=&quot;_blank&quot;&gt;Monoprice TV Mount&lt;/a&gt; seemed perfect for it:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/concept.png&quot; alt=&quot;TV Mount Image&quot; class=&quot;media-left&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It does handle the weight pretty well. However, a few major issues:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;The remote is horrible. It picks up IR signals from the TV remote and moves on things like volume up/down/mute etc. Super annoying!&lt;/li&gt;
  &lt;li&gt;It has a powerful motor, but no sensor to stop if something is obstructing. It literally can crush anything which comes in its way.&lt;/li&gt;
  &lt;li&gt;If you press the up button for too long, the motor keeps hammering as it’s stuck at the top-most position and doesn’t know it should stop.&lt;/li&gt;
  &lt;li&gt;At the top-most position, you can still swivel the TV right/left, possibly hitting the wall. Guaranteed to damage the TV or the wall behind it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I decided to make it better with features like:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;RF remote instead of IR, so it isn’t affected by the TV remote or any other IR source&lt;/li&gt;
  &lt;li&gt;Detect if the TV is too close to the wall and prevent any further moving up to prevent damage to the mount or the TV&lt;/li&gt;
  &lt;li&gt;Detect motor stalls or obstructions by measuring motor current and stop the motors in such fault conditions&lt;/li&gt;
  &lt;li&gt;Move the mount to the rest position(top-most) automatically, when the TV is turned OFF&lt;/li&gt;
  &lt;li&gt;Similarly, move the mount to the viewing position(bottom-most) automatically, when the TV is turned ON&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;components&quot;&gt;Components&lt;/h3&gt;

&lt;p&gt;Here’s a block diagram of the whole system:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/block_diagram.png&quot; alt=&quot;Block Diagram&quot; class=&quot;media-left&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The two time-of-flight(TOF) distance sensors are &lt;a href=&quot;https://www.st.com/en/imaging-and-photonics-solutions/vl53l0x.html&quot; target=&quot;_blank&quot;&gt;VL53L0x&lt;/a&gt; sensors I bought from &lt;a href=&quot;https://www.amazon.com/HiLetgo-VL53L0X-Distance-Measurement-Breakout/dp/B071DW8M8V/&quot; target=&quot;_blank&quot;&gt;Amazon&lt;/a&gt;. These are pretty accurate from 20mm to 2000mm. These are placed behind the TV on the opposite ends to detect the distance from the wall, as well as the swivel angle.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/motion.png&quot; alt=&quot;TV Mount Image&quot; class=&quot;media-left&quot; /&gt;
&lt;img src=&quot;/assets/images/top_image.png&quot; alt=&quot;TV Mount Image&quot; class=&quot;media-left&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;the-circuit&quot;&gt;The Circuit&lt;/h3&gt;

&lt;p&gt;The circuit is just soldered on two separate prototype PCBs, layered one over another. The top part contains the Arduino and connectors for the sensors. Also has a USB connector for the cable coming from the TV for TV On/Off detection. The bottom part contains the two H-bridges for the two motors in the mount(up/down and swivel). There’s a &lt;a href=&quot;https://www.amazon.com/gp/product/B01MQGMOKI/&quot; target=&quot;_blank&quot;&gt;DC/DC converter&lt;/a&gt; as well, for running the Arduino from the 24V power supply.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/pcb.png&quot; alt=&quot;TV Mount Image&quot; class=&quot;media-left&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Fits nearly perfectly in this &lt;a href=&quot;https://www.amazon.com/gp/product/B08PZCC562/&quot; target=&quot;_blank&quot;&gt;enclosure&lt;/a&gt; built for Raspberry PI:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/assembled.png&quot; alt=&quot;TV Mount Image&quot; class=&quot;media-left&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;the-code&quot;&gt;The Code&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/shadabahmed/smarter_tv_mount&quot; target=&quot;_blank&quot;&gt;Github Repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The code is written in C++ using the Arduino framework. I initially started coding in Arduino IDE but as the code got bigger, switched over to the Jetbrains CLion using the Platform IO framework. I must say that CLion is so much better to write code in!&lt;/p&gt;

&lt;p&gt;The main part of the code is a state machine, that manages the various states and transitions based on the inputs from the remote/sensors.&lt;/p&gt;

&lt;p&gt;As a side challenge, I also ported the code to an almost pin-compatible &lt;a href=&quot;https://docs.arduino.cc/hardware/nano-rp2040-connect&quot; target=&quot;_blank&quot;&gt;Arduino Nano RP2040&lt;/a&gt;, which is based on the &lt;a href=&quot;https://www.raspberrypi.com/products/raspberry-pi-pico/&quot; target=&quot;_blank&quot;&gt;Raspberry Pi Pico&lt;/a&gt; microcontroller.&lt;/p&gt;

&lt;h3 id=&quot;final-setup&quot;&gt;Final Setup&lt;/h3&gt;

&lt;p&gt;Right now, I crammed the circuit, power supply etc in a cable box. I do plan to make it neater. Videos(5x speed) of the whole setup with TV On/Off function:&lt;/p&gt;

&lt;div class=&quot;vid-container row media-left&quot;&gt;
  &lt;div class=&quot;vid-border col-xs-6 nopadding&quot;&gt;
    &lt;img src=&quot;/assets/images/tv_on.png&quot; /&gt;
      &lt;details&gt;
      &lt;summary role=&quot;button&quot; aria-label=&quot;static image&quot; class=&quot;gif-player&quot;&gt;
        &lt;img class=&quot;button play&quot; src=&quot;/assets/images/play_circle_filled-24px.svg&quot; /&gt;
        &lt;img class=&quot;button pause&quot; src=&quot;/assets/images/pause_circle_filled-24px.svg&quot; /&gt;
        &lt;img src=&quot;/assets/images/tv_on.jpg&quot; class=&quot;thumb&quot; loading=&quot;lazy&quot; /&gt;
        &lt;img src=&quot;/assets/images/tv_on.gif&quot; class=&quot;gif&quot; /&gt;
      &lt;/summary&gt;        
    &lt;/details&gt;  
  &lt;/div&gt;
  &lt;div class=&quot;vid-border col-xs-6 nopadding&quot;&gt;
    &lt;img src=&quot;/assets/images/tv_off.png&quot; /&gt;
    &lt;details&gt;
      &lt;summary role=&quot;button&quot; aria-label=&quot;static image&quot; class=&quot;gif-player&quot;&gt;
        &lt;img class=&quot;button play&quot; src=&quot;/assets/images/play_circle_filled-24px.svg&quot; /&gt;
        &lt;img class=&quot;button pause&quot; src=&quot;/assets/images/pause_circle_filled-24px.svg&quot; /&gt;
        &lt;img src=&quot;/assets/images/tv_off.jpg&quot; class=&quot;thumb&quot; loading=&quot;lazy&quot; /&gt;
        &lt;img src=&quot;/assets/images/tv_off.gif&quot; class=&quot;gif&quot; /&gt;
      &lt;/summary&gt;        
    &lt;/details&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;This has been a fun little project to do, and pretty useful as well. I last coded on a microcontroller (AVR Atmega series) in 2008, and it was all on custom-manufactured circuit boards. Comparing that to now, here’s what I observed:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;There are many microcontrollers available today with a host of connectivity options like LoRa, Wifi, Bluetooth etc.&lt;/li&gt;
  &lt;li&gt;You can buy fully assembled breadboard-ready microcontroller boards for just a few dollars&lt;/li&gt;
  &lt;li&gt;The diversity in the microcontroller choice is also supplemented by a good set of frameworks like Arduino, Platform IO etc. Not too hard to write portable code without a lot of changes like I did with Arduino Nano RP2040&lt;/li&gt;
  &lt;li&gt;You can virtually find any sensor on Amazon, Sparkfun, AdaFruit or many other sites.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall so much easier to do your hobby projects today. I too hope to pick up a few other cool projects as well. Will keep you posted. Cheers !!!!ß&lt;/p&gt;
</description>
				<pubDate>Tue, 28 Jun 2022 00:00:00 +0000</pubDate>
				<link>/2022/06/28/smarter-tv-mount</link>
				<guid isPermaLink="true">/2022/06/28/smarter-tv-mount</guid>
			</item>
		
			<item>
				<title>Single Value Tree</title>
				<description>
&lt;p&gt;Another popular tree question:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Given a binary tree, count the number of unival subtrees(all nodes having the same value).
For e.g. in the tree below, all the subtrees enclosed in ellipses are unival trees.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img width=&quot;400&quot; alt=&quot;unival_tree&quot; src=&quot;/assets/images/unival_tree.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Above tree was generated using the &lt;a href=&quot;https://github.com/glejeune/Ruby-Graphviz&quot;&gt;graphviz&lt;/a&gt; library. The result for the tree above would be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;6&lt;/code&gt;. There is a &lt;a href=&quot;https://crazycoderzz.wordpress.com/count-the-number-of-unival-subtrees-in-a-binary-tree/&quot;&gt;C++ implementation&lt;/a&gt; around. The time complexity is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;O(n)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The ruby implementation looks a lot simpler owing to the fact that it can return multiple values. Here it is:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# let&apos;s quickly create a tree&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# this function returns true if:&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# a. child is nil&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# b. child is not nil and it has same value as parent plus it&apos;s subtree is a unival until the child&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;is_unival?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_child_unival&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;is_child_unival&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;nil?&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;unival_subtrees&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# if node is nil, the subtree count is obviously 0 and it is unival&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;nil?&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;is_left_unival&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;left_count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unival_subtrees&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;is_right_unival&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;right_count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unival_subtrees&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# check is left and right subtrees are unival and the current node and children have same values&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_unival?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_left_unival&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
     &lt;span class=&quot;n&quot;&gt;is_unival?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_right_unival&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Add one more subtree which includes current node to the total count&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;left_count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;right_count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;left_count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;right_count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# test by calling the unival_subtrees method&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;unival_subtrees&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This was a fun question to solve. Let me know your thoughts in comments. Cheers!!!&lt;/p&gt;
</description>
				<pubDate>Thu, 30 Nov 2017 00:00:00 +0000</pubDate>
				<link>/2017/11/30/single-value-tree</link>
				<guid isPermaLink="true">/2017/11/30/single-value-tree</guid>
			</item>
		
			<item>
				<title>BST Inorder Sucessor</title>
				<description>
&lt;p&gt;Getting back to blogging after a long time. Whatever be the reasons, just want to share a quick insight I had yesterday.&lt;/p&gt;

&lt;p&gt;Finding an in-order successor to a BST node is a pretty popular problem. While trying to think of it, I realized I could create a more elegant solution than what I could find online. I don’t know if similar solutions exist but here is a ruby implementation anyway (explanation within the comments):&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# let&apos;s quickly create a tree&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Struct&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# finding min in a tree, simple to do&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;find_min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;nil?&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;nil?&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;find_min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;find_successor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;possible_successor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;nil?&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;right&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# if found and node has right, then successor is min in right&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;find_min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;elsif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;val&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# if found and node has no right, then it is one of the ancestors&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;possible_successor&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;elsif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;val&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# if the value is on the left subtree,&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# then current node is possible successor.&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# Pass it as possible_successor&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;find_successor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# if the value is on the right subtree,&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# then current node can&apos;t be possible successor.&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# Pass along ancestor which could be successor&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;find_successor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;possible_successor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# test by calling find_successor method&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;find_successor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;val&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I’ll be more frequent with new posts now. I promise :)&lt;/p&gt;
</description>
				<pubDate>Wed, 18 Oct 2017 00:00:00 +0000</pubDate>
				<link>/2017/10/18/bst-inorder-sucessor</link>
				<guid isPermaLink="true">/2017/10/18/bst-inorder-sucessor</guid>
			</item>
		
			<item>
				<title>Mysterious Killer of my Processes</title>
				<description>
&lt;p&gt;Recently I had deployed my node app on one of the overloaded linux servers, I was using. It uses &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cluster&lt;/code&gt; node library, which also sends me notification if any child process is killed and then it respawns the child.&lt;/p&gt;

&lt;p&gt;So ever since deployment, everyday around lunch, I would get a hella-lot of emails about the child processes being killed. The weird thing was that every one of the child process were receiving &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SIGKILL&lt;/code&gt;, thus someone was killing them.
During the carnage which would last for around 2-3 hours, even processes such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;npm install&lt;/code&gt; would be killed, just as mercilessly.&lt;/p&gt;

&lt;p&gt;Shutting down a few processes did help. It slowed down the killing, but did not stop it completely. Only passing of time would stop it, so by late evening till next day lunch, the carnage was again silent.&lt;/p&gt;

&lt;p&gt;So next day, I figured out what other thing was happening at the same time. It turns out that another team was uploading a huge data which also involved lots of processing and thus system was becoming &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OOM&lt;/code&gt; (Out of Memory) and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OOM Killer&lt;/code&gt; was killing my processes. Looking at the mem stats:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;free -m
             total       used       free     shared    buffers     cached
Mem:          2008       1995         13          0          0         23
-/+ buffers/cache:       1971         36
Swap:         1535       1535          0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This server was super-contrained for memory and the kernel &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OOM Killer&lt;/code&gt; kicked in to reclaim memory. Obviously not ideal amount of &lt;strong&gt;RAM&lt;/strong&gt; and even worse &lt;strong&gt;SWAP&lt;/strong&gt; space but this was a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sandbox&lt;/code&gt; server, so a bit of unsettleness dint matter so much. Looking at more logs for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;oom killer&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;grep -i &apos;kill&apos; /var/log/messages | awk -F &apos;kernel:&apos; &apos;{print $2}&apos;
 [1776235.313736] PassengerHel/ei invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0
 [1776235.313791]  [&amp;lt;ffffffff810b8dec&amp;gt;] oom_kill_process+0xcc/0x2f0
 [1776235.322903] Out of memory: kill process 12050 (ruby) score 113591 or a child
 [1776235.322906] Killed process 12050 (ruby)
 [1776766.287970] python invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0
 [1776766.288033]  [&amp;lt;ffffffff810b8dec&amp;gt;] oom_kill_process+0xcc/0x2f0
 [1776766.298348] Out of memory: kill process 12121 (ruby) score 112262 or a child
 [1776766.298350] Killed process 12121 (ruby)
 [1776766.304348] python invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0
 [1776766.304389]  [&amp;lt;ffffffff810b8dec&amp;gt;] oom_kill_process+0xcc/0x2f0
 [1776766.313545] Out of memory: kill process 8259 (python) score 85423 or a child
 [1776766.313548] Killed process 8259 (python)
 ...truncated
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As sou can see, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OOM Killer&lt;/code&gt; killed a number of processes. The best way to resolve this &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OOM Killing&lt;/code&gt;, is to add more &lt;strong&gt;RAM&lt;/strong&gt; and &lt;strong&gt;SWAP&lt;/strong&gt; space. You can see more helpful reference for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OOM Killer&lt;/code&gt; here:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.oracle.com/technetwork/articles/servers-storage-dev/oom-killer-1911807.html&quot;&gt;oom-killer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://unix.stackexchange.com/questions/136291/will-linux-start-killing-my-processes-without-asking-me-if-memory-gets-short&quot;&gt;will-linux-start-killing-my-processes-without-asking-me-if-memory-gets-short&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://unix.stackexchange.com/questions/10077/where-can-i-see-a-list-of-kernel-killed-processes&quot;&gt;where-can-i-see-a-list-of-kernel-killed-processes&lt;/a&gt;&lt;/p&gt;
</description>
				<pubDate>Thu, 21 May 2015 00:00:00 +0000</pubDate>
				<link>/2015/05/21/mysterious-killer-of-my-processes</link>
				<guid isPermaLink="true">/2015/05/21/mysterious-killer-of-my-processes</guid>
			</item>
		
			<item>
				<title>Integrating Slack With Github Enterprise</title>
				<description>
&lt;p&gt;If you are using &lt;strong&gt;Slack&lt;/strong&gt;(Yes it’s awesome) and &lt;strong&gt;Github Enterprise&lt;/strong&gt;(Awesome too), then you might have played around with the integration of both the tools.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://slack.zendesk.com/hc/en-us/articles/201710957-Using-the-GitHub-integration-with-GitHub-Enterprise&quot;&gt;Slack documentation&lt;/a&gt; helps a bit but to have a complete integration with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;issues&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;issues comments&lt;/code&gt; etc, you’ll have to jump through some hoops. So let me put it all below.&lt;/p&gt;

&lt;h3 id=&quot;adding-webhook-in-github-enterprise-for-your-slack-groupchannel&quot;&gt;Adding Webhook in &lt;strong&gt;Github Enterprise&lt;/strong&gt; for your &lt;strong&gt;Slack&lt;/strong&gt; group/channel&lt;/h3&gt;

&lt;p&gt;First step is to obviously add a hook in your company’s &lt;strong&gt;Github Enterprise&lt;/strong&gt; repo for &lt;strong&gt;Slack&lt;/strong&gt;. Skip to &lt;a href=&quot;#update-webhook&quot;&gt;next section&lt;/a&gt; if you’ve already addded the &lt;strong&gt;Github Webhook&lt;/strong&gt;.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Click on the &lt;strong&gt;Add Service Integration&lt;/strong&gt; menu link for your group&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Select your &lt;strong&gt;Slack&lt;/strong&gt; group or channel where you want the &lt;strong&gt;Github&lt;/strong&gt; notifications:&lt;/p&gt;

    &lt;p&gt;&lt;img src=&quot;/assets/media/github-select-group.png&quot; alt=&quot;Github Channel&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Now click on the &lt;strong&gt;switch to unauthed mode&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;&lt;img src=&quot;/assets/media/github-unauth-mode.png&quot; alt=&quot;Github Channel&quot; /&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Copy the &lt;strong&gt;Webhook URL&lt;/strong&gt; you see on the next screen. Now goto the &lt;strong&gt;Settings&lt;/strong&gt; &amp;gt; &lt;strong&gt;Hooks&lt;/strong&gt; page of your repo in Github Enterprise. Add a &lt;strong&gt;Webhook&lt;/strong&gt; and paste the Webhook URL there.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After adding the &lt;strong&gt;Webhook&lt;/strong&gt; you should receive notifications when anyone pushes commits to your repo.&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;update-webhook&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;updating-webhook-in-github-enterprise-to-support-more-notifications&quot;&gt;Updating Webhook in &lt;strong&gt;Github Enterprise&lt;/strong&gt; to support more notifications&lt;/h3&gt;

&lt;p&gt;Now you may have noticed that even after adding a &lt;strong&gt;Webhook&lt;/strong&gt;, you can only see notifications for new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;commits&lt;/code&gt;. The integration is still missing notifications for events such a new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;issue&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;issue comment&lt;/code&gt; etc.&lt;/p&gt;

&lt;p&gt;The reason is that Webhook only publishes commit events by default. You can change this behaviour by altering the hook via &lt;a href=&quot;https://developer.github.com/webhooks/&quot;&gt;Github Webhook API&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Assuming your &lt;strong&gt;Github Enterprise&lt;/strong&gt; link as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://githuben.mycompany.com/&lt;/code&gt;, your organization as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;myorg&lt;/code&gt; and repo as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;myrepo&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;1 . Find your hook url (containing the hook id) by retrieving a list all the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hooks&lt;/code&gt; for a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;repo&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl --user &quot;&amp;lt;User&amp;gt;:&amp;lt;Password&amp;gt;&quot; http://githuben.mycompany.com/api/v3/repos/myorg/myrepo/hooks
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You should see a big &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JSON&lt;/code&gt; output. All you need is the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;url&lt;/code&gt; of the hook matching your &lt;strong&gt;Slack Webhook&lt;/strong&gt; integration url.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; [
    {
      &quot;url&quot;: &quot;http://githuben.mycompany.com/api/v3/repos/myorg/myrepo/hooks/1121&quot;,
      &quot;test_url&quot;: &quot;http://githuben.mycompany.com/api/v3/repos/myorg/myrepo/hooks/1121/test&quot;,
      &quot;id&quot;: 1121,
      &quot;name&quot;: &quot;web&quot;,
      &quot;active&quot;: true,
      &quot;events&quot;: [
        &quot;push&quot;
      ],
      ....
      &quot;config&quot;: {
            &quot;url&quot;: &quot;https://hooks.slack.com/services/SOMEHASH/SOMEHASH/SOMEHASHBUTLONGER&quot;,
            &quot;content_type&quot;: &quot;form&quot;,
            &quot;insecure_ssl&quot;: &quot;1&quot;
          },
      ....
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can see in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JSON&lt;/code&gt; aboce, that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;events&lt;/code&gt; in the hook is only &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;push&lt;/code&gt;. The url for our &lt;strong&gt;Slack&lt;/strong&gt; hook is - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://githuben.mycompany.com/api/v3/repos/myorg/myrepo/hooks/1121&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;2 . Now add all the extra notifications to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;events&lt;/code&gt; for the &lt;strong&gt;Webhook&lt;/strong&gt; using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hook url&lt;/code&gt; from above:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -X PATCH --user &quot;&amp;lt;User&amp;gt;:&amp;lt;Password&amp;gt;&quot;  -H &quot;Content-Type: application/json&quot;
http://githuben.mycompany.com/api/v3/repos/myorg/myrepo/hooks/1121
-d &apos;{&quot;add_events&quot;: [&quot;commit_comment&quot;, &quot;create&quot;, &quot;issue_comment&quot;, &quot;issues&quot;, &quot;pull_request_review_comment&quot;]}&apos;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That’s all. You should now be able to receive notifications for all these events apart from push. You can call the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Get Hooks&lt;/code&gt; api again to confirm.&lt;/p&gt;
</description>
				<pubDate>Fri, 06 Mar 2015 00:00:00 +0000</pubDate>
				<link>/git/2015/03/06/integrating-slack-with-github-enterprise</link>
				<guid isPermaLink="true">/git/2015/03/06/integrating-slack-with-github-enterprise</guid>
			</item>
		
			<item>
				<title>Inside Git Guts</title>
				<description>
&lt;p&gt;&lt;strong&gt;TLDR;&lt;/strong&gt; Git is greatly extensible. I made many custom commands to create an interesting talk on “The Insides of Git”. Skip the text and just watch the video for details.&lt;/p&gt;

&lt;p&gt;Back in June last year in the cool city of &lt;a href=&quot;http://en.wikipedia.org/wiki/Pune&quot;&gt;Pune&lt;/a&gt; at the RubyConf India 2013, I gave a talk on Git. It was aptly titled &lt;strong&gt;Inside Git Guts with Ruby&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The idea was to explore what happens inside the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.git&lt;/code&gt; folder when you do git operations like &lt;em&gt;commit, push, merge&lt;/em&gt; etc. The talk was far more about &lt;strong&gt;&lt;em&gt;git&lt;/em&gt;&lt;/strong&gt; than &lt;strong&gt;&lt;em&gt;ruby&lt;/em&gt;&lt;/strong&gt;. Infact, the part &lt;strong&gt;with Ruby&lt;/strong&gt; in the title was added just to ensure a better chance of my proposal getting selected for RubyConf. Although, all of the tools I showed in the talk were written in Ruby, the actual ruby code shown was just about 4 lines.&lt;/p&gt;

&lt;p&gt;Now, here’s the actual talk:&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;//www.youtube.com/embed/lPlwkxrG2NM&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;The talk was greatly inspired by the movie &lt;a href=&quot;http://www.imdb.com/title/tt1375666/combined&quot;&gt;Inception&lt;/a&gt;. Infact I even had a command &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git inception&lt;/code&gt; which gave the following output(truncated):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ git inception                                           
                        .git
                     .git
                  .git
               .git
            .git
         .git
      .git
   .git &amp;lt;--- 2nd Level Gitception
.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;strong&gt;Inception&lt;/strong&gt; bit was actually the most interesting part of the talk. There were other super cool commands like - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git music&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git autocommit&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git server&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git fireworks&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git quote&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;git about&lt;/code&gt; and more&lt;/p&gt;

&lt;p&gt;Lots of folks have asked me to share the code and the instructions, so here’s the &lt;a href=&quot;https://github.com/shadabahmed/git_guts&quot;&gt;code&lt;/a&gt;. To get all the tools on your system:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;gem install git_guts
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
				<pubDate>Tue, 18 Mar 2014 00:00:00 +0000</pubDate>
				<link>/blog/2014/03/18/inside-git-guts</link>
				<guid isPermaLink="true">/blog/2014/03/18/inside-git-guts</guid>
			</item>
		
			<item>
				<title>Bang Bang !!</title>
				<description>
&lt;p&gt;The more you learn about the linux shell, the more you love it. Reason I am saying this because I recently saw this:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/JTMlx.png&quot; alt=&quot;sudo !!&quot; style=&quot;width:299px&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This made me immediately google it and I found an excellent reference &lt;a href=&quot;http://craig-russell.co.uk/2011/09/28/bang-bang-command-recall-in-linux.html#.Ug0fy2QS2a4&quot;&gt;here&lt;/a&gt;. 
This is a quick summary of the source:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ !!                     # Repeat last command
$ !x                     # Repeat last command that started with x
$ !?x                    # Repeat last command that has the substring x
$ !10                    # Repeat 10th command in the history file
$ !-10                   # Repeat 10th from last command in the history file
$ !!*                    # Fetch parameters from last command
$ !!^                    # Fetch first parameter from last command
$ !!$                    # Fetch last parameter from last command
$ !!3                    # Fetch third parameter from last command
$ !!:s/foo/bar/          # Repeat last command substituting foo for bar
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you append &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;:p&lt;/code&gt; to any of the above commands then it will only print the command than running it&lt;/p&gt;

&lt;h2 id=&quot;infinite-bang-bang&quot;&gt;Infinite Bang Bang&lt;/h2&gt;

&lt;p&gt;Now what if the last command also contains a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!!&lt;/code&gt;. Would it become recursive ? Let’s see:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# : is noop operator. This command sets up our base. 
# Note that the !! inside single quote doesn&apos;t expand to the previous command
$ : &apos;!!&apos;
  
# Let&apos;s start our recursive operation in here. This is the first sequence in the chain
# Only the !! inside double quotes expands to the previous command - : &apos;!!&apos;
$ : &quot;!!&quot; &apos;!!&apos;

: &quot;: &apos;!!&apos;&quot; &apos;!!&apos;

# Pressing up arrow, we have a second sequence
# Once again, only !! inside double quotes expands and !! appears 3 times after expansion
$ : &quot;: &apos;!!&apos;&quot; &apos;!!&apos;

: &quot;: &apos;: &quot;: &apos;!!&apos;&quot; &apos;!!&apos;&apos;&quot; &apos;!!&apos;

# Now, third sequence - !! appears 5 times
$ : &quot;: &apos;: &quot;: &apos;!!&apos;&quot; &apos;!!&apos;&apos;&quot; &apos;!!&apos;

: &quot;: &apos;: &quot;: &apos;!!&apos;&quot; &apos;: &quot;: &apos;: &quot;: &apos;!!&apos;&quot; &apos;!!&apos;&apos;&quot; &apos;!!&apos;&apos;&apos;&quot; &apos;!!&apos;

# Fourth Sequence - !! appears 17 times
$ : &quot;: &apos;: &quot;: &apos;!!&apos;&quot; &apos;: &quot;: &apos;: &quot;: &apos;!!&apos;&quot; &apos;!!&apos;&apos;&quot; &apos;!!&apos;&apos;&apos;&quot; &apos;!!&apos;

: &quot;: &apos;: &quot;: &apos;!!&apos;&quot; &apos;: &quot;: &apos;: &quot;: &apos;: &quot;: &apos;: &quot;: &apos;!!&apos;&quot; &apos;: &quot;: &apos;: &quot;: &apos;!!&apos;&quot; &apos;!!&apos;&apos;&quot; &apos;!!&apos;&apos;&apos;&quot; &apos;!!&apos;&apos;&quot; &apos;: &quot;: &apos;: &quot;: &apos;!!&apos;&quot; &apos;: &quot;: &apos;: &quot;: &apos;!!&apos;&quot; &apos;!!&apos;&apos;&quot; &apos;!!&apos;&apos;&apos;&quot; &apos;!!&apos;&apos;&apos;&quot; &apos;: &quot;: &apos;: &quot;: &apos;!!&apos;&quot; &apos;: &quot;: &apos;: &quot;: &apos;!!&apos;&quot; &apos;!!&apos;&apos;&quot; &apos;!!&apos;&apos;&apos;&quot; &apos;!!&apos;&apos;&apos;&apos;&quot; &apos;!!&apos;

# Fifth
$ : &quot;: &apos;: &quot;: &apos;!!&apos;&quot; &apos;: &quot;: &apos;: &quot;: &apos;: &quot;: &apos;: &quot;: &apos;!!&apos;&quot; &apos;: &quot;: &apos;: &quot;: &apos;!!&apos;&quot; &apos;!!&apos;&apos;&quot; &apos;!!&apos;&apos;&apos;&quot; &apos;!!&apos;&apos;&quot; &apos;: &quot;: &apos;: &quot;: &apos;!!&apos;&quot; &apos;: &quot;: &apos;: &quot;: &apos;!!&apos;&quot; &apos;!!&apos;&apos;&quot; &apos;!!&apos;&apos;&apos;&quot; &apos;!!&apos;&apos;&apos;&quot; &apos;: &quot;: &apos;: &quot;: &apos;!!&apos;&quot; &apos;: &quot;: &apos;: &quot;: &apos;!!&apos;&quot; &apos;!!&apos;&apos;&quot; &apos;!!&apos;&apos;&apos;&quot; &apos;!!&apos;&apos;&apos;&apos;&quot; &apos;!!&apos;

: &quot;: &apos;: &quot;: &apos;!!&apos;&quot; &apos;: &quot;: &apos;: &quot;: &apos;: &quot;: &apos;: &quot;: &apos;!!&apos;&quot; &apos;: &quot;: &apos;: &quot;: &apos;: &quot;: &apos;: &quot;: &apos;!!&apos;&quot; &apos;: &quot;: &apos;: &quot;: &apos;: &quot;: &apos;
... # !! appears 161 times
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In the sixth sequence &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!!&lt;/code&gt; appears &lt;strong&gt;15681&lt;/strong&gt; times and in the seventh, more than &lt;strong&gt;150 million&lt;/strong&gt; times. Do not even try to run it for the 7th iteration unless you want to end up with a 2GB history file and your shell stuck for hours at 100% CPU.&lt;/p&gt;

&lt;p&gt;The 8th sequence has more than &lt;strong&gt;16 Quadrillion&lt;/strong&gt; bang bangs&lt;/p&gt;

&lt;p&gt;Now, I haven’t been able to figure out the exact equation yet for the number of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!!&lt;/code&gt; in nth sequence,  but this is what happens:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Any &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!!&lt;/code&gt; not surrounded by any quotes is expanded to the previous command&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!!&lt;/code&gt; surrounded only by single quotes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&apos;!!&apos;&lt;/code&gt; do not expand&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!!&lt;/code&gt; surrounded by double quotes at the outermost level are expanded, even if that bang bang  is nested inside single quotes. For e.g. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot; &apos;!!&apos; &quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The approximate equation is like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;f(n) ~ f(n-1)*f(n-1)/2 + f(n-1)/2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let me know if you can figure out the exact equation. The above commands have been tested on sh and bash.&lt;/p&gt;

&lt;p&gt;Update: Thanks to &lt;a href=&quot;https://github.com/vog&quot;&gt;Volker&lt;/a&gt;, we have code to calculate the exact number of bang bangs in nth sequence, &lt;a href=&quot;https://github.com/vog/bangbang&quot;&gt;here&lt;/a&gt;, which works till the 7th sequence.&lt;/p&gt;

&lt;p&gt;Volker has even submitted the &lt;strong&gt;Bang Bang Numbers&lt;/strong&gt; at &lt;a href=&quot;http://en.wikipedia.org/wiki/On-Line_Encyclopedia_of_Integer_Sequences&quot;&gt;OEIS&lt;/a&gt; and the sequence has been accepted. View it over &lt;a href=&quot;https://oeis.org/A228162&quot;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Update2: &lt;a href=&quot;https://github.com/robinhouston&quot;&gt;Robin Houston&lt;/a&gt; wrote an analysis of these numbers on his &lt;a href=&quot;http://bosker.wordpress.com/2013/08/16/using-group-theory-to-understand-unix-command-substitution/&quot;&gt;blog&lt;/a&gt;. He also wrote this code for generating the numbers in the &lt;strong&gt;Bang Bang Numbers&lt;/strong&gt; series:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# /usr/bin/env python
p, q = 2, 4
for i in range(4, 16):
  print &quot;%d: %d&quot; % (i, 4*p + 2*q + 1)
  p,q = 3*p*p + 2*p + p*q, 2*q + 2*p*p + 2*p*q 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
				<pubDate>Fri, 16 Aug 2013 00:00:00 +0000</pubDate>
				<link>/blog/2013/08/16/bang-bang</link>
				<guid isPermaLink="true">/blog/2013/08/16/bang-bang</guid>
			</item>
		
			<item>
				<title>Split Tunneling on VPN via Routing Table</title>
				<description>
&lt;h3 id=&quot;split-tunneling&quot;&gt;Split Tunneling&lt;/h3&gt;

&lt;p&gt;Whenever I connect to VPN on my mac, my default route is modified to this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ netstat -nr
Routing tables

Internet:
Destination        Gateway            Flags        Refs      Use   Netif Expire
default            utun1              UCS            34        0   utun1 
default            192.168.2.1        UGScI           0        0     en0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;What this does is, route all my traffic, even the one which is outside of VPN network routed through the VPN interface &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;utun1&lt;/code&gt;. The second default route via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;192.168.1.1&lt;/code&gt; is not even used. This is unnecessary and sometimes counterproductive as the VPN network takes extra load on bandwidth/resources for the IPs outside of its network and even bans sites which do not require banning.&lt;/p&gt;

&lt;p&gt;You can easily change your  routing table to circumvent this using the script below. This way you access public IPs directly and private IPs over VPN.  This concept is called &lt;a href=&quot;http://en.wikipedia.org/wiki/Split_tunneling&quot;&gt;Split Tunneling&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;modifying-routing-table&quot;&gt;Modifying Routing Table&lt;/h3&gt;

&lt;p&gt;Now to modify routing table for split tunneling, all you need to do is to find out the subnet of the IPs in your VPN you need access to. Let’t take for example, if the subnets of my VPN private space are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;10.109.0.0&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;10.110.0.0&lt;/code&gt; (Any IPs starting with 10.109 and 10.110):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;#! /usr/bin/env bash
if (( EUID != 0 )); then
  echo &quot;Please, run this command with sudo&quot; 1&amp;gt;&amp;amp;2
  exit 1
fi
WIRELESS_INTERFACE=en0
TUNNEL_INTERFACE=utun0
GATEWAY=$(netstat -nrf inet | grep default | grep $WIRELESS_INTERFACE | awk &apos;{print $2}&apos;)

echo &quot;Resetting routes with gateway =&amp;gt; $GATEWAY&quot;
echo
route -n delete default -ifscope $WIRELESS_INTERFACE
route -n delete -net default -interface $TUNNEL_INTERFACE
route -n add -net default $GATEWAY
for subnet in  10.109 10.110
do
  route -n add -net $subnet -interface $TUNNEL_INTERFACE
done
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Just save the script as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/bin/vpn&lt;/code&gt; and whenever you connect to vpn, just run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo vpn&lt;/code&gt;. This  is what the script does:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Finds wireless router &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IP (en0)&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Remove the default routes set by VPN&lt;/li&gt;
  &lt;li&gt;Set the IP found for en0 as the default gateway&lt;/li&gt;
  &lt;li&gt;Add the specific routes for your VPN subnet&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are connecting over wired network, just change the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;en0&lt;/code&gt; in script to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;en1&lt;/code&gt;. Don’t change your VPN DNS to make sure you can resolve private domains on the VPN.&lt;/p&gt;

&lt;p&gt;Looking at the routing table again after running the script:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ netstat -nr
Routing tables

Internet:
Destination        Gateway            Flags        Refs      Use   Netif Expire
default            192.168.2.1        UGSc            1        0     en0
...
10.109                 utun1              USc            0        0   utun1
10.110                 utun1              USc            0        0   utun1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see now, our default gate is back to wifi router IP - &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;192.168.1.1 on en0&lt;/code&gt; and there are some routes for the subnets inside the VPN.&lt;/p&gt;

&lt;p&gt;You can test the route as well with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;route&lt;/code&gt; command. Route for any IP outside of your VPN:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ route get google.com                                            
route to: lga15s29-in-f5.1e100.net
destination: default
   mask: default
   gateway: 192.168.1.1
   interface: en0
   flags: &amp;lt;UP,GATEWAY,DONE,STATIC,PRCLONING&amp;gt;
   recvpipe  sendpipe  ssthresh  rtt,msec    rttvar  hopcount      mtu     expire
            0         0         0         0         0         0      1500         0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Route for IP inside your VPN:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ route get 10.109.10.135
route to: 10.109.10.135
destination: 156.107.0.0
   mask: 255.255.0.0
   interface: utun0
   flags: &amp;lt;UP,GATEWAY,DONE,STATIC,PRCLONING&amp;gt;
   recvpipe  sendpipe  ssthresh  rtt,msec    rttvar  hopcount      mtu     expire
            0         0         0         0         0         0      1280         0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To reset the routing table back, just disconnect from the VPN. Same script can be used on Linux with some modifications.&lt;/p&gt;
</description>
				<pubDate>Sun, 11 Aug 2013 00:00:00 +0000</pubDate>
				<link>/blog/2013/08/11/split-tunneling-vpn-routing-table</link>
				<guid isPermaLink="true">/blog/2013/08/11/split-tunneling-vpn-routing-table</guid>
			</item>
		
			<item>
				<title>Logstasher - For awesome Rails logging</title>
				<description>
&lt;h2 id=&quot;rails-logs&quot;&gt;Rails Logs&lt;/h2&gt;

&lt;p&gt;Rails logging is a mess, atleast the &lt;strong&gt;&lt;em&gt;default&lt;/em&gt;&lt;/strong&gt; one. I’ve even seen some gems, spewing garbage into the logfile with no predefined format. Good thing is that you can easily fix/customize it. Infact, you can customize it so much, that you can have this:&lt;/p&gt;

&lt;p&gt;&lt;img class=&quot;magnifier&quot; src=&quot;http://i.imgur.com/zZXWQNp.png&quot; title=&quot;Awesome Rails Logs&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;whats-there-in-these-supposedly-awesome-logs-&quot;&gt;What’s there in these supposedly &lt;em&gt;awesome&lt;/em&gt; logs ?&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Superfast search backend&lt;/li&gt;
  &lt;li&gt;UI is much much cooler than, what the single screenshot shows&lt;/li&gt;
  &lt;li&gt;You can add custom fields such as username and custom rails instrumentations&lt;/li&gt;
  &lt;li&gt;Consolidation of logs across multiple servers&lt;/li&gt;
  &lt;li&gt;Email notifications on events such as exceptions&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;how-its-done-&quot;&gt;How it’s done ?&lt;/h2&gt;

&lt;p&gt;The slick UI with superfast search is made possible with Rails Logs using:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/shadabahmed/logstasher&quot;&gt;Logstasher Gem&lt;/a&gt; - A rails gem I wrote. It makes rails, generate &lt;a href=&quot;http://logstash.net/&quot;&gt;logstash&lt;/a&gt; compatible logs with minimal overhead&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://logstash.net/&quot;&gt;Logstash&lt;/a&gt; - An open source log collector&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://kibana.org/&quot;&gt;Kibana&lt;/a&gt; - A ruby/rack application for visualization and searching the logstash index&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;logstasher-gem&quot;&gt;Logstasher Gem&lt;/h2&gt;

&lt;p&gt;I have already written much about it on the &lt;a href=&quot;https://github.com/shadabahmed/logstasher&quot;&gt;README at Github&lt;/a&gt;. Please check it out to know the usage/installation&lt;/p&gt;

&lt;h2 id=&quot;logstash&quot;&gt;Logstash&lt;/h2&gt;

&lt;p&gt;Now this is the core of the logging system. It collects and stores the logs. It has a very clean seperation of concerns, basically:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Inputs&lt;/strong&gt; - The source for logs. There are tons of options for input sources. We’ll be using &lt;a href=&quot;http://logstash.net/docs/1.1.10/inputs/file&quot;&gt;file input&lt;/a&gt; for local logs and &lt;a href=&quot;http://logstash.net/docs/1.1.10/inputs/lumberjack&quot;&gt;lumberjack&lt;/a&gt; for remote logs.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Filters&lt;/strong&gt; - These are tranformations you would like to apply on the input log. Used for sanitizing and appending any extra information. Since logstasher already sends sanitized logs, we’ll not need any filters, thus saving on some processing.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Ouputs&lt;/strong&gt; - Again we have many options for outputs. We will use the email and elastic-search output.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See the full list of input, filter and output options &lt;a href=&quot;http://logstash.net/docs/1.1.10/&quot;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h4 id=&quot;setting-up-logstash&quot;&gt;Setting up logstash&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;You can compile the jar from &lt;a href=&quot;https://github.com/logstash/logstash&quot;&gt;source code&lt;/a&gt; or &lt;a href=&quot;https://logstash.objects.dreamhost.com/release/logstash-1.1.10-flatjar.jar&quot;&gt;download it&lt;/a&gt;. My preference is to compile, since it is newer (more fixes). Copy the jar file to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/opt/logstash/logstash.jar&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Set it up as a service - &lt;a href=&quot;https://gist.github.com/shadabahmed/5486949&quot;&gt;Ubuntu  and SUSE SLES init.d scripts&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Setup your config file - See &lt;a href=&quot;https://gist.github.com/shadabahmed/5486949#file-logstash-conf&quot;&gt;sample config file&lt;/a&gt;. Copy it to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/logstash/logstash.conf&lt;/code&gt;. The email output functionality is not perfect yet. I am waiting still for this &lt;a href=&quot;https://github.com/logstash/logstash/pull/409&quot;&gt;pull request&lt;/a&gt; to be merged.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once your logstash is setup, you now need to configure input source. If the rails app is on the same machine, you can skip the lumberjack section.&lt;/p&gt;

&lt;p&gt;For output we’re using the embedded elastic-search, so no need for any extra setups.&lt;/p&gt;

&lt;h2 id=&quot;lumberjack&quot;&gt;Lumberjack&lt;/h2&gt;

&lt;p&gt;If your app resides on a remote server, or there are multiple app servers, you need to transport the logs to logstash. Lumberjack is a very fast and small utility to do the same with minimal memory usage. It also encrypts the logs, so super secure as well. It will just monitor your logfile for changes and on  any updates, sends the new logs to logstash.&lt;/p&gt;

&lt;h4 id=&quot;setting-up-lumberjack&quot;&gt;Setting up Lumberjack&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;I found compiling lumberjack to be a bit of pain on SUSE(Yes, unfortunately I have to use SUSE). You can have a go yourself by grabbing it from &lt;a href=&quot;https://github.com/jordansissel/lumberjack&quot;&gt;source&lt;/a&gt;. You will need to install &lt;a href=&quot;http://golang.org/&quot;&gt;Go Language&lt;/a&gt; to compile it. Luckily I found rpm and deb packages &lt;a href=&quot;https://github.com/hectcastro/chef-lumberjack/tree/master/files/default&quot;&gt;here&lt;/a&gt;. Install the deb by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dpkg -i debfilename&lt;/code&gt; or rpm by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rpm -i rpmfilename&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Set it up as a service - &lt;a href=&quot;https://gist.github.com/shadabahmed/5487541&quot;&gt;init.d script&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Set up the config file - &lt;a href=&quot;https://gist.github.com/shadabahmed/5487541#file-lumberjack&quot;&gt;sample config&lt;/a&gt;. Create the config file at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/default/lumberjack&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is a good idea to restart lumberjack when you deploy or rotate logs.&lt;/p&gt;

&lt;p&gt;There is a new protocol for lumberjack v2. I will play with it and update the documentation on that.&lt;/p&gt;

&lt;h4 id=&quot;key-and-ssl-certificate-for-lumberjack&quot;&gt;Key and SSL Certificate for lumberjack&lt;/h4&gt;

&lt;p&gt;You’ll notice that key and certificate files are required by logstash and lumberjack. These are required just to encrypt the log shipping. All the commands I used to generate them are consolidated &lt;a href=&quot;https://gist.github.com/shadabahmed/5487541#file-logstash-cert-sh&quot;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;kibana&quot;&gt;Kibana&lt;/h2&gt;

&lt;p&gt;This is the easiest part. Just see &lt;a href=&quot;http://kibana.org/intro.html&quot;&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you have everything setup, you should be able to see logs in the Kibana UI. Play around to see the powerful search feature. You can also write your custom queries for .e.g. to get all requests from an IP which raised an exception just put this query in the search field - ` @fields.ip:”157.191.96.84” AND @tags:”exception”`&lt;/p&gt;

&lt;h2 id=&quot;inspirations&quot;&gt;Inspirations&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/roidrage/lograge&quot;&gt;https://github.com/roidrage/lograge&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;[http://www.vmdoh.com/blog/centralizing-logs-lumberjack-logstash-and-elasticsearch]
(http://www.vmdoh.com/blog/centralizing-logs-lumberjack-logstash-and-elasticsearch)&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;Loggly.com&quot;&gt;Loggly&lt;/a&gt; and &lt;a href=&quot;logentries.com&quot;&gt;Logentries&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
				<pubDate>Tue, 30 Apr 2013 00:00:00 +0000</pubDate>
				<link>/blog/2013/04/30/logstasher-for-awesome-rails-logging</link>
				<guid isPermaLink="true">/blog/2013/04/30/logstasher-for-awesome-rails-logging</guid>
			</item>
		
	</channel>
</rss>
