<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Joshua Wood</title>
    <description>The latest articles on Forem by Joshua Wood (@wood).</description>
    <link>https://forem.com/wood</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F121656%2Ff3c12eda-9631-40b5-aed1-120306a50c39.png</url>
      <title>Forem: Joshua Wood</title>
      <link>https://forem.com/wood</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/wood"/>
    <language>en</language>
    <item>
      <title>Aggressively part-time</title>
      <dc:creator>Joshua Wood</dc:creator>
      <pubDate>Fri, 31 Mar 2023 02:43:02 +0000</pubDate>
      <link>https://forem.com/wood/aggressively-part-time-3mk2</link>
      <guid>https://forem.com/wood/aggressively-part-time-3mk2</guid>
      <description>&lt;p&gt;I recently used the phrase "aggressively part-time" to describe the culture and work ethic at Honeybadger. We typically work on Honeybadger for 20-30 hours a week. To get things done, we have to be focused and efficient.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This approach allows us to maximize the time we spend on life outside of work.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I've been thinking about applying this concept to the rest of my life. Work is just one area where I desire progress. I want my relationships, interests, and hobbies to improve too.&lt;/p&gt;

&lt;p&gt;In family life, I want to become a better partner to my wife and father to my children and to enjoy meaningful experiences together.&lt;/p&gt;

&lt;p&gt;I want to expand my knowledge and improve my thinking to grow intellectually and solve problems.&lt;/p&gt;

&lt;p&gt;I don't want to &lt;em&gt;have&lt;/em&gt; hobbies—I want to be good at them. I want to develop skill and experience success in each area.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;These areas encompass my life goals.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each area demands focus to improve. But, like work, I can’t pursue everything at once—I need to prioritize.&lt;/p&gt;

&lt;p&gt;Aggressively part-time leaves room for your other endeavors—whatever they may be.&lt;/p&gt;

&lt;p&gt;What are your part-time pursuits? Leave a comment below!&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>career</category>
      <category>honeybadger</category>
    </item>
    <item>
      <title>openpgp proof</title>
      <dc:creator>Joshua Wood</dc:creator>
      <pubDate>Fri, 02 Dec 2022 20:47:35 +0000</pubDate>
      <link>https://forem.com/wood/openpgp-proof-l0a</link>
      <guid>https://forem.com/wood/openpgp-proof-l0a</guid>
      <description>&lt;p&gt;openpgp4fpr:4E5DC0D7B51CF6AB3664FCD83C185ED56E760F73&lt;/p&gt;

</description>
    </item>
    <item>
      <title>My notes from Aaron Patterson's RailsConf 2020 keynote</title>
      <dc:creator>Joshua Wood</dc:creator>
      <pubDate>Thu, 07 May 2020 02:04:17 +0000</pubDate>
      <link>https://forem.com/wood/my-notes-from-aaron-patterson-s-railsconf-2020-keynote-392n</link>
      <guid>https://forem.com/wood/my-notes-from-aaron-patterson-s-railsconf-2020-keynote-392n</guid>
      <description>&lt;p&gt;Aaron's talk was very Aaron: 20 minutes of jokes, 40 minutes of brain bending Rails performance show-and-tell. His goal: to teach you how to profile your Rails app. If you haven't watched his keynote yet, here's the gist:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.joshuawood.net/notes/2020-railsconf-aaron-patterson-keynote" rel="noopener noreferrer"&gt;https://www.joshuawood.net/notes/2020-railsconf-aaron-patterson-keynote&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A few takeaways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not all code is equal&lt;/li&gt;
&lt;li&gt;Similar behaviors should have similar performance&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Poor performance is a bug&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Miss Aaron's talk? In THIS economy?&lt;/p&gt;

&lt;p&gt;👌&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>activerecord</category>
    </item>
    <item>
      <title>My notes from DHH's RailsConf keynote interview</title>
      <dc:creator>Joshua Wood</dc:creator>
      <pubDate>Wed, 06 May 2020 21:31:34 +0000</pubDate>
      <link>https://forem.com/wood/my-notes-from-dhh-s-railsconf-keynote-interview-37op</link>
      <guid>https://forem.com/wood/my-notes-from-dhh-s-railsconf-keynote-interview-37op</guid>
      <description>&lt;p&gt;For those of you who haven't had the chance to watch yet:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.joshuawood.net/notes/2020-railsconf-dhh-keynote" rel="noopener noreferrer"&gt;https://www.joshuawood.net/notes/2020-railsconf-dhh-keynote&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the parts I liked best was this comment:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Ruby is great because you can know a little JavaScript and then jump to Ruby, understand it, and own the full stack.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What do y'all think about the state of Ruby and Rails in 2020?&lt;/p&gt;

</description>
      <category>rails</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Deploy a new Rails app to AWS Lambda using Lamby</title>
      <dc:creator>Joshua Wood</dc:creator>
      <pubDate>Thu, 30 Apr 2020 16:42:44 +0000</pubDate>
      <link>https://forem.com/wood/deploy-a-new-rails-app-to-aws-lambda-using-lamby-3i32</link>
      <guid>https://forem.com/wood/deploy-a-new-rails-app-to-aws-lambda-using-lamby-3i32</guid>
      <description>&lt;p&gt;These are my notes from deploying a boilerplate Rails app to AWS Lambda (yeah, you read that right) using Lamby. Basically this is me going through the Quick Start guide. (&lt;a href="https://2ayxcm8ff3.execute-api.us-west-1.amazonaws.com/production/" rel="noopener noreferrer"&gt;Here is my production endpoint&lt;/a&gt;--not sure how long this will be up.)&lt;/p&gt;

&lt;p&gt;Related links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/lambda/" rel="noopener noreferrer"&gt;https://aws.amazon.com/lambda/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lamby.custominktech.com" rel="noopener noreferrer"&gt;https://lamby.custominktech.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lamby.custominktech.com/docs/quick_start" rel="noopener noreferrer"&gt;https://lamby.custominktech.com/docs/quick_start&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Follow me on Twitter: &lt;a href="https://twitter.com/heyjoshwood" rel="noopener noreferrer"&gt;https://twitter.com/heyjoshwood&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A few unanswered questions I have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What about &lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html" rel="noopener noreferrer"&gt;Lambda's 250MB max function size&lt;/a&gt;? Will this work with a large Rails app?&lt;/li&gt;
&lt;li&gt;What about cold starts? Even a boilerplate Rails app takes a long time to boot.&lt;/li&gt;
&lt;li&gt;Why is Docker so slow on macOS 😭&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Update: Ken Collins, the creator of the Lamby gem, responded to some of my questions on Reddit. &lt;a href="https://www.reddit.com/r/rails/comments/gafh0n/deploy_a_new_rails_app_to_aws_lambda_using_lamby/fp1xxhf/" rel="noopener noreferrer"&gt;Check out the thread&lt;/a&gt;.&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;Generate the initial Rails app:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  brew &lt;span class="nb"&gt;install &lt;/span&gt;awscli jq
  brew tap aws/tap
  brew &lt;span class="nb"&gt;install &lt;/span&gt;aws-sam-cli

  asdf shell ruby 2.7.1

  gem &lt;span class="nb"&gt;install &lt;/span&gt;rails &lt;span class="nt"&gt;-N&lt;/span&gt;

  rails new lamby_rails &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--skip-action-mailer&lt;/span&gt; &lt;span class="nt"&gt;--skip-action-mailbox&lt;/span&gt; &lt;span class="nt"&gt;--skip-action-text&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--skip-active-record&lt;/span&gt; &lt;span class="nt"&gt;--skip-active-storage&lt;/span&gt; &lt;span class="nt"&gt;--skip-puma&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--skip-action-cable&lt;/span&gt; &lt;span class="nt"&gt;--skip-spring&lt;/span&gt; &lt;span class="nt"&gt;--skip-listen&lt;/span&gt; &lt;span class="nt"&gt;--skip-turbolinks&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--skip-system-test&lt;/span&gt; &lt;span class="nt"&gt;--skip-bootsnap&lt;/span&gt;

  &lt;span class="nb"&gt;cd &lt;/span&gt;lamby_rails

  git add &lt;span class="nb"&gt;.&lt;/span&gt;
  git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s1"&gt;'initial'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Edit &lt;code&gt;app/controllers/application_controller.rb&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ApplicationController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActionController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;
      &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;html: &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;h1&amp;gt;Hello Lamby&amp;lt;/h1&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;html_safe&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit &lt;code&gt;config/routes.rb&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;draw&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="s2"&gt;"application#index"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Save progress:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  git add &lt;span class="nt"&gt;-p&lt;/span&gt;
  git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s1"&gt;'hello lamby'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Install lamby gems:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  bundle add lamby aws-sdk-ssm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Edit &lt;code&gt;Gemfile&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;  - gem "lamby", "~&amp;gt; 2.0"
  + gem "lamby", "~&amp;gt; 2.0", require: false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Finish installing lamby:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  ./bin/rake &lt;span class="nt"&gt;-r&lt;/span&gt; lamby lamby:install

  git add &lt;span class="nt"&gt;-p&lt;/span&gt;
  git status
  git add &lt;span class="nb"&gt;.&lt;/span&gt;
  git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s1"&gt;'install lamby'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;I set up my AWS credentials here:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  # ~/.aws/credentials
  [lamby_rails]
  aws_access_key_id = VALUE
  aws_secret_access_key = SECRET_VALUE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;And the region config here:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  # ~/.aws/config
  [lamby_rails]
  output = json
  region = us-west-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;I set my AWS_PROFILE using &lt;a href="https://direnv.net" rel="noopener noreferrer"&gt;direnv&lt;/a&gt;. Edit &lt;code&gt;.envrc&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  export AWS_PROFILE=lamby_rails
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  direnv allow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Configure
&lt;a href="https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html" rel="noopener noreferrer"&gt;SSM&lt;/a&gt;
w/ Rails master key:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws ssm put-parameter &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"/config/lamby_rails/env/RAILS_MASTER_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--type&lt;/span&gt; &lt;span class="s2"&gt;"SecureString"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--value&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;config/master.key&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Edit &lt;code&gt;app.rb&lt;/code&gt; and add this line right after &lt;code&gt;require 'lamby'&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'RAILS_MASTER_KEY'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="no"&gt;Lamby&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SsmParameterStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/config/lamby_rails/env/RAILS_MASTER_KEY'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Edit &lt;code&gt;template.yaml&lt;/code&gt; CloudFormation/SAM file by adding this to the &lt;code&gt;Properties&lt;/code&gt; section of your &lt;code&gt;RailsFunction&lt;/code&gt;. This addition allows your Lambda's runtime policy to read configs from SSM Parameter store (&lt;a href="https://gist.github.com/joshuap/4ab915f6b94366f570fcb63f38660262#file-template-yml" rel="noopener noreferrer"&gt;see full &lt;code&gt;template.yml&lt;/code&gt;&lt;/a&gt;):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  Policies:
    - Version: "2012-10-17"
      Statement:
        - Effect: Allow
          Action:
            - ssm:GetParameter
            - ssm:GetParameters
            - ssm:GetParametersByPath
            - ssm:GetParameterHistory
          Resource:
            - !Sub arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:parameter/config/lamby_rails/*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Save progress:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  git add &lt;span class="nt"&gt;-p&lt;/span&gt;
  git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s1"&gt;'configure lamby'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Edit &lt;code&gt;.envrc&lt;/code&gt; (change the bucket name):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  export CLOUDFORMATION_BUCKET=lamby-rails-josh
  export AWS_DEFAULT_REGION=us-west-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;don't forget:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  direnv allow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now run:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws s3 mb &lt;span class="s2"&gt;"s3://&lt;/span&gt;&lt;span class="nv"&gt;$CLOUDFORMATION_BUCKET&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

  ./bin/deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This uses Docker to bake the Rails app Lambda function. That can take a long time on macOS.
Go get some coffee or tea. :)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;time&lt;/span&gt; ./bin/deploy

  Successfully created/updated stack - lambyrails-production-us-west-1 &lt;span class="k"&gt;in &lt;/span&gt;None
  ./bin/deploy  17.45s user 9.86s system 5% cpu 9:04.13 total
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(that's the build/deploy time on an 8-core MacBook Pro 🤔)&lt;/p&gt;

</description>
      <category>rails</category>
      <category>aws</category>
      <category>devops</category>
      <category>lambda</category>
    </item>
    <item>
      <title>We made a community error dashboard for DEV</title>
      <dc:creator>Joshua Wood</dc:creator>
      <pubDate>Tue, 17 Mar 2020 15:48:14 +0000</pubDate>
      <link>https://forem.com/honeybadger/we-made-a-community-error-dashboard-for-dev-1no9</link>
      <guid>https://forem.com/honeybadger/we-made-a-community-error-dashboard-for-dev-1no9</guid>
      <description>&lt;p&gt;Software development is more fun with friends; that's why we've built tons of collaboration features into Honeybadger over the years, making it easier for teams to fix errors.&lt;/p&gt;

&lt;p&gt;Earlier this year the team at DEV emailed us with a feature request: could we make it easier to involve the broader DEV open source community in the error-fixing process?&lt;/p&gt;

&lt;p&gt;Today, we're excited to announce a new feature that does exactly that: &lt;strong&gt;Public Dashboards&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;[Read on to learn more about public dashboards and how to enable one for your own Honeybadger project. If you want to help DEV squash bugs in Honeybadger, &lt;a href="https://dev.to/devteam/help-us-squash-bugs-in-dev-with-honeybadger-4nof"&gt;they wrote about how to get involved&lt;/a&gt;.]&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwyyovf9314n3hfo3gwpr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwyyovf9314n3hfo3gwpr.png" alt="Public Dashboard" width="800" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A public dashboard is a secret URL that you can share with outside users (such as contractors and open-source contributors). When you use the share button (see below for details) from the error details page, that error appears on the public dashboard for your project—making it easy for everyone to discover new errors to fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  Backstory on the share button
&lt;/h2&gt;

&lt;p&gt;Most DevOps tools do not adapt well to community projects, where the team is continually changing. It's is a problem we've thought a lot about in the past: open-source benefits from anyone in the world being able to jump in and fix an error, but sometimes the needed production data is private.&lt;/p&gt;

&lt;p&gt;To begin to address the problem, we added the ability to "share" an error with an outside user, scrubbed of all PII (Personally Identifiable Information, such as user IDs and session data). This single feature made it easy for core teams to share vital debugging information (such as error messages and stack traces) with community members without a ton of copy/pasting:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faqbdrvy7x9lit7cjyh97.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faqbdrvy7x9lit7cjyh97.png" alt="Public Dashboard Share Button" width="800" height="66"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Community Dashboard
&lt;/h2&gt;

&lt;p&gt;DEV wanted us to take this a step further and create a public dashboard where the community could see existing production errors and contribute a fix. We loved the idea so much that we fast-tracked it and are launching it today.&lt;/p&gt;

&lt;p&gt;Of course, not everyone wants a public dashboard for their Honeybadger project, so it's disabled by default. To enable it, head over to Settings -&amp;gt; Advanced -&amp;gt; Enable Public Dashboard, and flip the bit:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn3b0f9f2osv4hfujld2l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn3b0f9f2osv4hfujld2l.png" alt="Public Dashboard Setting Page" width="800" height="678"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feel free to send the unique dashboard link to just a few team members, or share it with the world.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We are stoked to have the opportunity to work with the DEV team on this, and can't wait to see what other open source communities do with it.&lt;/p&gt;

&lt;p&gt;If you're involved in an open-source community that runs production applications, Honeybadger is for you. It's also free for non-commercial open-source projects. &lt;a href="https://www.honeybadger.io/" rel="noopener noreferrer"&gt;Sign up today!&lt;/a&gt;&lt;/p&gt;

</description>
      <category>honeybadger</category>
      <category>meta</category>
      <category>errors</category>
    </item>
    <item>
      <title>I never deploy on Fridays, but when I do...</title>
      <dc:creator>Joshua Wood</dc:creator>
      <pubDate>Fri, 21 Feb 2020 22:21:08 +0000</pubDate>
      <link>https://forem.com/wood/i-never-deploy-on-fridays-but-when-i-do-bkh</link>
      <guid>https://forem.com/wood/i-never-deploy-on-fridays-but-when-i-do-bkh</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdgl7crmbqpmei6rzg6ay.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdgl7crmbqpmei6rzg6ay.gif" width="436" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I know you're not supposed to. I may have been the one to tell you not to. And yet, sometimes I can't help myself... 😬&lt;/p&gt;

&lt;p&gt;Anybody else deploying today? If so, why? What are you shipping that's so important?&lt;/p&gt;

&lt;p&gt;I'll tell if you tell. :)&lt;/p&gt;

</description>
      <category>devops</category>
      <category>discuss</category>
    </item>
    <item>
      <title>F*ck-That Money</title>
      <dc:creator>Joshua Wood</dc:creator>
      <pubDate>Tue, 11 Feb 2020 15:22:08 +0000</pubDate>
      <link>https://forem.com/honeybadger/f-ck-that-money-53kc</link>
      <guid>https://forem.com/honeybadger/f-ck-that-money-53kc</guid>
      <description>&lt;p&gt;&lt;strong&gt;I've met some hugely successful people. Some of them are happy.&lt;/strong&gt; Some of them... aren't. I've noticed some things about the ones who aren't:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They're obsessed with their careers&lt;/li&gt;
&lt;li&gt;They spend a lot of time at work&lt;/li&gt;
&lt;li&gt;They aren't fulfilled by the work they do&lt;/li&gt;
&lt;li&gt;They aren't content with what they have&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In many circles, these people are way more successful than most of us. They probably have better networks. They might have fancier job titles. They certainly make more money.&lt;/p&gt;

&lt;p&gt;The Silicon Valley meme goes, "start a company and sell it for so much money that you can say 'f*ck you' to anyone in the world." Or maybe an alternate career path is to climb the corporate ladder at Google until you've banked that privilege.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So much toxic bullshit stems from that line of thinking.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'd rather have f*ck-that money—e.g., a moderate amount of money that empowers you to live a meaningful life. F*ck-that money isn't about being a pretentious asshole; it's about keeping your priorities straight. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Miss your kid's soccer practice to catch up on emails? F*ck that!&lt;/li&gt;
&lt;li&gt;Power through lunch? F*ck that!&lt;/li&gt;
&lt;li&gt;Skip the gym? F*ck that!&lt;/li&gt;
&lt;li&gt;Work over the weekend? F*ck that!&lt;/li&gt;
&lt;li&gt;Save that side project for when you have more free time? F*ck that!&lt;/li&gt;
&lt;li&gt;You get the idea...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At Honeybadger, this mindset has led us to turn down acquisition offers and investors—to stay small and grow naturally. We're not in this business to be rich; we're in it to be free.&lt;/p&gt;

&lt;p&gt;Regret the best years of our lives?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fuck that.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;Btw, we're currently &lt;a href="https://www.honeybadger.io/blog/hiring-a-software-developer/" rel="noopener noreferrer"&gt;hiring a developer&lt;/a&gt; to join us.&lt;/p&gt;

</description>
      <category>career</category>
      <category>startup</category>
      <category>business</category>
      <category>motivation</category>
    </item>
    <item>
      <title>Cold Showers</title>
      <dc:creator>Joshua Wood</dc:creator>
      <pubDate>Sat, 08 Feb 2020 05:19:51 +0000</pubDate>
      <link>https://forem.com/wood/cold-showers-4no1</link>
      <guid>https://forem.com/wood/cold-showers-4no1</guid>
      <description>&lt;p&gt;Next time you rinse off, do this:&lt;/p&gt;

&lt;p&gt;Standing right under the showerhead, gradually increase the hot water. When you can’t handle it anymore, turn the temperature all the way to cold (and brace yourself). Wait to stop hyperventilating before turning the water off.&lt;/p&gt;

&lt;p&gt;Do this every day. Not only is it refreshing, but it’s also a daily reminder that for many things, getting past the initial resistance is the hardest part. 🚿&lt;/p&gt;

</description>
      <category>goals</category>
      <category>motivation</category>
    </item>
    <item>
      <title>Breadcrumbs for JavaScript in Honeybadger</title>
      <dc:creator>Joshua Wood</dc:creator>
      <pubDate>Fri, 07 Feb 2020 01:00:20 +0000</pubDate>
      <link>https://forem.com/honeybadger/breadcrumbs-for-javascript-in-honeybadger-2o41</link>
      <guid>https://forem.com/honeybadger/breadcrumbs-for-javascript-in-honeybadger-2o41</guid>
      <description>&lt;p&gt;One of the things that make fixing JavaScript errors so difficult is that everything happens on the client-side. When an obscure error happens in a callback, you often lack the context to reproduce it. If the error is critical, you may even resort to deploying debug code to get more information about the events leading up to it.&lt;/p&gt;

&lt;p&gt;We added a feature to help, and it's called Breadcrumbs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Farufzpa1zndez09oc9qj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Farufzpa1zndez09oc9qj.png" width="800" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;Breadcrumb&lt;/strong&gt; is a client-side event that happened before an error. Breadcrumbs are collected in realtime as users interact with your client-side application. When an error happens, the breadcrumbs leading up to it are included, filling in the missing context.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.honeybadger.io/blog/introducing-breadcrumbs/" rel="noopener noreferrer"&gt;Since launching breadcrumbs for Ruby and Elixir last year&lt;/a&gt;, our customers have been fixing errors faster and with more confidence. Today we're excited to announce that breadcrumbs are available for JavaScript!&lt;/p&gt;

&lt;h2&gt;
  
  
  How Can You Use It?
&lt;/h2&gt;

&lt;p&gt;Breadcrumbs are available as of &lt;a href="https://github.com/honeybadger-io/honeybadger-js" rel="noopener noreferrer"&gt;honeybadger-js&lt;/a&gt; version 2.1, but disabled by default. To capture breadcrumbs, you must explicitly enable them. We plan to enable breadcrumbs by default in version 3.0.&lt;/p&gt;

&lt;p&gt;To enable breadcrumbs in your project:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Update your honeybadger-js package to the latest 2.x version (2.1.1 at the time of this post)&lt;/li&gt;
&lt;li&gt;Enable breadcrumbs in your honeybadger-js configuration:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="nx"&gt;Honeybadger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="na"&gt;breadcrumbsEnabled&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Automatic Breadcrumbs
&lt;/h2&gt;

&lt;p&gt;Honeybadger captures the following breadcrumbs automatically by instrumenting browser features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clicks&lt;/li&gt;
&lt;li&gt;Console logs&lt;/li&gt;
&lt;li&gt;Errors&lt;/li&gt;
&lt;li&gt;History/location changes&lt;/li&gt;
&lt;li&gt;Network requests (XHR and fetch)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Sending Custom Breadcrumbs
&lt;/h2&gt;

&lt;p&gt;No one knows your app better than you. In addition to the default events, you can report custom breadcrumbs to Honeybadger:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Honeybadger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addBreadcrumb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Loading User&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;user_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userName&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When an error is subsequently reported, you should see it in the Breadcrumb stack:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ft48d6m0z28u41z6blhu7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ft48d6m0z28u41z6blhu7.png" width="800" height="57"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also customize the category of custom events that are displayed. For&lt;br&gt;
more information, &lt;a href="https://docs.honeybadger.io/lib/javascript/guides/breadcrumbs.html" rel="noopener noreferrer"&gt;check out the guide in the Honeybadger&lt;br&gt;
docs&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let us know how it goes!
&lt;/h2&gt;

&lt;p&gt;We hope that Breadcrumbs will be a helpful addition to your JavaScript toolbox. Try it out, and give us a shout if there is anything you would like to see added.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>errors</category>
      <category>honeybadger</category>
    </item>
    <item>
      <title>What if I called FLUSHALL on your Redis instance? 😱</title>
      <dc:creator>Joshua Wood</dc:creator>
      <pubDate>Mon, 05 Aug 2019 19:11:53 +0000</pubDate>
      <link>https://forem.com/honeybadger/what-if-i-called-flushall-on-your-redis-instance-2gc1</link>
      <guid>https://forem.com/honeybadger/what-if-i-called-flushall-on-your-redis-instance-2gc1</guid>
      <description>&lt;p&gt;At &lt;a href="https://www.honeybadger.io" rel="noopener noreferrer"&gt;Honeybadger&lt;/a&gt;, we use Redis &lt;strong&gt;a lot&lt;/strong&gt;. It's our Swiss Army Knife; it's a cache, a single source of truth, it stores background jobs, and more. Basically, &lt;strong&gt;Redis is one of those services that should never fail.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I was pondering the DevOps apocalypse recently, as one does (could Redis be one of the four horsemen?), which led me to jump into our &lt;em&gt;#ops&lt;/em&gt; channel to ask Ben a simple question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;josh [13:58]&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
what are the risks if someone executed flushall on our redis instances?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ben [13:58]&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
you just gave me a micro heart attack&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;josh [13:59]&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
rofl&lt;br&gt;&lt;br&gt;
Sorry :)&lt;br&gt;&lt;br&gt;
I didn’t do it, for the record&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ben [14:00]&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
all kinds of badness would happen... the job queues would be flushed, there would be a potential for duplicate notifications, timeline charts would start hitting ES instead of being cached, and more :)&lt;br&gt;&lt;br&gt;
it would make for a very bad day :)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Don't worry, Ben recovered after a few hours, and is mostly back to his old self again. I should have prefaced my question; I didn't mean to suggest that I'd &lt;em&gt;actually flushed our Redis cluster&lt;/em&gt;. Still, it kind of proved my point. Maybe trolling your SREs and measuring their sweat is a good way to plan for catastrophes...&lt;/p&gt;

&lt;h3&gt;
  
  
  SO. I'd identified a potential issue. It would be really bad if Redis got flushed. What are the risks of that happening?
&lt;/h3&gt;

&lt;p&gt;Our Redis clusters are deployed with primary and secondary instances across multiple availability zones in AWS, with automatic failover to the secondary in case of primary failure. That's a pretty rock-solid Redis deployment; we can lose entire instances without losing data or even impacting other services.&lt;/p&gt;

&lt;p&gt;Unfortunately, preventing human error is much harder, and for some reason, Redis makes it dead-simple to delete all your data with a single command entered in the wrong console. Our architecture did not guard against that. While our team is aware of this, there's a pretty good chance that a future developer could make this mistake.&lt;/p&gt;

&lt;h3&gt;
  
  
  In fact, my friend Molly Struve, Sr. SRE at &lt;a href="https://www.kennasecurity.com/" rel="noopener noreferrer"&gt;&lt;span&gt;Kenna Security&lt;/span&gt;&lt;/a&gt;, remembers a situation where something similar happened:
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;We made a change to some code that caused the old cache values in Redis to break with the new code. So we would request the old value and it was not what the code was expecting. Rather than rollback the code, one of our engineers thought it would be fine to run &lt;code&gt;Rails.cache.data.flushdb&lt;/code&gt; and just start with a fresh cache.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Like Honeybadger, Kenna uses Redis for several things—one is the cache-backend for their Ruby on Rails application. The command Molly mentioned, &lt;code&gt;Rails.cache.data.flushdb&lt;/code&gt;, is the Ruby on Rails equivalent of opening up a Redis console and calling &lt;code&gt;FLUSHDB&lt;/code&gt; (which deletes all data in the current database).&lt;/p&gt;

&lt;p&gt;Unfortunately, Redis was also being used to cache report data from Elasticsearch (something that we also do at Honeybadger, incidentally), and that's where things went wrong. When the Redis database was flushed, the cache had to be rebuilt from scratch, which overwhelmed their Elasticsearch cluster:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We have a "Dashboard" page where clients can load part of ALL their reports (think hundreds), and when clients started to hit that without the cache, Elasticsearch lit up like a Christmas Tree. CPU maxed out on all nodes across the board. In the end it was a mad scramble to open multiple consoles to re-cache the reports.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After Kenna's systems were restored, Molly worked with the development team to identify steps they could take to prevent the same thing from happening in the future. They came up with a creative safeguard for new developers who might not realize that clearing the Rails cache is a destructive action: &lt;a href="https://gist.github.com/mstruve/fe7ec87e7b76d228146b9a5a33c79bf3" rel="noopener noreferrer"&gt;they made all production application consoles read-only by default&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Luckily, Kenna's incident was not catastrophic—they were able to recover from it after just a little downtime. It would have been much worse had the unlucky developer accidentally called &lt;code&gt;FLUSHALL&lt;/code&gt;—which flushes &lt;strong&gt;all&lt;/strong&gt; Redis databases—instead of &lt;code&gt;FLUSHDB&lt;/code&gt;. It would have been an easy mistake under pressure, especially when exception reports are already rolling in (did I mention they also use Honeybadger?)&lt;/p&gt;

&lt;h3&gt;
  
  
  Let me ask you a quick question: what would happen if someone called &lt;code&gt;FLUSHALL&lt;/code&gt; on &lt;em&gt;your&lt;/em&gt; Redis console?
&lt;/h3&gt;

&lt;p&gt;If the answer is "all hell would break loose", then you might consider taking preventative action. Here's what we went with; of course, this is us (I'm more than a little paranoid)—your mileage may vary.&lt;/p&gt;

&lt;p&gt;First, access to Redis through &lt;em&gt;clients&lt;/em&gt; (i.e., in the Rails console) should disallow use of the &lt;code&gt;FLUSHALL&lt;/code&gt; and &lt;code&gt;FLUSHDB&lt;/code&gt; commands entirely. Developers &lt;em&gt;never&lt;/em&gt; need to run these commands in production; doing so would cause serious problems, so why have them at all?&lt;/p&gt;

&lt;p&gt;If you're a Ruby/Rails user, feel free to &lt;a href="https://gist.github.com/joshuap/c1ff2657c150df6fb1257398b1d2716b" rel="noopener noreferrer"&gt;steal this gist&lt;/a&gt;. If you want something a bit more comprehensive, &lt;a href="https://gist.github.com/mstruve/fe7ec87e7b76d228146b9a5a33c79bf3" rel="noopener noreferrer"&gt;see Molly's gist&lt;/a&gt;. If you use a different programming language, &lt;em&gt;hopefully&lt;/em&gt; there is a way to disable these commands, but even if there isn't, don't worry, I got you.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Redis config that everyone should use
&lt;/h2&gt;

&lt;p&gt;Mike Perham, the creator of &lt;a href="https://sidekiq.org/" rel="noopener noreferrer"&gt;Sidekiq&lt;/a&gt; (by far the most popular Ruby background job system, with an &lt;a href="https://www.indiehackers.com/podcast/016-mike-perham-of-sidekiq" rel="noopener noreferrer"&gt;awesome business model&lt;/a&gt;), knows a thing or two about Redis. Sidekiq is built on top of Redis to provide an incredibly reliable and efficient job system.&lt;/p&gt;

&lt;p&gt;I asked Mike what best-practices he recommends to his customers, many of which have mission-critical Redis deployments (think Netflix and Oracle). He told me that users who are concerned about the safety of their Redis data should &lt;a href="https://redis.io/topics/security#disabling-of-specific-commands" rel="noopener noreferrer"&gt;disable destructive commands entirely&lt;/a&gt; via Redis's configuration file.&lt;/p&gt;

&lt;p&gt;This approach has the added benefit that the commands are disabled everywhere, including in &lt;code&gt;redis-cli&lt;/code&gt; consoles. The following config should be added to &lt;code&gt;redis.conf&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG ""
rename-command SWAPDB ""
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Renaming the above commands to empty strings means that they will no longer exist as Redis commands. If you still want to be able to call them in rare (and intentional) circumstances, you can rename them to something secret:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rename-command FLUSHALL SUDO_FLUSHALL_222ed15a
rename-command FLUSHDB SUDO_FLUSHDB_2a3bdd5e
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;For instance, you could put those commands in a doomsday ops playbook which only your operations team has access to. Treat them like your company's nuclear codes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Of course, there's always a caveat 🤦
&lt;/h3&gt;

&lt;p&gt;We use Amazon's ElastiCache service to host our Redis clusters, and after some research, I learned that ElastiCache does not provide direct access to &lt;code&gt;redis.conf&lt;/code&gt;, and it doesn't provide a &lt;a href="https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/ParameterGroups.Redis.html" rel="noopener noreferrer"&gt;Redis configuration parameter&lt;/a&gt; for &lt;code&gt;rename-command&lt;/code&gt;. So unfortunately, while our application consoles are safe, we still must handle &lt;code&gt;redis-cli&lt;/code&gt; with care.&lt;/p&gt;

&lt;p&gt;In the end, we added a note about this to our internal Redis playbook, and will revisit the ElastiCache documentation occasionally to see if Amazon gives us access to &lt;code&gt;rename-command&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Failures are inevitable
&lt;/h2&gt;

&lt;p&gt;If it were possible to prevent 100% of failures before they occur, our jobs would be much easier. We wouldn't need on-call rotations or postmortems, and we could all code full-time. Unfortunately, we live in the real world, where chaos rules, and entropy ensures that our systems are constantly deteriorating.&lt;/p&gt;

&lt;p&gt;There's risk inherent in everything we do. To ship stable applications, we should take actions which minimize risk. In doing so, we reduce (but not eliminate) the potential for failures.&lt;/p&gt;

&lt;h3&gt;
  
  
  Being able to evaluate the risks associated with your actions dramatically increases your value as a developer.
&lt;/h3&gt;

&lt;p&gt;Molly's story and others convinced me that the same thing could easily happen to us; the (perceived) risk was high. The solution—disabling potentially destructive commands, or making them extremely difficult to execute—was relatively easy.&lt;/p&gt;

&lt;p&gt;There's a name for the combination of high value and minimum effort: low-hanging fruit. In the context of software, it's the idea that if you can gain a lot by making a small change, it's probably worth doing. This felt like it was in the sweet spot of eliminating a big risk for a small amount of effort. Kind of like the first time I installed &lt;a href="https://www.honeybadger.io" rel="noopener noreferrer"&gt;Honeybadger&lt;/a&gt;... ;)&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This story was adapted from an email I recently sent to our community newsletter, Leveling Up. If you liked it, &lt;a href="https://www.honeybadger.io/leveling-up/" rel="noopener noreferrer"&gt;feel free to subscribe.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>redis</category>
      <category>devops</category>
      <category>ruby</category>
      <category>rails</category>
    </item>
    <item>
      <title>Ship it like Honeybadger</title>
      <dc:creator>Joshua Wood</dc:creator>
      <pubDate>Tue, 05 Feb 2019 18:40:56 +0000</pubDate>
      <link>https://forem.com/honeybadger/ship-it-like-honeybadger-27jb</link>
      <guid>https://forem.com/honeybadger/ship-it-like-honeybadger-27jb</guid>
      <description>&lt;p&gt;A long time ago, my friends and I were in trouble. An app we used almost every day to debug software for our clients had basically stopped working, and it was giving us all headaches. There wasn't really a viable alternative on the market at the time, so we decided we'd build one. Three months later, our app—Honeybadger—was launched.&lt;/p&gt;

&lt;p&gt;Over the next 5 years, we'd build Honeybadger into something we were really proud of, used by thousands of developers to debug exceptions and monitor their web apps for errors. We also built a company that we really wanted to work at, &lt;a href="https://joshuawood.net/badger-life" rel="noopener noreferrer"&gt;turning down a tempting acquisition offer at one point&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  We did all of this on our own, with no funding and just 3 developers.
&lt;/h4&gt;

&lt;p&gt;In case you don't believe me, here's a pic from a recent company meetup (we're all remote). If you're wondering why we're wearing blue, it was for Autism Awareness Month:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fupbhg1w1ruy0n1xg96gz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fupbhg1w1ruy0n1xg96gz.png" alt="The honeybadger.io crew, wearing blue" width="550" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;center&gt;&lt;small&gt;👋 Sup, I'm the fuzzy one on the left.&lt;/small&gt;&lt;/center&gt;




&lt;p&gt;When I tell other devs how small our company is, I usually get the same reaction: "No way, I thought you were like 20 people" (one time someone said 100 🤔), "I would love to [do my own awesome thing] someday".&lt;/p&gt;

&lt;h4&gt;
  
  
  My response is always the same: if we did it, so can you.
&lt;/h4&gt;

&lt;p&gt;Building Honeybadger was a lot of work—and we got a bit lucky with our timing, tbh—but we're not special. In fact, we're pretty average (I didn't even finish college 😬).&lt;/p&gt;

&lt;p&gt;I can think of a few things we did right with Honeybadger, but there's one very basic thing we did that I blame most of our success on: &lt;strong&gt;we shipped a scrappy version 1.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It wasn't perfect, and it didn't do all the things our customers love us for today. That didn't matter, though, because it was enough to make us happy, and as it turns out, there were other devs like us out there. Had we wasted time trying to make it perfect, it would have never taken off, and I wouldn't be here to tell you that—whatever it may be—&lt;em&gt;you can ship it too&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Shipping doesn't mean you have to start your own app (although you certainly can). You may want to write blog posts, record screen casts, contribute to open source, or just kick ass at your job/career. You can do all of these things—the fundamentals are the same.&lt;/p&gt;

&lt;h4&gt;
  
  
  In hindsight, it sounds too simple... "oh yeah, just ship it."
&lt;/h4&gt;

&lt;p&gt;I know it's harder than that. There are all the times you don't start, because you don't know how, or don't believe you can. There's the paralyzing fear that drops in every time you think about finally executing on your plans. There's the cynical voice that whispers "this will never work" whenever you're nearing the finish line.&lt;/p&gt;

&lt;p&gt;If you add up all of these excuses, you get what &lt;a href="https://seths.blog/about/" rel="noopener noreferrer"&gt;&lt;span&gt;Seth Godin&lt;/span&gt;&lt;/a&gt; calls "the resistance." The 10,000 foot view is that most of what you know is holding you back, keeping you from creating your best work. If you want to ship, you need to overcome the resistance.&lt;/p&gt;

&lt;h4&gt;
  
  
  You can beat the resistance through small, iterative changes—it's time to level up.
&lt;/h4&gt;

&lt;p&gt;No matter where you are in your career, there's &lt;em&gt;always&lt;/em&gt; a next level. Building software is easier when you make small changes over time (nobody wants a big rewrite). Habits work the same way. The more things you ship, the easier shipping becomes. Why not start today?&lt;/p&gt;

&lt;p&gt;Pick the smallest thing you can do &lt;em&gt;right now&lt;/em&gt;, and then do it. Send a pull request. Share something you know with someone else. Investigate a new tool or technology. Read &lt;a href="https://www.amazon.com/Linchpin-Are-Indispensable-Seth-Godin/dp/1591844096/" rel="noopener noreferrer"&gt;&lt;span&gt;&lt;em&gt;Linchpin&lt;/em&gt;&lt;/span&gt;&lt;/a&gt;, by Seth Godin (the book I mentioned earlier—it's good).&lt;/p&gt;

&lt;p&gt;Get in the habit of shipping small things; when the big one arrives, you'll ship that too. 🚀&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;If you found this story inspirational, reply and let me know a) what you're shipping today, and b) what you'd like to ship in the future. There are no wrong answers. 😄&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This story was adapted from an email I recently sent to our community newsletter, Leveling Up. If you liked it, &lt;a href="https://www.honeybadger.io/leveling-up/" rel="noopener noreferrer"&gt;feel free to subscribe.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>career</category>
      <category>motivation</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
