Skip to content

Instantly share code, notes, and snippets.

@elct9620
Last active January 28, 2022 17:48
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save elct9620/fc1c75ac7fb9a447bbd1993e840e8eba to your computer and use it in GitHub Desktop.
Save elct9620/fc1c75ac7fb9a447bbd1993e840e8eba to your computer and use it in GitHub Desktop.
CloudFlare Workers Status API

CloudFlare Workers as Status API

In most case, the CloudFlare SLA is greater than our server. So, we can use it as a simple uptime checker.

Usage

  1. Deploy index.js to your CloudFlare Workers, and bind KV which you save the status.
  2. Add updater.rb to your server, and setup cron job to run it
  3. Get node status on any static page with https://your-worker.workers.dev/?node[]=name to fetch node status
  4. Build some script to check timestamp and verify uptime status
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
/**
* Fetch and log a request
* @param {Request} request
*/
async function handleRequest(request) {
// Response as JSON
let responseInit = {
status: 200,
headers: {
'Content-Type': 'application/json;charset=UTF-8'
}
}
// Find all request nodes
let url = new URL(request.url)
let nodes = url.searchParams.getAll('node[]')
let status = await getAllNodeStatus(nodes);
return new Response(JSON.stringify(status), responseInit)
}
// Read nodes status from KV
async function getAllNodeStatus(nodes) {
let status = {};
await Promise.all(nodes.map(async (node) => {
var nodeStatus = await Status.get(node, 'json');
if (nodeStatus) {
status[node] = nodeStatus
}
}));
return status;
}
# frozen_string_literal: true
require 'net/http'
class Updater
attr_reader :hostname
API = 'https://api.cloudflare.com/client/%<version>s/accounts'
ENDPOINT = '/%<account>s/storage/kv/namespaces/%<namespace>s/values/%<node>s'
def initialize
@node_name = ENV['NODE_NAME'] || Socket.gethostname
end
def update!
Net::HTTP.start(uri.host, uri.port, use_ssl: ssl?) do |http|
http.request request
end
end
def request
request = Net::HTTP::Put.new(uri)
request['X-Auth-Email'] = ENV['CF_EMAIL']
request['X-Auth-Key'] = ENV['CF_TOKEN']
request.body = body.to_json
request
end
def ssl?
uri.scheme == 'https'
end
def uri
@uri ||=
URI(format("#{API}#{ENDPOINT}", options))
end
def options
{
version: 'v4',
account: ENV['CF_ACCOUNT_ID'],
namespace: ENV['CF_NAMESPACE_ID'],
node: @node_name
}
end
def body
{
status: :online,
timestamp: Time.now.to_i
}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment