diff --git a/CHANGES/3115.feature b/CHANGES/3115.feature
new file mode 100644
index 00000000000..5a55aa15f4e
--- /dev/null
+++ b/CHANGES/3115.feature
@@ -0,0 +1,3 @@
+Introduces anonymous telemetry data posting to ``_. This is
+enabled by default, and can be disabled by setting the ``TELEMETRY`` setting to ``False``. See the
+:ref:`telemetry docs ` for more info on exactly what is posted along with an example.
diff --git a/docs/components.rst b/docs/components.rst
index e6a4c763f45..5bbf5798bcc 100644
--- a/docs/components.rst
+++ b/docs/components.rst
@@ -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
--------------
@@ -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
+``_ 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"
+ }]
+ }
diff --git a/docs/configuration/settings.rst b/docs/configuration/settings.rst
index ab02518fa4d..1a2be363138 100644
--- a/docs/configuration/settings.rst
+++ b/docs/configuration/settings.rst
@@ -406,3 +406,15 @@ TASK_DIAGNOSTICS
``/var/tmp/pulp//``. 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
+ ``_ and aids in project decision making. See the
+ :ref:`telemetry docs ` for more info on exactly what is posted along with an example.
+
+ Defaults to ``True``.
diff --git a/pulpcore/app/apps.py b/pulpcore/app/apps.py
index 6b6dba17ba8..cbe9653e20c 100644
--- a/pulpcore/app/apps.py
+++ b/pulpcore/app/apps.py
@@ -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
@@ -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()
diff --git a/pulpcore/app/settings.py b/pulpcore/app/settings.py
index 2aeead6ca4e..422beb796df 100644
--- a/pulpcore/app/settings.py
+++ b/pulpcore/app/settings.py
@@ -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
diff --git a/pulpcore/app/tasks/telemetry.py b/pulpcore/app/tasks/telemetry.py
index df929e29ee5..79831fc1bc0 100644
--- a/pulpcore/app/tasks/telemetry.py
+++ b/pulpcore/app/tasks/telemetry.py
@@ -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
@@ -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())
diff --git a/pulpcore/app/util.py b/pulpcore/app/util.py
index 5243bf4eab7..06dc9771728 100644
--- a/pulpcore/app/util.py
+++ b/pulpcore/app/util.py
@@ -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):
"""
@@ -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