Skip to content

Commit

Permalink
Collect artifact size metrics after caching the content
Browse files Browse the repository at this point in the history
The caching machinery stores all headers from the response coming from
content-handler. With this commit, we are introducing an proprietary header
that contains the size of the served artifact or artifact available after the
redirect, X-PULP-ARTIFACT-SIZE.

closes #5817
  • Loading branch information
lubosmj committed Oct 3, 2024
1 parent 4009116 commit cfc3305
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 28 deletions.
1 change: 1 addition & 0 deletions CHANGES/5817.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Started collecting artifact size metrics even after caching the served content.
6 changes: 6 additions & 0 deletions pulpcore/cache/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
)
from pulpcore.responses import ArtifactResponse

from .metrics import artifacts_size_counter

DEFAULT_EXPIRES_TTL = settings.CACHE_SETTINGS["EXPIRES_TTL"]


Expand Down Expand Up @@ -352,6 +354,10 @@ async def cached_function(*args, **kwargs):
response = await self.make_entry(
key, bk, func, args, kwargs, self.default_expires_ttl
)

if size := response.headers.get("X-PULP-ARTIFACT-SIZE"):
artifacts_size_counter.add(size)

return response

return cached_function
Expand Down
23 changes: 23 additions & 0 deletions pulpcore/cache/metrics.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from opentelemetry import metrics

from pulpcore.app.util import MetricsEmitter, get_domain, get_worker_name


class ArtifactsSizeCounter(MetricsEmitter):
def __init__(self):
self.meter = metrics.get_meter("artifacts.size.meter")
self.counter = self.meter.create_counter(
"artifacts.size.counter",
unit="Bytes",
description="Counts the size of served artifacts",
)

def add(self, amount):
attributes = {
"domain_name": get_domain().name,
"worker_process": get_worker_name(),
}
self.counter.add(int(amount), attributes)


artifacts_size_counter = ArtifactsSizeCounter.build()
31 changes: 3 additions & 28 deletions pulpcore/content/handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@

import django

from opentelemetry import metrics

from pulpcore.constants import STORAGE_RESPONSE_MAP
from pulpcore.responses import ArtifactResponse

Expand Down Expand Up @@ -52,9 +50,7 @@
)
from pulpcore.app import mime_types # noqa: E402: module level not at top of file
from pulpcore.app.util import ( # noqa: E402: module level not at top of file
MetricsEmitter,
get_domain,
get_worker_name,
cache_key,
)

Expand Down Expand Up @@ -161,20 +157,6 @@ class Handler:

distribution_model = None

class ArtifactsSizeCounter(MetricsEmitter):
def __init__(self):
self.meter = metrics.get_meter("artifacts.size.meter")
self.counter = self.meter.create_counter(
"artifacts.size.counter",
unit="Bytes",
description="Counts the size of served artifacts",
)

def add(self, amount, attributes):
self.counter.add(amount, attributes)

artifacts_size_counter = ArtifactsSizeCounter.build()

@staticmethod
def _reset_db_connection():
"""
Expand Down Expand Up @@ -1010,7 +992,7 @@ def _build_url(**kwargs):
size = artifact_file.size or "*"
raise HTTPRequestRangeNotSatisfiable(headers={"Content-Range": f"bytes */{size}"})

self._report_served_artifact_size(content_length)
headers["X-PULP-ARTIFACT-SIZE"] = str(content_length)

if domain.storage_class == "pulpcore.app.models.storage.FileSystem":
path = storage.path(artifact_name)
Expand Down Expand Up @@ -1144,9 +1126,9 @@ async def finalize():
download_result = await downloader.run()

if content_length := response.headers.get("Content-Length"):
self._report_served_artifact_size(int(content_length))
response.headers["X-PULP-ARTIFACT-SIZE"] = content_length
else:
self._report_served_artifact_size(size)
response.headers["X-PULP-ARTIFACT-SIZE"] = str(size)

if save_artifact and remote.policy != Remote.STREAMED:
await asyncio.shield(
Expand All @@ -1157,10 +1139,3 @@ async def finalize():
if response.status == 404:
raise HTTPNotFound()
return response

def _report_served_artifact_size(self, size):
attributes = {
"domain_name": get_domain().name,
"worker_name": get_worker_name(),
}
self.artifacts_size_counter.add(size, attributes)

0 comments on commit cfc3305

Please sign in to comment.