Bug 1874684 - Part 28: Return DateDuration from DifferenceISODateTime. r=mgaudet
[gecko.git] / python / mozbuild / mozbuild / telemetry.py
blobce2e99ca73d91943074f4bf2f7664e42e42c4f0c
1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 """
6 This file contains functions used for telemetry.
7 """
9 import os
10 import platform
11 import sys
13 import distro
14 import mozpack.path as mozpath
17 def cpu_brand_linux():
18 """
19 Read the CPU brand string out of /proc/cpuinfo on Linux.
20 """
21 with open("/proc/cpuinfo", "r") as f:
22 for line in f:
23 if line.startswith("model name"):
24 _, brand = line.split(": ", 1)
25 return brand.rstrip()
26 # not found?
27 return None
30 def cpu_brand_windows():
31 """
32 Read the CPU brand string from the registry on Windows.
33 """
34 try:
35 import _winreg
36 except ImportError:
37 import winreg as _winreg
39 try:
40 h = _winreg.OpenKey(
41 _winreg.HKEY_LOCAL_MACHINE,
42 r"HARDWARE\DESCRIPTION\System\CentralProcessor\0",
44 (brand, ty) = _winreg.QueryValueEx(h, "ProcessorNameString")
45 if ty == _winreg.REG_SZ:
46 return brand
47 except WindowsError:
48 pass
49 return None
52 def cpu_brand_mac():
53 """
54 Get the CPU brand string via sysctl on macos.
55 """
56 import ctypes
57 import ctypes.util
59 libc = ctypes.cdll.LoadLibrary(ctypes.util.find_library("c"))
60 # First, find the required buffer size.
61 bufsize = ctypes.c_size_t(0)
62 result = libc.sysctlbyname(
63 b"machdep.cpu.brand_string", None, ctypes.byref(bufsize), None, 0
65 if result != 0:
66 return None
67 bufsize.value += 1
68 buf = ctypes.create_string_buffer(bufsize.value)
69 # Now actually get the value.
70 result = libc.sysctlbyname(
71 b"machdep.cpu.brand_string", buf, ctypes.byref(bufsize), None, 0
73 if result != 0:
74 return None
76 return buf.value.decode()
79 def get_cpu_brand():
80 """
81 Get the CPU brand string as returned by CPUID.
82 """
83 return {
84 "Linux": cpu_brand_linux,
85 "Windows": cpu_brand_windows,
86 "Darwin": cpu_brand_mac,
87 }.get(platform.system(), lambda: None)()
90 def get_psutil_stats():
91 """Return whether psutil exists and its associated stats.
93 @returns (bool, int, int, int) whether psutil exists, the logical CPU count,
94 physical CPU count, and total number of bytes of memory.
95 """
96 try:
97 import psutil
99 return (
100 True,
101 psutil.cpu_count(),
102 psutil.cpu_count(logical=False),
103 psutil.virtual_memory().total,
105 except ImportError:
106 return False, None, None, None
109 def filter_args(command, argv, topsrcdir, topobjdir, cwd=None):
111 Given the full list of command-line arguments, remove anything up to and including `command`,
112 and attempt to filter absolute pathnames out of any arguments after that.
114 if cwd is None:
115 cwd = os.getcwd()
117 # Each key is a pathname and the values are replacement sigils
118 paths = {
119 topsrcdir: "$topsrcdir/",
120 topobjdir: "$topobjdir/",
121 mozpath.normpath(os.path.expanduser("~")): "$HOME/",
122 # This might override one of the existing entries, that's OK.
123 # We don't use a sigil here because we treat all arguments as potentially relative
124 # paths, so we'd like to get them back as they were specified.
125 mozpath.normpath(cwd): "",
128 args = list(argv)
129 while args:
130 a = args.pop(0)
131 if a == command:
132 break
134 def filter_path(p):
135 p = mozpath.abspath(p)
136 base = mozpath.basedir(p, paths.keys())
137 if base:
138 return paths[base] + mozpath.relpath(p, base)
139 # Best-effort.
140 return "<path omitted>"
142 return [filter_path(arg) for arg in args]
145 def get_distro_and_version():
146 if sys.platform.startswith("linux"):
147 dist, version, _ = distro.linux_distribution(full_distribution_name=False)
148 return dist, version
149 elif sys.platform.startswith("darwin"):
150 return "macos", platform.mac_ver()[0]
151 elif sys.platform.startswith("win32") or sys.platform.startswith("msys"):
152 ver = sys.getwindowsversion()
153 return "windows", "%s.%s.%s" % (ver.major, ver.minor, ver.build)
154 else:
155 return sys.platform, ""
158 def get_shell_info():
159 """Returns if the current shell was opened by vscode and if it's a SSH connection"""
161 return (
162 True if "vscode" in os.getenv("TERM_PROGRAM", "") else False,
163 bool(os.getenv("SSH_CLIENT", False)),
167 def get_vscode_running():
168 """Return if the vscode is currently running."""
169 try:
170 import psutil
172 for proc in psutil.process_iter():
173 try:
174 # On Windows we have "Code.exe"
175 # On MacOS we have "Code Helper (Renderer)"
176 # On Linux we have ""
177 if (
178 proc.name == "Code.exe"
179 or proc.name == "Code Helper (Renderer)"
180 or proc.name == "code"
182 return True
183 except Exception:
184 # may not be able to access process info for all processes
185 continue
186 except Exception:
187 # On some platforms, sometimes, the generator throws an
188 # exception preventing us to enumerate.
189 return False
191 return False