forked from pyropy/cf-metrics
-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add cloudflare worker to collect API key usage inside Influx DB #1
Merged
Merged
Changes from 33 commits
Commits
Show all changes
40 commits
Select commit
Hold shift + click to select a range
07f4429
Cache response inside cloudflare worker
pyropy 6c5318d
Do not cache POST requests
pyropy e2ca738
Do not cache POST request responses
pyropy 51b147b
Simplify request formating code
pyropy 4c547d7
Remove unused function arguments
pyropy 467e081
Use default project layout
pyropy 0bba446
Update example env
pyropy 15abebe
Move request logic to worker
pyropy 5891c88
Add unit tests for worker.fetch
pyropy df26c99
Add basic docs
pyropy 1ab824c
Update lib/request.js
pyropy 3525f3e
Update lib/metrics.js
pyropy f6c88ac
Update lib/request.js
pyropy 8732dc3
Update lib/request.js
pyropy 882792d
Update .env.example
pyropy d27848d
Move all influx db related code to lib/influx.js
pyropy 116b146
Add basic github actions
pyropy bb1ae1c
Fix failing test
pyropy a8d3bb9
Fix missing wranger.toml in test job
pyropy 6b76ef4
Update readme with deployment steps
pyropy 6143e4c
Fix README URL for getting CF API token
pyropy 8c65bab
Improve api key parsing to be more readable
pyropy c3fd71f
Simplify worker code; Don't compress metrics
pyropy 4bd5fb2
Remove unused env variable
pyropy 700b15a
Report api key as value
pyropy 201b375
Edit default env variables and secrets
pyropy 7f844c6
Reformat files with newline at EOF
pyropy 16cae7e
Refactor influx.js module
pyropy ef2ecd0
Reformat JSDoc
pyropy 842eaf5
Update test name
pyropy 81e8b56
Add table tests for influx lib
pyropy 8fc77ed
Refactor how influx lib is tested
pyropy c43b0d5
Add test for reportRequestMetric
pyropy 081d4ea
Improve influx test
pyropy bb531a9
Use envsubst to replace env vars in gh actions
pyropy 357da93
Update lib/influx.js
pyropy 82feb43
Update bin/worker.js
pyropy bdc81ee
Fix imports and mocks for renamed functions in tests
pyropy 99c0884
Rename project to spark-stats-request-metrics
pyropy 8f5ef87
Rename import for reporting metrics to influx
pyropy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
INFLUX_TOKEN="example" |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
name: CI | ||
on: | ||
push: | ||
branches: [main] | ||
pull_request: | ||
branches: [main] | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- run: cp wrangler.toml.example wrangler.toml | ||
- uses: actions/setup-node@v4 | ||
with: | ||
node-version: 20 | ||
- run: npm ci | ||
- run: npm test | ||
|
||
deploy: | ||
if: github.ref == 'refs/heads/main' | ||
needs: [test] | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Deploy | ||
uses: cloudflare/wrangler-action@v3 | ||
with: | ||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} | ||
preCommands: | | ||
cp wranger.toml.example wrangler.toml | ||
echo "[env.production.vars]" >> wrangler.toml | ||
echo "ENVIRONMENT = 'production'" >> wrangler.toml" | ||
echo "INFLUX_URL = '${{ env.INFLUX_URL }}'" >> wrangler.toml | ||
echo "INFLUX_METRIC_NAME = '${{ env.INFLUX_METRIC_NAME }}'" >> wrangler.toml | ||
echo "INFLUX_DATABASE = '${{ env.INFLUX_DATABASE }}'" >> wrangler.toml | ||
postCommands: | | ||
rm -f wrangler.toml | ||
environment: production | ||
secrets: | | ||
INFLUX_TOKEN | ||
env: | ||
INFLUX_METRIC_NAME: ${{ env.INFLUX_METRIC }} | ||
INFLUX_URL: ${{ env.INFLUX_URL }} | ||
INFLUX_TOKEN: ${{ secrets.INFLUX_TOKEN }} | ||
INFLUX_DATABASE: ${{ env.INFLUX_DATABASE }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,37 @@ | ||
# Cloudflare metrics worker | ||
|
||
Send your page views from [Cloudflare worker](https://developers.cloudflare.com/workers/) to InfluxDB. | ||
[Couldflare worker](https://developers.cloudflare.com/workers/) used to proxy requests to your application and send metrics to InfluxDB. | ||
|
||
![Dashboard views](static/dashboard.png) | ||
## Development | ||
|
||
## Requirements | ||
|
||
1. Your site need to be setup behind Cloudflare CDN. | ||
2. You need to setup InfluxDB with external access (make sure you have set [authentication](https://docs.influxdata.com/influxdb/v1.7/administration/authentication_and_authorization/#set-up-authentication)) | ||
1. Make sure InfluxDB is hosted under [supported port](https://blog.cloudflare.com/cloudflare-now-supporting-more-ports/) for Workers. Best option is 80 or 443. | ||
|
||
## How to use | ||
|
||
1. Install wrangler package | ||
1. Install dependencies | ||
|
||
``` | ||
npm i @cloudflare/wrangler -g | ||
npm install | ||
``` | ||
|
||
2. Copy example files | ||
|
||
``` | ||
cp .env.example .env | ||
cp .dev.vars.example .dev.vars | ||
cp wrangler.toml.example wrangler.toml | ||
``` | ||
|
||
3. Deploy your worker to a site with wrangler | ||
3. Edit secrets inside `.dev.vars` and environment variables inside `wrangler.toml` files | ||
|
||
3. Run your worker | ||
|
||
``` | ||
wrangler publish --env production | ||
npm run dev | ||
``` | ||
|
||
4. (Optional) If you're using Grafana with InfluxDB, then you can import [example Dashboard](static/dashboard.json) from first screen. | ||
## Deployment to production | ||
|
||
In order to deploy your worker via Github Actions, you need to have a [Cloudflare API token](https://developers.cloudflare.com/fundamentals/api/get-started/create-token/) and running instance of InfluxDB. | ||
|
||
Add generated API token to Github secrets as `CLOUDFLARE_API_TOKEN` and authentication token under `INFLUX_TOKEN`. | ||
|
||
Other required environment variables include the following: | ||
- `INFLUX_URL` - InfluxDB URL | ||
- `INFLUX_DATABASE` - InfluxDB database (bucket) name | ||
- `INFLUX_METRIC_NAME` - InfluxDB metric name | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { reportRequestMetric } from '../lib/influx.js' | ||
|
||
export default { | ||
async fetch(request, env, ctx, { reportRequestMetric } = { reportRequestMetric }) { | ||
pyropy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const response = await fetch(request) | ||
ctx.waitUntil(reportRequestMetric(request, env)) | ||
return response | ||
}, | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/* | ||
* Reports request metrics to InfluxDB | ||
* @param {Request} request - incoming request | ||
* @param {object} env - environment variables | ||
*/ | ||
export const reportRequestMetric = async (request, env) => { | ||
pyropy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
await writeMetrics(createMetricsFromRequest(request, env), env) | ||
} | ||
|
||
/* | ||
* Returns request metrics in InfluxDB line protocol format | ||
* https://docs.influxdata.com/influxdb/cloud/reference/syntax/line-protocol/ | ||
* @param {Request} request - incoming request | ||
* @param {object} env - environment variables | ||
*/ | ||
export const createMetricsFromRequest = (request, env) => { | ||
const url = new URL(request.url); | ||
const timestamp = Date.now(); | ||
const apiKey = request.headers.get('api-key') || | ||
url.searchParams.get('api-key') || ( | ||
request.headers.get('Authorization')?.startsWith('Bearer ') | ||
? request.headers.get('Authorization').substring(7) | ||
: 'unknown' | ||
); | ||
|
||
return `${env.INFLUX_METRIC_NAME} api_key="${apiKey}" ${timestamp}` | ||
pyropy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
/* | ||
* Sends request metrics to InfluxDB | ||
* https://docs.influxdata.com/enterprise_influxdb/v1/guides/write_data/ | ||
* @param {string} lineProtocolData - InfluxDB line protocol formatted data | ||
* @param {object} env - environment variables | ||
*/ | ||
export const writeMetrics = async (lineProtocolData, env) => { | ||
// Define API endpoint and headers | ||
const url = `${env.INFLUX_URL}/api/v2/write?&bucket=${env.INFLUX_DATABASE}&precision=ms`; | ||
bajtos marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
return fetch(url, { | ||
method: 'POST', | ||
headers: { | ||
'Authorization': `Token ${env.INFLUX_TOKEN}`, | ||
'Content-Type': 'application/octet-stream' | ||
}, | ||
body: lineProtocolData, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,9 +6,11 @@ | |
"main": "index.js", | ||
"scripts": { | ||
"deploy": "wrangler deploy", | ||
"dev": "wrangler dev", | ||
"deploy:prod": "wrangler deploy --env production", | ||
"dev": "wrangler dev --env dev", | ||
"start": "wrangler dev", | ||
"test": "vitest" | ||
"test": "vitest run", | ||
"test:watch": "vitest" | ||
}, | ||
"author": "vanadium23 <[email protected]>", | ||
"license": "MIT", | ||
|
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find this confusing. We have spark-api and spark-stats projects, this bucket name leads me to think about spark-api, while we are reporting telemetry for spark-stats.
Proposed bucket name:
spark-stats-telemetry
or simplyspark-stats
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 to
spark-stats
,spark-stats-telemetry
is redundant I think in the context of InfluxDBThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's go with
spark-stats
once we have this finished. I'll keep this bucket name while in development.