diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d3b32577c..8a28278c7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## 3.17.6 +- Remove telemetry tracking (mihran113) + ## 3.17.5 Jun 2, 2023 - Fix gpu stat collection when driver is not loaded (mihran113) diff --git a/aim/__init__.py b/aim/__init__.py index 02f3a4bc03..7f10698f92 100644 --- a/aim/__init__.py +++ b/aim/__init__.py @@ -4,8 +4,6 @@ from aim.cli.manager.manager import run_process from aim.utils.deprecation import python_version_deprecation_check, sqlalchemy_version_check -from aim.utils.tracking import analytics python_version_deprecation_check() sqlalchemy_version_check() -analytics.track_install_event() diff --git a/aim/cli/cli.py b/aim/cli/cli.py index 861e932cfc..c99b828cf4 100644 --- a/aim/cli/cli.py +++ b/aim/cli/cli.py @@ -10,7 +10,6 @@ from aim.cli.runs import commands as runs_commands from aim.cli.convert import commands as convert_commands from aim.cli.storage import commands as storage_commands -from aim.cli.telemetry import commands as telemetry_commands core._verify_python3_env = lambda: None @@ -30,4 +29,3 @@ def cli_entry_point(verbose): cli_entry_point.add_command(runs_commands.runs, RUNS_NAME) cli_entry_point.add_command(convert_commands.convert, CONVERT) cli_entry_point.add_command(storage_commands.storage, STORAGE) -cli_entry_point.add_command(telemetry_commands.telemetry) diff --git a/aim/cli/init/commands.py b/aim/cli/init/commands.py index be4345cc7e..54f32af454 100644 --- a/aim/cli/init/commands.py +++ b/aim/cli/init/commands.py @@ -4,8 +4,6 @@ from aim.sdk.repo import Repo from aim.sdk.utils import clean_repo_path -from aim.utils.tracking import analytics - @click.command() @click.option('--repo', required=False, type=click.Path(exists=True, @@ -34,9 +32,7 @@ def init(repo, yes): repo = Repo.from_path(repo_path, init=True) if re_init: - analytics.track_event(event_name='[Repo] Initialize') click.echo( 'Re-initialized empty Aim repository at {}'.format(repo.root_path)) else: - analytics.track_event(event_name='[Repo] Re-initialize') click.echo('Initialized a new Aim repository at {}'.format(repo.root_path)) diff --git a/aim/cli/server/commands.py b/aim/cli/server/commands.py index 95f5e50ba6..53e3f143f2 100644 --- a/aim/cli/server/commands.py +++ b/aim/cli/server/commands.py @@ -7,8 +7,6 @@ from aim.ext.transport.config import AIM_SERVER_DEFAULT_HOST, AIM_SERVER_DEFAULT_PORT, AIM_SERVER_MOUNTED_REPO_PATH from aim.ext.transport.server import run_router -from aim.utils.tracking import analytics - @click.command() @click.option('-h', '--host', default=AIM_SERVER_DEFAULT_HOST, type=str) @@ -70,7 +68,6 @@ def server(host, port, workers, fg='yellow')) click.echo('Server is mounted on {}:{}'.format(host, port), err=True) click.echo('Press Ctrl+C to exit') - analytics.track_event(event_name='[Aim Remote Tracking] Start server') try: run_router(host, port, workers, ssl_keyfile, ssl_certfile) diff --git a/aim/cli/telemetry/__init__.py b/aim/cli/telemetry/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/aim/cli/telemetry/commands.py b/aim/cli/telemetry/commands.py deleted file mode 100644 index 4c17673fde..0000000000 --- a/aim/cli/telemetry/commands.py +++ /dev/null @@ -1,18 +0,0 @@ -import click - -from aim.utils.tracking import analytics - - -@click.group('telemetry', hidden=True) -def telemetry(): - pass - - -@telemetry.command('off') -def turn_off_tracking(): - analytics.telemetry_enabled = False - - -@telemetry.command('on') -def turn_on_tracking(): - analytics.telemetry_enabled = True diff --git a/aim/cli/up/commands.py b/aim/cli/up/commands.py index ebaaf4d5aa..5ef6ca7cb0 100644 --- a/aim/cli/up/commands.py +++ b/aim/cli/up/commands.py @@ -10,7 +10,6 @@ AIM_UI_DEFAULT_HOST, AIM_UI_DEFAULT_PORT, AIM_UI_MOUNTED_REPO_PATH, - AIM_UI_TELEMETRY_KEY, AIM_PROXY_URL, AIM_PROFILER_KEY ) @@ -19,8 +18,6 @@ from aim.web.utils import exec_cmd from aim.web.utils import ShellCommandException -from aim.utils.tracking import analytics - @click.command() @click.option('-h', '--host', default=AIM_UI_DEFAULT_HOST, type=str) @@ -114,11 +111,6 @@ def up(dev, host, port, workers, uds, except Exception: pass - if not dev and os.getenv(AIM_UI_TELEMETRY_KEY, 1) == '0': - click.echo(f'"{AIM_UI_TELEMETRY_KEY}" is ignored. Read how to opt-out here: ' - f'https://aimstack.readthedocs.io/en/latest/community/telemetry.html') - if dev: - analytics.dev_mode = True click.echo(click.style('Running Aim UI on repo `{}`'.format(repo_inst), fg='yellow')) if uds: @@ -132,7 +124,6 @@ def up(dev, host, port, workers, uds, click.echo(f'Proxy {proxy_url}{base_path}/') click.echo('Press Ctrl+C to exit') - analytics.track_event(event_name='[Aim UI] Start UI') if profiler: os.environ[AIM_PROFILER_KEY] = '1' diff --git a/aim/cli/watcher_cli.py b/aim/cli/watcher_cli.py index 1f62142af7..81503e282f 100644 --- a/aim/cli/watcher_cli.py +++ b/aim/cli/watcher_cli.py @@ -12,7 +12,6 @@ from aim.sdk.run_status_watcher import RunStatusWatcher from aim.sdk.repo import Repo -from aim.utils.tracking import analytics core._verify_python3_env = lambda: None DEFAULT_MESSAGE_TEMPLATE = "❗️ Something wrong with Run '{run.hash}'. Please check. ❗️" @@ -78,7 +77,6 @@ def start_watcher(ctx): watcher = RunStatusWatcher(repo) click.secho(f'Starting Aim watcher for repo \'{repo.path}\'...', fg='yellow') click.echo('Press Ctrl+C to exit') - analytics.track_event(event_name='[Aim Watcher] Start event watcher') watcher.start_watcher() diff --git a/aim/sdk/base_run.py b/aim/sdk/base_run.py index b23809e538..7e9c6c14b3 100644 --- a/aim/sdk/base_run.py +++ b/aim/sdk/base_run.py @@ -10,8 +10,6 @@ from aim.sdk.errors import MissingRunError from aim.sdk.tracker import STEP_HASH_FUNCTIONS -from aim.utils.tracking import analytics - if TYPE_CHECKING: from aim.sdk.repo import Repo @@ -40,10 +38,8 @@ def __init__(self, run_hash: Optional[str] = None, else: if run_hash is None: self.hash = generate_run_hash() - analytics.track_event(event_name='[Run] Create new run') elif self.repo.run_exists(run_hash): self.hash = run_hash - analytics.track_event(event_name='[Run] Resume run') else: raise MissingRunError(f'Cannot find Run {run_hash} in aim Repo {self.repo.path}.') self._lock = self.repo.request_run_lock(self.hash) diff --git a/aim/utils/tracking.py b/aim/utils/tracking.py deleted file mode 100644 index dd8d4a2764..0000000000 --- a/aim/utils/tracking.py +++ /dev/null @@ -1,130 +0,0 @@ -import logging -import os -import json -import sys -import uuid -import contextlib - -import segment.analytics as sa # noqa - -logger = logging.getLogger(__name__) - -aim_profile_path = os.path.expanduser('~/.aim_profile') - - -class Analytics: - SEGMENT_WRITE_KEY = 'RrVqLHHD6WDXoFBkodO9KidodTtU92XO' - - def __init__(self): - self.dev_mode = False - self.initialized = False - - if os.path.exists(aim_profile_path): - with open(aim_profile_path, 'r') as fh: - try: - self._profile = json.load(fh) - except json.JSONDecodeError: - logger.error('Corrupted .aim_profile. Replacing with default.') - with self._autocommit(): - self._profile = self.default_profile() - else: - with self._autocommit(): - self._profile = self.default_profile() - - self._user_id = self._profile['user-id'] - - def track_install_event(self) -> None: - if not self.dev_mode and self.telemetry_enabled: - env_key = sys.exec_prefix - if env_key in self._profile['envs']: - is_new_env = False - from aim.__version__ import __version__ as aim_version - if aim_version == self._profile['envs'][env_key]: - return - else: - is_new_env = True - from aim.__version__ import __version__ as aim_version - - event_name = '[Aim] install' if is_new_env else '[Aim] upgrade' - self.track_event(event_name=event_name, aim_version=aim_version) - with self._autocommit(): - self._profile['envs'][env_key] = aim_version - - def track_event(self, *, event_name: str, **kwargs) -> None: - if not self.dev_mode and self.telemetry_enabled: - try: - self.initialize() - self._warn_once() - - # sa.track(self._user_id, event=event_name, properties=kwargs) - except Exception as e: # noqa - logger.debug(f'Failed to track event {event_name}. Reason: {e}.') - - def initialize(self) -> None: - if self.initialized: - return - - segment_logger = logging.getLogger('segment') - segment_logger.disabled = True - - # sa.write_key = Analytics.SEGMENT_WRITE_KEY - # sa.timeout = 2 # set send request timeout to 2 seconds - # sa.max_retries = 2 # set maximum send request retries to 2 - # - # sa.identify(user_id=self._user_id) - self.initialized = True - - @property - def telemetry_enabled(self) -> bool: - return self._profile['telemetry']['enable'] - - @telemetry_enabled.setter - def telemetry_enabled(self, enable: bool): - if enable != self.telemetry_enabled: - with self._autocommit(): - self._profile['telemetry']['enable'] = enable - - @property - def warning_shown(self) -> bool: - return self._profile['telemetry']['warning-shown'] - - @contextlib.contextmanager - def _autocommit(self): - yield - with open(aim_profile_path, 'w+') as fh: - json.dump(self._profile, fh, indent=2) - - def _warn_once(self): - assert self.telemetry_enabled - if not self.warning_shown: - alert_msg = 'Aim collects anonymous usage analytics.' - opt_out_msg = 'Read how to opt-out here: ' - opt_out_url = 'https://aimstack.readthedocs.io/en/latest/community/telemetry.html' - line_width = max(len(opt_out_msg), len(alert_msg), len(opt_out_url)) + 8 - logger.warning('-' * line_width) - logger.warning('{}{}{}'.format(' ' * ((line_width - len(alert_msg)) // 2), - alert_msg, - ' ' * ((line_width - len(alert_msg)) // 2))) - logger.warning('{}{}{}'.format(' ' * ((line_width - len(opt_out_msg)) // 2), - opt_out_msg, - ' ' * ((line_width - len(opt_out_msg)) // 2))) - logger.warning('{}{}{}'.format(' ' * ((line_width - len(opt_out_url)) // 2), - opt_out_url, - ' ' * ((line_width - len(opt_out_url)) // 2))) - logger.warning('-' * line_width) - with self._autocommit(): - self._profile['telemetry']['warning-shown'] = True - - @staticmethod - def default_profile(): - return { - 'envs': {}, - 'telemetry': { - 'enable': True, - 'warning-shown': False - }, - 'user-id': str(uuid.uuid4()) - } - - -analytics = Analytics() diff --git a/aim/web/api/dashboards/pydantic_models.py b/aim/web/api/dashboards/pydantic_models.py index 793ccd1f07..b008272ccc 100644 --- a/aim/web/api/dashboards/pydantic_models.py +++ b/aim/web/api/dashboards/pydantic_models.py @@ -8,7 +8,7 @@ class DashboardOut(BaseModel): id: UUID name: str - description: str = None + description: Optional[str] = None app_id: Optional[UUID] = None app_type: Optional[str] = None updated_at: datetime = 'Wed, 01 Jan 2021 16:12:07 GMT' diff --git a/aim/web/api/experiments/pydantic_models.py b/aim/web/api/experiments/pydantic_models.py index 3568648453..765d25289e 100644 --- a/aim/web/api/experiments/pydantic_models.py +++ b/aim/web/api/experiments/pydantic_models.py @@ -19,7 +19,7 @@ class ExperimentGetOut(BaseModel): description: Optional[str] = '' run_count: int archived: bool - creation_time: Optional[float] + creation_time: Optional[float] = None ExperimentListOut = List[ExperimentGetOut] diff --git a/aim/web/api/projects/views.py b/aim/web/api/projects/views.py index ae525c769d..2b26130e5c 100644 --- a/aim/web/api/projects/views.py +++ b/aim/web/api/projects/views.py @@ -18,7 +18,6 @@ from aim.web.api.utils import object_factory from aim.sdk.index_manager import RepoIndexManager from aim.storage.locking import AutoFileLock -from aim.utils.tracking import analytics projects_router = APIRouter() @@ -34,7 +33,7 @@ async def project_api(): 'name': project.name, 'path': project.path, 'description': project.description, - 'telemetry_enabled': analytics.telemetry_enabled, + 'telemetry_enabled': 0, } diff --git a/aim/web/configs.py b/aim/web/configs.py index cfb7143d55..e4e3cd3175 100644 --- a/aim/web/configs.py +++ b/aim/web/configs.py @@ -5,7 +5,6 @@ AIM_ENV_MODE_KEY = '__AIM_ENV_MODE__' AIM_LOG_LEVEL_KEY = '__AIM_LOG_LEVEL__' AIM_UI_MOUNTED_REPO_PATH = '__AIM_UI_MOUNT_REPO_PATH__' -AIM_UI_TELEMETRY_KEY = 'AIM_UI_TELEMETRY_ENABLED' AIM_UI_BASE_PATH = '__AIM_UI_BASE_PATH__' AIM_PROXY_URL = '__AIM_PROXY_URL__' AIM_PROFILER_KEY = '__AIM_PROFILER_ENABLED__' diff --git a/docs/source/community/telemetry.md b/docs/source/community/telemetry.md deleted file mode 100644 index b50e87d39a..0000000000 --- a/docs/source/community/telemetry.md +++ /dev/null @@ -1,36 +0,0 @@ -## Anonymized Telemetry -We constantly seek to improve Aim for the community. -Telemetry data helps us immensely by capturing anonymous usage analytics and statistics. -The "anonymous usage" means that no user-specific data is tracked. Aim will generate a unique -random ID, which is not tied to any user data (such as e-mail, UNIX username, etc.). -You will be notified when you run `aim up`, `aim server` commands, -as well as when running any SDK method which is tracked by Aim. -User-defined data is **NOT** tracked. Only the fact of certain event has happened is tracked. Here is the complete list of events tracked by Aim SDK: - -- Aim UI start (`aim up`) -- Aim Remote Tracking server start (`aim server`) -- Aim Watcher service start (`aim-watcher start`) -- New Repo initialization/re-initialization of existing Repo (`aim init`) -- New Run created -- Run resumed - -### Motivation -Aim uses segment's analytics toolkit to collect basic info about the usage: -- Anonymized stripped-down basic usage analytics; -- Anonymized number of experiments and run. We constantly improve the storage and UI for performance in case of many experiments. This type of usage analytics helps us to stay on top of the performance problem. - -### How to opt out -You can turn telemetry off by running the following CLI command: - -```shell -aim telemetry off -``` - -In order to turn telemetry back on, run - -```shell -aim telemetry on -``` - -> Note: Setting `AIM_UI_TELEMETRY_ENABLED` environment variable to `0` is obsolete. -You'll get a warning message if the variable is set, while telemetry is turned on. \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst index 7289a6158a..492a09ebb7 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -86,7 +86,6 @@ :name: community :caption: Community - community/telemetry.md generated/CHANGELOG.md .. raw:: html diff --git a/performance_tests/conftest.py b/performance_tests/conftest.py index f62fd17c6a..d18b484251 100644 --- a/performance_tests/conftest.py +++ b/performance_tests/conftest.py @@ -6,7 +6,6 @@ from pathlib import Path from aim.sdk.configs import AIM_REPO_NAME -from aim.utils.tracking import analytics from performance_tests.utils import get_baseline_filename TEST_REPO_PATHS = { @@ -42,7 +41,6 @@ def _cleanup_test_repo(path): def pytest_sessionstart(session): - analytics.dev_mode = True if os.environ.get('AIM_LOCAL_PERFORMANCE_TEST'): _init_test_repos() diff --git a/setup.py b/setup.py index ffe7b22cf1..072be62779 100644 --- a/setup.py +++ b/setup.py @@ -74,7 +74,6 @@ def package_files(directory): 'packaging>=15.0', 'python-dateutil', 'requests', - 'segment-analytics-python', ] if platform.machine() != 'arm64': diff --git a/tests/conftest.py b/tests/conftest.py index 8cdd353ec2..ca40382c9f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,7 +6,6 @@ from aim.cli.up.utils import build_db_upgrade_command from aim.web.configs import AIM_ENV_MODE_KEY from aim.sdk.configs import AIM_ENABLE_TRACKING_THREAD, AIM_REPO_NAME -from aim.utils.tracking import analytics TEST_REPO_PATH = '.aim-test-repo' @@ -30,8 +29,6 @@ def _upgrade_api_db(): def pytest_sessionstart(session): - analytics.dev_mode = True - os.environ[AIM_REPO_NAME] = TEST_REPO_PATH os.environ[AIM_ENV_MODE_KEY] = 'test'