267 lines
7.7 KiB
Diff
267 lines
7.7 KiB
Diff
diff --git a/dvc/analytics.py b/dvc/analytics.py
|
|
deleted file mode 100644
|
|
index 6e3dc91..0000000
|
|
--- a/dvc/analytics.py
|
|
+++ /dev/null
|
|
@@ -1,156 +0,0 @@
|
|
-import json
|
|
-import logging
|
|
-import os
|
|
-
|
|
-from .env import DVC_NO_ANALYTICS
|
|
-
|
|
-logger = logging.getLogger(__name__)
|
|
-
|
|
-
|
|
-def collect_and_send_report(args=None, return_code=None):
|
|
- """
|
|
- Collect information from the runtime/environment and the command
|
|
- being executed into a report and send it over the network.
|
|
-
|
|
- To prevent analytics from blocking the execution of the main thread,
|
|
- sending the report is done in a separate process.
|
|
-
|
|
- The inter-process communication happens through a file containing the
|
|
- report as a JSON, where the _collector_ generates it and the _sender_
|
|
- removes it after sending it.
|
|
- """
|
|
- import tempfile
|
|
-
|
|
- from dvc.daemon import daemon
|
|
-
|
|
- report = {}
|
|
-
|
|
- # Include command execution information on the report only when available.
|
|
- if args and hasattr(args, "func"):
|
|
- report.update({"cmd_class": args.func.__name__})
|
|
-
|
|
- if return_code is not None:
|
|
- report.update({"cmd_return_code": return_code})
|
|
-
|
|
- with tempfile.NamedTemporaryFile(delete=False, mode="w") as fobj:
|
|
- json.dump(report, fobj)
|
|
- daemon(["analytics", fobj.name])
|
|
-
|
|
-
|
|
-def is_enabled():
|
|
- from dvc.config import Config, to_bool
|
|
- from dvc.utils import env2bool
|
|
-
|
|
- if env2bool("DVC_TEST"):
|
|
- return False
|
|
-
|
|
- enabled = not os.getenv(DVC_NO_ANALYTICS)
|
|
- if enabled:
|
|
- enabled = to_bool(
|
|
- Config.from_cwd(validate=False).get("core", {}).get("analytics", "true")
|
|
- )
|
|
-
|
|
- logger.debug("Analytics is %sabled.", "en" if enabled else "dis")
|
|
-
|
|
- return enabled
|
|
-
|
|
-
|
|
-def send(path):
|
|
- """
|
|
- Side effect: Removes the report after sending it.
|
|
-
|
|
- The report is generated and stored in a temporary file, see:
|
|
- `collect_and_send_report`. Sending happens on another process,
|
|
- thus, the need of removing such file afterwards.
|
|
- """
|
|
- import requests
|
|
-
|
|
- url = "https://analytics.dvc.org"
|
|
- headers = {"content-type": "application/json"}
|
|
-
|
|
- with open(path, encoding="utf-8") as fobj:
|
|
- report = json.load(fobj)
|
|
-
|
|
- report.update(_runtime_info())
|
|
-
|
|
- try:
|
|
- requests.post(url, json=report, headers=headers, timeout=5)
|
|
- except requests.exceptions.RequestException:
|
|
- logger.debug("failed to send analytics report", exc_info=True)
|
|
-
|
|
- os.remove(path)
|
|
-
|
|
-
|
|
-def _scm_in_use():
|
|
- from dvc.exceptions import NotDvcRepoError
|
|
- from dvc.repo import Repo
|
|
- from dvc.scm import NoSCM
|
|
-
|
|
- from .scm import SCM, SCMError
|
|
-
|
|
- try:
|
|
- scm = SCM(root_dir=Repo.find_root())
|
|
- return type(scm).__name__
|
|
- except SCMError:
|
|
- return NoSCM.__name__
|
|
- except NotDvcRepoError:
|
|
- pass
|
|
-
|
|
-
|
|
-def _runtime_info():
|
|
- """
|
|
- Gather information from the environment where DVC runs to fill a report.
|
|
- """
|
|
- from iterative_telemetry import _generate_ci_id, find_or_create_user_id
|
|
-
|
|
- from dvc import __version__
|
|
- from dvc.utils import is_binary
|
|
-
|
|
- ci_id = _generate_ci_id()
|
|
- if ci_id:
|
|
- group_id, user_id = ci_id
|
|
- else:
|
|
- group_id, user_id = None, find_or_create_user_id()
|
|
-
|
|
- return {
|
|
- "dvc_version": __version__,
|
|
- "is_binary": is_binary(),
|
|
- "scm_class": _scm_in_use(),
|
|
- "system_info": _system_info(),
|
|
- "user_id": user_id,
|
|
- "group_id": group_id,
|
|
- }
|
|
-
|
|
-
|
|
-def _system_info():
|
|
- import platform
|
|
- import sys
|
|
-
|
|
- import distro
|
|
-
|
|
- system = platform.system()
|
|
-
|
|
- if system == "Windows":
|
|
- version = sys.getwindowsversion() # type: ignore[attr-defined]
|
|
-
|
|
- return {
|
|
- "os": "windows",
|
|
- "windows_version_build": version.build,
|
|
- "windows_version_major": version.major,
|
|
- "windows_version_minor": version.minor,
|
|
- "windows_version_service_pack": version.service_pack,
|
|
- }
|
|
-
|
|
- if system == "Darwin":
|
|
- return {"os": "mac", "mac_version": platform.mac_ver()[0]}
|
|
-
|
|
- if system == "Linux":
|
|
- return {
|
|
- "os": "linux",
|
|
- "linux_distro": distro.id(),
|
|
- "linux_distro_like": distro.like(),
|
|
- "linux_distro_version": distro.version(),
|
|
- }
|
|
-
|
|
- # We don't collect data for any other system.
|
|
- raise NotImplementedError
|
|
diff --git a/dvc/cli/__init__.py b/dvc/cli/__init__.py
|
|
index 274b564..b601d84 100644
|
|
--- a/dvc/cli/__init__.py
|
|
+++ b/dvc/cli/__init__.py
|
|
@@ -236,11 +236,6 @@ def main(argv=None): # noqa: C901, PLR0912, PLR0915
|
|
ret = _log_exceptions(exc) or 255
|
|
|
|
try:
|
|
- from dvc import analytics
|
|
-
|
|
- if analytics.is_enabled():
|
|
- analytics.collect_and_send_report(args, ret)
|
|
-
|
|
return ret
|
|
finally:
|
|
logger.setLevel(outer_log_level)
|
|
diff --git a/dvc/commands/daemon.py b/dvc/commands/daemon.py
|
|
index 35d6e90..d5a7b6e 100644
|
|
--- a/dvc/commands/daemon.py
|
|
+++ b/dvc/commands/daemon.py
|
|
@@ -26,15 +26,6 @@ class CmdDaemonUpdater(CmdDaemonBase):
|
|
return 0
|
|
|
|
|
|
-class CmdDaemonAnalytics(CmdDaemonBase):
|
|
- def run(self):
|
|
- from dvc import analytics
|
|
-
|
|
- analytics.send(self.args.target)
|
|
-
|
|
- return 0
|
|
-
|
|
-
|
|
def add_parser(subparsers, parent_parser):
|
|
DAEMON_HELP = "Service daemon."
|
|
daemon_parser = subparsers.add_parser(
|
|
@@ -59,15 +50,3 @@ def add_parser(subparsers, parent_parser):
|
|
help=DAEMON_UPDATER_HELP,
|
|
)
|
|
daemon_updater_parser.set_defaults(func=CmdDaemonUpdater)
|
|
-
|
|
- DAEMON_ANALYTICS_HELP = "Send dvc usage analytics."
|
|
- daemon_analytics_parser = daemon_subparsers.add_parser(
|
|
- "analytics",
|
|
- parents=[parent_parser],
|
|
- description=DAEMON_ANALYTICS_HELP,
|
|
- help=DAEMON_ANALYTICS_HELP,
|
|
- )
|
|
- daemon_analytics_parser.add_argument(
|
|
- "target", help="Analytics file."
|
|
- ).complete = completion.FILE
|
|
- daemon_analytics_parser.set_defaults(func=CmdDaemonAnalytics)
|
|
diff --git a/dvc/commands/init.py b/dvc/commands/init.py
|
|
index ca44919..05730aa 100644
|
|
--- a/dvc/commands/init.py
|
|
+++ b/dvc/commands/init.py
|
|
@@ -3,7 +3,6 @@ import logging
|
|
|
|
import colorama
|
|
|
|
-from dvc import analytics
|
|
from dvc.cli.command import CmdBaseNoRepo
|
|
from dvc.cli.utils import append_doc_link
|
|
from dvc.utils import boxify
|
|
@@ -15,16 +14,6 @@ logger = logging.getLogger(__name__)
|
|
def _welcome_message():
|
|
from dvc.ui import ui
|
|
|
|
- if analytics.is_enabled():
|
|
- ui.write(
|
|
- boxify(
|
|
- "DVC has enabled anonymous aggregate usage analytics.\n"
|
|
- "Read the analytics documentation (and how to opt-out) here:\n"
|
|
- + fmt_link("https://dvc.org/doc/user-guide/analytics"),
|
|
- border_color="red",
|
|
- )
|
|
- )
|
|
-
|
|
msg = (
|
|
"{yellow}What's next?{nc}\n"
|
|
"{yellow}------------{nc}\n"
|
|
diff --git a/dvc/config_schema.py b/dvc/config_schema.py
|
|
index 2e36e90..3d9e402 100644
|
|
--- a/dvc/config_schema.py
|
|
+++ b/dvc/config_schema.py
|
|
@@ -144,7 +144,6 @@ SCHEMA = {
|
|
"remote": Lower,
|
|
"checksum_jobs": All(Coerce(int), Range(1)),
|
|
Optional("interactive", default=False): Bool,
|
|
- Optional("analytics", default=True): Bool,
|
|
Optional("hardlink_lock", default=False): Bool,
|
|
Optional("no_scm", default=False): Bool,
|
|
Optional("autostage", default=False): Bool,
|
|
diff --git a/dvc/env.py b/dvc/env.py
|
|
index 081ec9d..06c1332 100644
|
|
--- a/dvc/env.py
|
|
+++ b/dvc/env.py
|
|
@@ -7,7 +7,6 @@ DVC_EXP_GIT_REMOTE = "DVC_EXP_GIT_REMOTE"
|
|
DVC_EXP_NAME = "DVC_EXP_NAME"
|
|
DVC_GLOBAL_CONFIG_DIR = "DVC_GLOBAL_CONFIG_DIR"
|
|
DVC_IGNORE_ISATTY = "DVC_IGNORE_ISATTY"
|
|
-DVC_NO_ANALYTICS = "DVC_NO_ANALYTICS"
|
|
DVC_PAGER = "DVC_PAGER"
|
|
DVC_ROOT = "DVC_ROOT"
|
|
DVC_SHOW_TRACEBACK = "DVC_SHOW_TRACEBACK"
|