From 9aaf5ae5e8662fd40ae0e973a1eaa2e64847587b Mon Sep 17 00:00:00 2001 From: houk-ms Date: Fri, 4 Sep 2020 10:10:19 +0800 Subject: [PATCH 1/3] add session id for Telemetry --- .../azure/cli/core/telemetry.py | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/azure-cli-core/azure/cli/core/telemetry.py b/src/azure-cli-core/azure/cli/core/telemetry.py index cc10885e88b..a84a955a79e 100644 --- a/src/azure-cli-core/azure/cli/core/telemetry.py +++ b/src/azure-cli-core/azure/cli/core/telemetry.py @@ -104,7 +104,7 @@ def _get_base_properties(self): 'Reserved.ChannelUsed': 'AI', 'Reserved.EventId': str(uuid.uuid4()), 'Reserved.SequenceNumber': 1, - 'Reserved.SessionId': str(uuid.uuid4()), + 'Reserved.SessionId': _get_session_id(), 'Reserved.TimeSinceSessionStart': 0, 'Reserved.DataModel.Source': 'DataModelAPI', @@ -407,6 +407,33 @@ def _get_installation_id(): return _get_profile().get_installation_id() +@decorators.suppress_all_exceptions(fallback_return="") +def _get_session_id(): + # This function works as a workaround to get the terminal info: when the difference + # of create time between current process and its parent process is larger than a given + # threshold, the parent process will be viewed as a terminal process. + + def get_hash_result(content): + import hashlib + + hasher = hashlib.sha256() + hasher.update(content.encode('utf-8')) + return hasher.hexdigest() + + # Usually, more than one layer of sub-process will be called when excuting a CLI command. While, the create time + # of these processes will be very close, usually in several milliseconds. We use 1 second as the threshold here. + time_threshold = 1 + import psutil + process = psutil.Process() + while process and process.ppid() and process.pid != process.ppid(): + parent_process = process.parent() + if parent_process and process.create_time() - parent_process.create_time() > time_threshold: + content = '{}{}{}'.format(_get_installation_id(), parent_process.create_time(), parent_process.pid) + return get_hash_result(content) + process = parent_process + return "" + + @decorators.call_once @decorators.suppress_all_exceptions(fallback_return=None) def _get_profile(): From c0cfb6ab3af3b9ff0b3c59d33c509b385895dc75 Mon Sep 17 00:00:00 2001 From: houk-ms Date: Tue, 8 Sep 2020 11:24:50 +0800 Subject: [PATCH 2/3] add psutil dependency --- src/azure-cli-core/azure/cli/core/telemetry.py | 12 ++++++------ src/azure-cli/requirements.py3.Darwin.txt | 1 + src/azure-cli/requirements.py3.Linux.txt | 1 + src/azure-cli/requirements.py3.windows.txt | 1 + src/azure-cli/setup.py | 4 ++++ 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/azure-cli-core/azure/cli/core/telemetry.py b/src/azure-cli-core/azure/cli/core/telemetry.py index a84a955a79e..44b719fcfb9 100644 --- a/src/azure-cli-core/azure/cli/core/telemetry.py +++ b/src/azure-cli-core/azure/cli/core/telemetry.py @@ -409,9 +409,7 @@ def _get_installation_id(): @decorators.suppress_all_exceptions(fallback_return="") def _get_session_id(): - # This function works as a workaround to get the terminal info: when the difference - # of create time between current process and its parent process is larger than a given - # threshold, the parent process will be viewed as a terminal process. + # As a workaround to get the terminal info as SessionId, this function may not be accurate. def get_hash_result(content): import hashlib @@ -420,10 +418,12 @@ def get_hash_result(content): hasher.update(content.encode('utf-8')) return hasher.hexdigest() - # Usually, more than one layer of sub-process will be called when excuting a CLI command. While, the create time - # of these processes will be very close, usually in several milliseconds. We use 1 second as the threshold here. - time_threshold = 1 + # Usually, more than one layer of sub-process will be started when excuting a CLI command. While, the create time + # of these sub-processes will be very close, usually in several milliseconds. We use 1 second as the threshold here. + # When the difference of create time between current process and its parent process is larger than the threshold, + # the parent process will be viewed as the terminal process. import psutil + time_threshold = 1 process = psutil.Process() while process and process.ppid() and process.pid != process.ppid(): parent_process = process.parent() diff --git a/src/azure-cli/requirements.py3.Darwin.txt b/src/azure-cli/requirements.py3.Darwin.txt index 90ff777b923..02d9b951e14 100644 --- a/src/azure-cli/requirements.py3.Darwin.txt +++ b/src/azure-cli/requirements.py3.Darwin.txt @@ -108,6 +108,7 @@ oauthlib==3.0.1 paramiko==2.6.0 pbr==5.3.1 portalocker==1.4.0 +psutil==5.7.2 pycparser==2.19 PyJWT==1.7.1 PyNaCl==1.3.0 diff --git a/src/azure-cli/requirements.py3.Linux.txt b/src/azure-cli/requirements.py3.Linux.txt index 90ff777b923..02d9b951e14 100644 --- a/src/azure-cli/requirements.py3.Linux.txt +++ b/src/azure-cli/requirements.py3.Linux.txt @@ -108,6 +108,7 @@ oauthlib==3.0.1 paramiko==2.6.0 pbr==5.3.1 portalocker==1.4.0 +psutil==5.7.2 pycparser==2.19 PyJWT==1.7.1 PyNaCl==1.3.0 diff --git a/src/azure-cli/requirements.py3.windows.txt b/src/azure-cli/requirements.py3.windows.txt index 8bd62e5f3c7..6294a4eb3f7 100644 --- a/src/azure-cli/requirements.py3.windows.txt +++ b/src/azure-cli/requirements.py3.windows.txt @@ -106,6 +106,7 @@ oauthlib==3.0.1 paramiko==2.6.0 pbr==5.3.1 portalocker==1.2.1 +psutil==5.7.2 pycparser==2.19 PyJWT==1.7.1 PyNaCl==1.3.0 diff --git a/src/azure-cli/setup.py b/src/azure-cli/setup.py index 7636fc411e0..ea60cbc82ff 100644 --- a/src/azure-cli/setup.py +++ b/src/azure-cli/setup.py @@ -139,6 +139,10 @@ 'jsondiff==1.2.0' ] +# dependencies for specific OSes +if not sys.platform.startswith('cygwin'): + DEPENDENCIES.append('psutil~=5.7') + TESTS_REQUIRE = [ 'mock~=4.0' ] From e3ea8ea5c9a7c9864bf16db36dbd0eba83421e41 Mon Sep 17 00:00:00 2001 From: houk-ms Date: Tue, 8 Sep 2020 12:19:09 +0800 Subject: [PATCH 3/3] fix code style --- src/azure-cli-core/azure/cli/core/telemetry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/azure-cli-core/azure/cli/core/telemetry.py b/src/azure-cli-core/azure/cli/core/telemetry.py index 44b719fcfb9..852c6468b30 100644 --- a/src/azure-cli-core/azure/cli/core/telemetry.py +++ b/src/azure-cli-core/azure/cli/core/telemetry.py @@ -420,7 +420,7 @@ def get_hash_result(content): # Usually, more than one layer of sub-process will be started when excuting a CLI command. While, the create time # of these sub-processes will be very close, usually in several milliseconds. We use 1 second as the threshold here. - # When the difference of create time between current process and its parent process is larger than the threshold, + # When the difference of create time between current process and its parent process is larger than the threshold, # the parent process will be viewed as the terminal process. import psutil time_threshold = 1