惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
Vulnerabilities – Threatpost
aimingoo的专栏
aimingoo的专栏
B
Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
GbyAI
GbyAI
阮一峰的网络日志
阮一峰的网络日志
Engineering at Meta
Engineering at Meta
IT之家
IT之家
V
Visual Studio Blog
The Cloudflare Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
A
About on SuperTechFans
博客园 - 聂微东
Blog — PlanetScale
Blog — PlanetScale
N
News and Events Feed by Topic
A
Arctic Wolf
WordPress大学
WordPress大学
小众软件
小众软件
C
CERT Recently Published Vulnerability Notes
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
D
Darknet – Hacking Tools, Hacker News & Cyber Security
F
Fortinet All Blogs
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Y
Y Combinator Blog
T
Threat Research - Cisco Blogs
Latest news
Latest news
Simon Willison's Weblog
Simon Willison's Weblog
Cyberwarzone
Cyberwarzone
S
Schneier on Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
L
Lohrmann on Cybersecurity
Stack Overflow Blog
Stack Overflow Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Privacy International News Feed
J
Java Code Geeks
Spread Privacy
Spread Privacy
宝玉的分享
宝玉的分享
I
Intezer
L
LangChain Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
G
GRAHAM CLULEY
博客园 - 叶小钗
博客园 - 三生石上(FineUI控件)
The GitHub Blog
The GitHub Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
N
News and Events Feed by Topic
AWS News Blog
AWS News Blog
Attack and Defense Labs
Attack and Defense Labs
Security Archives - TechRepublic
Security Archives - TechRepublic
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO

jola.dev

How to stop Claude from saying load-bearing | jola.dev Let libraries be libraries | jola.dev CI workflows on Tangled for Elixir | jola.dev Automatically syncing your blog to atproto and standard.site | jola.dev Appreciation for the small web | jola.dev Treating LLMs as programming books Publishing your blog to standard.site in Elixir Generating OG images in Elixir The social contract of writing Highest Random Weight in Elixir bunnyx: a bunny.net Elixir client library Building for the joy of building Running local models on an M4 with 24GB memory How to hit your Claude weekly limit so you can go outside and touch grass Dropping Cloudflare for bunny.net Building a blog with Elixir and Phoenix Stay in the Loop: How I Actually Use Claude Code Ruthless Prioritization: The Path to Delivery Estimates Are More Valuable Than You Think When Software Engineers Think They Need More Focus Time If the Goal is Resiliency, Defensive Programming is Your Enemy The Magic of Daily Pull Requests: Why Smaller is Better Building a Distributed Rate Limiter in Elixir with HashRing Announcing Hex Diff Building Hex Diff Push-based GenStage The Erlang :queue module in Elixir Patterns for managing ETS tables The new `Registry.select/2` and what match specs are Elixir String Processing Optimization
Health checks for Plug and Phoenix
Johanna Larsson · 2019-06-01 · via jola.dev

I want to share a simple pattern for setting up HTTP based health checks for Plug/Phoenix applications. Health checks can be used for anything from uptime measuring to readiness/liveness probes for platforms like Kubernetes och ECS. The most simple version of one accepts requests on some specific path and responds with a 200. Another consideration is that it might run very frequently (ECS by default checks around 6 times a second) so it’s also ideal to run it as light as possible, and not generate logs. Finally, personally, I prefer having it out of the way of routing and controllers because I see it as separate from the functionality of the application. Skip to the bottom for a suggestion on how to avoid logging health checks in Phoenix while still using Phoenix.Router.

This code example works even if you don’t use Phoenix since it’s just a plug.

defmodule HealthCheck do

import Plug.Conn

def init(opts), do: opts

def call(%Plug.Conn{request_path: "/health_check"} = conn, _opts) do

conn

|> send_resp(200, "")

|> halt()

end

def call(conn, _opts), do: conn

end

To just briefly explain it, it will grab any request with the specified request_path and immediately respond with an empty 200. All other requests are passed through untouched.

You use it by adding it to the top of your plugs. Here’s an example based on the default Phoenix project, in the Endpoint.ex file:

# hello_web/Endpoint.ex

defmodule HelloWeb.Endpoint do

use Phoenix.Endpoint, otp_app: :hello

# Put the health check here, before anything else

plug HealthCheck

socket "/socket", HelloWeb.UserSocket,

websocket: true,

longpoll: false

# Serve at "/" the static files from "priv/static" directory.

#

# You should set gzip to true if you are running phx.digest

# when deploying your static files in production.

plug Plug.Static,

at: "/",

from: :hello,

gzip: false,

only: ~w(css fonts images js favicon.ico robots.txt)

...

The reason you want it first is that it short circuits any requests to the path /health_check, meaning no other plugs are executed. This has two primary benefits: the first one being that you avoid unnecessary CPU cycles (no router etc). And the other being that it doesn’t get logged because it runs before Plug.Logger.

If you now try going to /health_check you’ll see that no request is logged and you get an empty successful response.

So there you are, a very simple pattern for handling health checks in Plug and Phoenix. You don’t have to limit yourself to just responding 200, you can do any checks in that function clause and return anything, so feel free to adjust and improve for your use case.

If you’re not like me, and you feel strongly that the health check should be in your router (and you’re using Phoenix), but you don’t want those requests to be logged, take a look at scope/2. It supports setting the log level for requests for a specific scope, or even turning request logging off completely for them. Here’s an example:

scope "/health_check", log: false do

forward "/", HealthCheck

end

Enjoy!

Written by Johanna Larsson. Thoughts on this post? Find me on Bluesky at @jola.dev or why not give it a vote on Bubbles.