Skip to content

Add a metrics endpoint #158

Add a metrics endpoint

Add a metrics endpoint #158

Workflow file for this run

name: CI
# The module, not the documentation. A change under docs/, a markdown file, or
# a documentation workflow runs docs-pr.yml instead.
on:
pull_request:
paths-ignore:
- 'docs/**'
- '**.md'
- 'LICENSE'
- 'NOTICE'
- '.github/workflows/docs-*.yml'
push:
branches:
- main
paths-ignore:
- 'docs/**'
- '**.md'
- 'LICENSE'
- 'NOTICE'
- '.github/workflows/docs-*.yml'
permissions:
contents: read
packages: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
name: Test
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
# No setup-buildx-action here on purpose. It installs a docker-container
# builder, which cannot see images in the local store, so a toolchain
# built by the fallback is invisible to the next build. The default
# builder reads the local store. Multi-arch lives in builder.yml, which
# is the one place that needs buildx.
- name: Log in to the registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Run the suite
run: make -C test test
- name: Show the module log
if: failure()
run: make -C test logs
- name: Upload rejected images
if: failure()
uses: actions/upload-artifact@v4
with:
name: failed-golden-images
path: test/golden/**/*.failed.*
if-no-files-found: ignore
golden:
name: Golden files
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
# No setup-buildx-action here on purpose. It installs a docker-container
# builder, which cannot see images in the local store, so a toolchain
# built by the fallback is invisible to the next build. The default
# builder reads the local store. Multi-arch lives in builder.yml, which
# is the one place that needs buildx.
- name: Log in to the registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Regenerating must reproduce the bytes already in the tree. A diff here
# means the output is not deterministic, which makes every golden case
# meaningless.
- name: Regenerate the goldens
run: make -C test test-update
- name: Check nothing changed
run: |
if ! git diff --quiet -- test/golden; then
echo "Regenerating the golden files changed them."
echo "The output is not deterministic, so every golden case is meaningless."
git diff --stat -- test/golden
exit 1
fi
echo "every golden file reproduced exactly"
arm64:
name: Test arm64
runs-on: ubuntu-24.04-arm
steps:
- uses: actions/checkout@v4
# No setup-buildx-action here on purpose. It installs a docker-container
# builder, which cannot see images in the local store, so a toolchain
# built by the fallback is invisible to the next build. The default
# builder reads the local store. Multi-arch lives in builder.yml, which
# is the one place that needs buildx.
- name: Log in to the registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# The golden files carry no architecture in their name, because amd64
# and arm64 were measured to produce all 90 byte for byte identical.
# This job is what keeps that true: it runs the same cases against the
# same baselines, so a divergence fails here instead of hiding in a
# second set nothing compares.
- name: Run the suite
run: make -C test test
- name: Show the module log
if: failure()
run: make -C test logs
- name: Upload rejected images
if: failure()
uses: actions/upload-artifact@v4
with:
name: failed-golden-images-arm64
path: test/golden/**/*.failed.*
if-no-files-found: ignore
image:
name: Server image
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- name: Log in to the registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# Pull the toolchain, or build it. A pull request that bumps a pinned
# version names a tag the registry does not have yet, because the
# builder workflow publishes on the merge. Without this the two wait on
# each other.
- name: Pull the toolchain
run: make toolchain
- name: Build the server image
run: |
docker build -f docker/Dockerfile -t mod-dims:ci \
--build-arg DIMS_COMMIT="$(git rev-parse --short HEAD)" .
# The image has to start with nothing set. Every DIMS_ variable has a
# default, and a missing one makes httpd refuse to start.
- name: Start the container
run: |
docker run -d --name dims-ci -p 8000:8000 mod-dims:ci
for i in $(seq 30); do
if curl -fsS -o /dev/null http://127.0.0.1:8000/dims-status/; then
exit 0
fi
sleep 1
done
docker logs dims-ci
exit 1
- name: Serve an image
run: |
docker run -d --name dims-origin \
-v "$PWD/test/origin:/usr/local/apache2/htdocs:ro" httpd:2.4.68
origin=$(docker inspect -f \
'{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' dims-origin)
docker rm -f dims-ci
# The origin runs on a private network address, so this run opts in.
docker run -d --name dims-ci \
-e DIMS_ENABLE_DIMS3=on \
-e DIMS_WHITELIST="$origin" \
-e DIMS_ALLOW_PRIVATE_ADDRESSES=on \
mod-dims:ci
sleep 5
docker exec dims-ci curl -fsS -o /tmp/out.png \
"http://127.0.0.1:8000/dims3/development/resize/100x100/?url=http://$origin/grid.png"
docker exec dims-ci sh -c 'test -s /tmp/out.png'
# The metrics endpoint serves its own port, and only when the
# environment turns it on.
- name: Scrape the metrics endpoint
run: |
docker rm -f dims-ci
docker run -d --name dims-ci -p 8001:8001 \
-e DIMS_METRICS_ENABLED=on mod-dims:ci
for i in $(seq 30); do
if curl -fsS -o /dev/null http://127.0.0.1:8001/metrics; then
break
fi
sleep 1
done
curl -fsS http://127.0.0.1:8001/metrics | grep -q dims_requests_total
curl -fsS http://127.0.0.1:8001/metrics | grep -q dims_httpd_workers
# The runtime user must not be able to rewrite the module it runs.
- name: Check the file permissions
run: |
docker exec dims-ci sh -c '
test "$(id -u)" = 33 || exit 1
! test -w /usr/local/apache2/modules/libmod_dims.so || exit 1
! test -w /usr/local/apache2/conf/httpd.conf || exit 1'
sanitizers:
name: Sanitizers
runs-on: ubuntu-24.04
# Findings C4, M9, and H10 are reads of uninitialized or out of bounds
# memory. This job is where they surface. It does not block until the fixes
# land, because the module reports them today.
continue-on-error: true
steps:
- uses: actions/checkout@v4
# No setup-buildx-action here on purpose. It installs a docker-container
# builder, which cannot see images in the local store, so a toolchain
# built by the fallback is invisible to the next build. The default
# builder reads the local store. Multi-arch lives in builder.yml, which
# is the one place that needs buildx.
- name: Log in to the registry
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Run the unit cases
run: make -C test sanitize