Skip to content

Instantly share code, notes, and snippets.

@garthk
garthk / Dockerfile
Last active April 8, 2020 01:32
Demonstration of problem installing Scalyr Agent 2 on Amazon Linux 2
FROM amazonlinux:2
COPY scalyr.key /etc/pki/rpm-gpg/RPM-GPG-KEY-scalyr-1
COPY scalyr.repo /etc/yum.repos.d/
RUN yum install -y jq systemd-python python2-pip scalyr-agent-2
RUN pip2 install docker-py
CMD ["python2", "-c", "import docker; docker.APIClient"]
@garthk
garthk / find-emoji-in-git-log.exs
Created March 12, 2020 04:11
Find Emoji in git log output using Elixir
#! /usr/bin/env elixir
defmodule FindEmoji do
def find_emoji_in_git_log do
:ok =
stream_executable("git", ["log"])
|> Stream.filter(&contains_emoji?/1)
|> Stream.each(&IO.puts/1)
|> Stream.run()
end
@garthk
garthk / Collisions-in-Key-Sortable-Unique-Identifiers-KSUID-in-Elixir.md
Last active January 30, 2020 22:29
Birthday Paradox for Random Collision Avoidance in Elixir

Collisions in Key-Sortable Unique Identifiers (KSUIDs)

Expanding on my thread, it’s been nagging me that the random tail on small key sortable unique IDs (KSUID) might not provide as much protection vs collision as I’d trusted. Segment were able to throw bits at the problem, but I needed to pack my identifiers in smaller spaces.

After sparing 32 bits for the timestamp I might have room for only 32, 40, or 96 random bits. There’s that cryptographers’ rule of thumb about collision needing half the bit count… but how likely is it we’ll get at least one collision?

My math being a bit rusty, I decided to brute force it (birthday.exs). I didn't like my results.exs:

  • 39% failure for 2¹⁶ random choices from 2³² possible keys (3443 rounds)
  • 45% failure for 2²⁰ random choices from 2⁴⁰ possible keys (163 rounds)
@garthk
garthk / pascal_case.ex
Created January 17, 2020 00:45
Pascal case conversion in Elixir
@doc "Convert a string or atom to a pascal case string"
@spec pascal_case(String.t() | atom()) :: String.t()
def pascal_case(name)
def pascal_case(name) when is_atom(name), do: name |> Atom.to_string() |> pascal_case()
def pascal_case(name) when is_binary(name) do
~r{(\W|_)+}
|> Regex.split(name)
|> Enum.map(&capitalise/1)
|> Enum.to_list()
@garthk
garthk / Dockerfile
Last active January 13, 2020 00:28
Demonstrates a way to trigger Credo.Code.ParserError
FROM elixir:1.9.4-alpine
ADD . /root
WORKDIR /root
RUN mix do local.hex --force, deps.get
ENTRYPOINT []
CMD ["mix", "credo", "--strict", "credo732.ex"]
@garthk
garthk / README.md
Last active October 17, 2019 01:16
Basic Risk Register Workflow for Slack
@garthk
garthk / opencensus_honeycomb_phoenix_integration_test.exs
Last active June 2, 2019 06:09
Now-successful attempt at a Phoenix integration test
defmodule Opencensus.Honeycomb.PhoenixIntegrationTest do
use ExUnit.Case, async: false
use Phoenix.ConnTest
alias Jason
alias Opencensus.Honeycomb.Event
alias Opencensus.Honeycomb.Sampler
defmodule HelloWeb.OpencensusTracePlug do
use Opencensus.Plug.Trace, attributes: [:release]
@garthk
garthk / README.md
Created May 15, 2019 06:50
Overkill With GenStage

Strikes me I'm just re-inventing poolboy, here.

@garthk
garthk / README.md
Created April 23, 2019 22:46
Honeycomb Beeline Header Parsing and Formatting in Elixir
@garthk
garthk / LICENSE.txt
Last active March 19, 2019 22:31
Generate an AWS CloudWatch Logs event as if an AWS Lambda executed
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit