Skip to content

Commit

Permalink
Adds user-facing telemetry submission.
Browse files Browse the repository at this point in the history
By default Pulp systems will now submit anonymous telemetry information
to https://analytics.pulpproject.org/. It documents exactly what is
submitted, and introduces the `TELEMETRY` setting which can be used to
disable anonymous telemetry submission entirely.

closes pulp#3115
  • Loading branch information
bmbouter committed Aug 22, 2022
1 parent a4b8e0b commit af7023a
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 23 deletions.
3 changes: 3 additions & 0 deletions CHANGES/3115.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Introduces anonymous telemetry data posting to `<https://analytics.pulpproject.org/>`_. This is
enabled by default, and can be disabled by setting the ``TELEMETRY`` setting to ``False``. See the
:ref:`telemetry docs <telemetry>` for more info on exactly what is posted along with an example.
41 changes: 41 additions & 0 deletions docs/components.rst
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ started and stopped without notifying Pulp.
All necessary information about tasks is stored in Pulp's Postgres database as a single source of
truth. In case your tasking system get's jammed, there is a guide to help :ref:debugging_tasks.


Static Content
--------------

Expand All @@ -100,3 +101,43 @@ Collect all of the static content into place using the ``collectstatic`` command
``DJANGO_SETTINGS_MODULE="pulpcore.app.settings"``. Run ``collectstatic`` as follows::

$ pulpcore-manager collectstatic



.. _telemetry:

Telemetry Collection
--------------------

By default, Pulp installations post anonymous telemetry data every 24 hours which is summarized on
`<https://analytics.pulpproject.org/>`_ and aids in project decision making. This is enabled by
default but can be disabled by setting ``TELEMETRY=False`` in your settings.

Here is the list of exactly what is collected along with an example below:

* The version of Pulp components installed
* The number of worker processes and number of hosts (not hostnames) those workers run on
* The number of content app processes and number of hosts (not hostnames) those content apps run on

An example payload:

.. code-block:: json
{
"systemId": "a6d91458-32e8-4528-b608-b2222ede994e",
"onlineContentApps": {
"processes": 2,
"hosts": 1
},
"onlineWorkers": {
"processes": 2,
"hosts": 1
},
"components": [{
"name": "core",
"version": "3.21.0"
}, {
"name": "file",
"version": "1.12.0"
}]
}
12 changes: 12 additions & 0 deletions docs/configuration/settings.rst
Original file line number Diff line number Diff line change
Expand Up @@ -406,3 +406,15 @@ TASK_DIAGNOSTICS
``/var/tmp/pulp/<task_UUID>/``. This is ``False`` by default.

* memory - the task's max resident set size in MB.


.. _telemetry-setting:

TELEMETRY
^^^^^^^^^

If ``True``, Pulp will anonymously post telemetry information to
`<https://analytics.pulpproject.org/>`_ and aids in project decision making. See the
:ref:`telemetry docs <telemetry>` for more info on exactly what is posted along with an example.

Defaults to ``True``.
17 changes: 7 additions & 10 deletions pulpcore/app/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from datetime import timedelta

from django import apps
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.db.models.signals import post_migrate
from django.utils.module_loading import module_has_submodule
Expand Down Expand Up @@ -264,21 +265,17 @@ def _populate_system_id(sender, apps, verbosity, **kwargs):

def _configure_telemetry(apps):
from django.db import connection
from pulpcore.app.util import get_telemetry_posting_url, PRODUCTION_URL

if "core_taskschedule" in connection.introspection.table_names():
url = get_telemetry_posting_url()
if settings.TELEMETRY and "core_taskschedule" in connection.introspection.table_names():
TaskSchedule = apps.get_model("core", "TaskSchedule")
task_name = "pulpcore.app.tasks.telemetry.post_telemetry"
dispatch_interval = timedelta(days=1)
name = "Post Anonymous Telemetry Periodically"
# Initially only dev systems receive posted data.
if url == PRODUCTION_URL:
TaskSchedule.objects.filter(task_name=task_name).delete()
else:
TaskSchedule.objects.update_or_create(
name=name, defaults={"task_name": task_name, "dispatch_interval": dispatch_interval}
)

TaskSchedule.objects.update_or_create(
name=name, defaults={"task_name": task_name, "dispatch_interval": dispatch_interval}
)

connection.close()


Expand Down
2 changes: 2 additions & 0 deletions pulpcore/app/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,8 @@

TASK_DIAGNOSTICS = False

TELEMETRY = True

# HERE STARTS DYNACONF EXTENSION LOAD (Keep at the very bottom of settings.py)
# Read more at https://dynaconf.readthedocs.io/en/latest/guides/django.html
from dynaconf import DjangoDynaconf, Validator # noqa
Expand Down
13 changes: 12 additions & 1 deletion pulpcore/app/tasks/telemetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from google.protobuf.json_format import MessageToJson

from pulpcore.app.apps import pulp_plugin_configs
from pulpcore.app.util import get_telemetry_posting_url
from pulpcore.app.models import SystemID
from pulpcore.app.models.status import ContentAppStatus
from pulpcore.app.models.task import Worker
Expand All @@ -19,6 +18,18 @@
logger = logging.getLogger(__name__)


PRODUCTION_URL = "https://analytics.pulpproject.org/"
DEV_URL = "https://dev.analytics.pulpproject.org/"


def get_telemetry_posting_url():
for app in pulp_plugin_configs():
if ".dev" in app.version:
return DEV_URL

return PRODUCTION_URL


async def _num_hosts(qs):
hosts = set()
items = await sync_to_async(list)(qs.all())
Expand Down
13 changes: 1 addition & 12 deletions pulpcore/app/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,9 @@
from pulpcore.app import models
from pulpcore.exceptions.validation import InvalidSignatureError

# a little cache so viewset_for_model doesn't have iterate over every app every time
# a little cache so viewset_for_model doesn't have to iterate over every app every time
_model_viewset_cache = {}

PRODUCTION_URL = "https://analytics.pulpproject.org/"
DEV_URL = "https://dev.analytics.pulpproject.org/"


def get_url(model):
"""
Expand Down Expand Up @@ -246,11 +243,3 @@ def gpg_verify(public_keys, signature, detached_data=None):
if not verified.valid:
raise InvalidSignatureError(_("The signature is not valid."), verified=verified)
return verified


def get_telemetry_posting_url():
for app in pulp_plugin_configs():
if ".dev" in app.version:
return DEV_URL

return PRODUCTION_URL

0 comments on commit af7023a

Please sign in to comment.