Skip to content

Commit 249418c

Browse files
authored
Merge pull request #42 from mrc-ide/proxy-metrics
Export packit and outpack metrics.
2 parents 649f8fb + ddb1a59 commit 249418c

File tree

8 files changed

+93
-12
lines changed

8 files changed

+93
-12
lines changed

config/multipackit/packit.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ instances:
2222
volumes:
2323
outpack: foo_outpack_volume
2424
packit_db: foo_packit_db
25+
packit_db_backup: foo_packit_db_backup
2526

2627
outpack:
2728
server:
@@ -48,6 +49,7 @@ instances:
4849
volumes:
4950
outpack: bar_outpack_volume
5051
packit_db: bar_packit_db
52+
packit_db_backup: bar_packit_db_backup
5153

5254
outpack:
5355
server:
@@ -78,6 +80,7 @@ proxy:
7880
hostname: localhost
7981
port_http: 80
8082
port_https: 443
83+
port_metrics: 8080
8184
image:
8285
build: ../../proxy
8386

config/runner/packit.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,5 +74,6 @@ proxy:
7474
hostname: localhost
7575
port_http: 80
7676
port_https: 443
77+
port_metrics: 8080
7778
image:
7879
build: ../../proxy

config/self-signed/packit.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ proxy:
9292
hostname: localhost
9393
port_http: 80
9494
port_https: 443
95+
port_metrics: 8080
9596
image:
9697
name: packit-proxy
9798
tag: main

src/packit_deploy/__about__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# SPDX-FileCopyrightText: 2023-present Alex Hill <[email protected]>
22
#
33
# SPDX-License-Identifier: MIT
4-
__version__ = "0.1.4"
4+
__version__ = "0.1.5"

src/packit_deploy/config.py

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ def from_data(cls, dat, key: list[str], *, container_name: str, ctx: Context) ->
199199
class PackitAPI:
200200
container_name: str
201201
image: constellation.ImageReference
202+
# port at which api provides health metrics, separately proxied by montagu API - different from Proxy port_metrics!
202203
management_port: int
203204
base_url: str
204205
cors_allowed_origins: str
@@ -312,15 +313,24 @@ class Proxy:
312313
hostname: str
313314
port_http: int
314315
port_https: int
316+
# port at which proxy will provide api and outpack server metrics. Different from PackitAPI management_port!
317+
port_metrics: Optional[int]
315318

316319
@classmethod
317320
def from_data(cls, dat, key: list[str], *, ctx: Context) -> "Proxy":
318321
image = config_buildable(dat, [*key, "image"], repo=ctx.repo, root=ctx.root)
319322
hostname = config.config_string(dat, [*key, "hostname"])
320323
port_http = config.config_integer(dat, [*key, "port_http"])
321324
port_https = config.config_integer(dat, [*key, "port_https"])
325+
port_metrics = config.config_integer(dat, [*key, "port_metrics"], is_optional=True)
322326

323-
return Proxy(image=image, hostname=hostname, port_http=port_http, port_https=port_https)
327+
return Proxy(
328+
image=image,
329+
hostname=hostname,
330+
port_http=port_http,
331+
port_https=port_https,
332+
port_metrics=port_metrics,
333+
)
324334

325335

326336
@dataclass
@@ -397,12 +407,16 @@ def outpack_server_url(self) -> str:
397407
return f"http://{self.outpack_server.container_name}:8000"
398408

399409
@property
400-
def packit_app_endpoint(self) -> str:
401-
return f"{self.packit_app.container_name}:80"
410+
def packit_app_url(self) -> str:
411+
return f"http://{self.packit_app.container_name}:80"
412+
413+
@property
414+
def packit_api_url(self) -> str:
415+
return f"http://{self.packit_api.container_name}:8080"
402416

403417
@property
404-
def packit_api_endpoint(self) -> str:
405-
return f"{self.packit_api.container_name}:8080"
418+
def packit_api_management_url(self) -> str:
419+
return f"http://{self.packit_api.container_name}:{self.packit_api.management_port}"
406420

407421

408422
class PackitConfig:

src/packit_deploy/packit_constellation.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,8 @@ def proxy_container(proxy: config.Proxy, cfg: PackitConfig):
262262
if cfg.acme_config is not None:
263263
mounts.append(constellation.ConstellationVolumeMount("packit-tls", "/run/proxy"))
264264
ports = [proxy.port_http, proxy.port_https]
265+
if proxy.port_metrics is not None:
266+
ports.append(proxy.port_metrics)
265267
return ConstellationContainer(
266268
name,
267269
image=proxy.image,
@@ -278,8 +280,10 @@ def proxy_preconfigure(container: ConstellationContainer, cfg: PackitConfig, pro
278280
instances = [
279281
{
280282
"hostname": instance_hostname(name, proxy.hostname),
281-
"upstream_api": instance.packit_api_endpoint,
282-
"upstream_app": instance.packit_app_endpoint,
283+
"outpack_server_url": instance.outpack_server_url,
284+
"packit_app_url": instance.packit_app_url,
285+
"packit_api_url": instance.packit_api_url,
286+
"packit_api_management_url": instance.packit_api_management_url,
283287
"name": instance.brand.name or name,
284288
}
285289
for name, instance in cfg.instances.items()
@@ -296,6 +300,7 @@ def proxy_preconfigure(container: ConstellationContainer, cfg: PackitConfig, pro
296300
instances=instances,
297301
port_http=proxy.port_http,
298302
port_https=proxy.port_https,
303+
port_metrics=proxy.port_metrics,
299304
index_hostname=index_hostname,
300305
)
301306
write_to_container(nginx_conf.encode("utf-8"), container, "/etc/nginx/conf.d/default.conf")

src/packit_deploy/templates/nginx.conf.j2

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ server {
4545
root /usr/share/nginx/html;
4646

4747
location /api/ {
48-
proxy_pass http://{{ instance.upstream_api }}/;
48+
proxy_pass {{ instance.packit_api_url }}/;
4949
}
5050

5151
location / {
52-
proxy_pass http://{{ instance.upstream_app }}/;
52+
proxy_pass {{ instance.packit_app_url }}/;
5353
}
5454
}
5555
{%- endfor -%}
@@ -108,3 +108,20 @@ server {
108108
return 301 https://$host$request_uri;
109109
}
110110
}
111+
112+
{%- if port_metrics is not none -%}
113+
{%- for instance in instances -%}
114+
server {
115+
listen {{ port_metrics }};
116+
server_name {{ instance.hostname }};
117+
118+
location /metrics/outpack_server {
119+
proxy_pass {{ instance.outpack_server_url }}/metrics;
120+
}
121+
location /metrics/packit-api {
122+
proxy_pass {{ instance.packit_api_management_url }}/prometheus;
123+
}
124+
125+
}
126+
{%- endfor -%}
127+
{%- endif -%}

tests/test_integration.py

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,11 +289,11 @@ def test_vault():
289289

290290

291291
# Test that the custom management port defined in the novault config
292-
# has been correctly configured in the api so we can get metrics from
292+
# has been correctly configured in the api so we can get health metrics from
293293
# within the network - we currently do not expose packit metrics through
294294
# the proxy as this will be done through montagu proxy, and handled
295295
# separately in the nix deployment
296-
def test_can_read_packit_metrics_on_custom_port():
296+
def test_can_read_packit_health_metrics_on_custom_port():
297297
path = "config/novault"
298298
try:
299299
runner = CliRunner()
@@ -311,6 +311,46 @@ def test_can_read_packit_metrics_on_custom_port():
311311
stop_packit(path)
312312

313313

314+
def test_can_read_metrics_from_proxy_single_instance():
315+
path = "config/runner"
316+
try:
317+
runner = CliRunner()
318+
res = runner.invoke(cli.cli, ["start", "--pull", "--name", path])
319+
assert res.exit_code == 0
320+
321+
retries = 50
322+
api_res = http_get("http://localhost:8080/metrics/packit-api", retries=retries)
323+
assert "application_ready_time_seconds" in api_res
324+
325+
outpack_res = http_get("http://localhost:8080/metrics/outpack_server", retries=retries)
326+
assert "outpack_server_build_info" in outpack_res
327+
finally:
328+
stop_packit(path)
329+
330+
331+
def test_can_read_metrics_from_proxy_multi_instance():
332+
path = "config/multipackit"
333+
try:
334+
runner = CliRunner()
335+
res = runner.invoke(cli.cli, ["start", "--pull", "--name", path])
336+
assert res.exit_code == 0
337+
338+
retries = 50
339+
expected_api_metrics_content = "application_ready_time_seconds"
340+
assert expected_api_metrics_content in http_get("http://foo.localhost:8080/metrics/packit-api", retries=retries)
341+
assert expected_api_metrics_content in http_get("http://bar.localhost:8080/metrics/packit-api", retries=retries)
342+
343+
expected_outpack_metrics_content = "outpack_server_build_info"
344+
assert expected_outpack_metrics_content in http_get(
345+
"http://foo.localhost:8080/metrics/outpack_server", retries=retries
346+
)
347+
assert expected_outpack_metrics_content in http_get(
348+
"http://bar.localhost:8080/metrics/outpack_server", retries=retries
349+
)
350+
finally:
351+
stop_packit(path)
352+
353+
314354
def stop_packit(path):
315355
with mock.patch("packit_deploy.cli._prompt_yes_no") as prompt:
316356
prompt.return_value = True

0 commit comments

Comments
 (0)