mirror of
https://github.com/facebook/sapling.git
synced 2024-10-11 01:07:15 +03:00
bc9087841c
Summary: Let's record the caller of the hg command that's using deprecated logic. In most cases the caller will be the unix username, but we'd like to get services to set an environment variable with their oncall so we could associate hg usage with specific oncalls and eventually automatically file tasks for using deprecated functionality. Reviewed By: markbt Differential Revision: D21891753 fbshipit-source-id: a4de0d348c583777cc3eeb9be26510e6af8b3a27
108 lines
3.4 KiB
Python
108 lines
3.4 KiB
Python
# Copyright (c) Facebook, Inc. and its affiliates.
|
|
#
|
|
# This software may be used and distributed according to the terms of the
|
|
# GNU General Public License version 2.
|
|
|
|
# sampling.py - sample collection extension
|
|
#
|
|
# Usage:
|
|
# - This extension enhances ui.log(category, message, key=value, ...)
|
|
# to also append filtered logged events as JSON to a file.
|
|
# - The events are separated by NULL characters: '\0'.
|
|
# - The file is either specified with the SCM_SAMPLING_FILEPATH environment
|
|
# variable or the sampling.filepath configuration.
|
|
# - If the file cannot be created or accessed, fails silently
|
|
#
|
|
# The configuration details can be found in the documentation of ui.log below
|
|
import os
|
|
import sys
|
|
import weakref
|
|
|
|
from edenscm.mercurial import encoding, json, localrepo, pycompat, registrar, util
|
|
|
|
|
|
configtable = {}
|
|
configitem = registrar.configitem(configtable)
|
|
|
|
configitem("sampling", "filepath", default="")
|
|
configitem("sampling", "debug", default=False)
|
|
|
|
onehundredmb = 100 * 1024 * 1024
|
|
|
|
|
|
def getrelativecwd(repo):
|
|
"""Returns the current directory relative to the working copy root, or
|
|
None if it's not in the working copy.
|
|
"""
|
|
cwd = pycompat.getcwdsafe()
|
|
if cwd.startswith(repo.root):
|
|
return os.path.normpath(cwd[len(repo.root) + 1 :])
|
|
else:
|
|
return None
|
|
|
|
|
|
def gettopdir(repo):
|
|
"""Returns the first component of the current directory, if it's in the
|
|
working copy.
|
|
"""
|
|
reldir = getrelativecwd(repo)
|
|
if reldir:
|
|
components = reldir.split(pycompat.ossep)
|
|
if len(components) > 0 and components[0] != ".":
|
|
return components[0]
|
|
else:
|
|
return None
|
|
|
|
|
|
def telemetry(reporef):
|
|
repo = reporef()
|
|
if repo is None:
|
|
return
|
|
ui = repo.ui
|
|
try:
|
|
try:
|
|
lfsmetrics = repo.svfs.lfsremoteblobstore.getlfsmetrics()
|
|
ui.log("command_metrics", **lfsmetrics)
|
|
except Exception:
|
|
pass
|
|
|
|
# Round to the nearest 100MB megabyte to reduce our storage size
|
|
maxrss = int(util.getmaxrss() / onehundredmb) * onehundredmb
|
|
|
|
# Log maxrss from within the hg process. The wrapper logs its own
|
|
# value (which is incorrect if chg is used) so the column is
|
|
# prefixed.
|
|
ui.log("command_info", hg_maxrss=maxrss, caller=util.caller())
|
|
except Exception as e:
|
|
ui.log("command_info", sampling_failure=str(e))
|
|
|
|
|
|
def reposetup(ui, repo):
|
|
# Don't setup telemetry for sshpeer's
|
|
if not isinstance(repo, localrepo.localrepository):
|
|
return
|
|
|
|
repo.ui.atexit(telemetry, weakref.ref(repo))
|
|
|
|
# Log other information that we don't want to log in the wrapper, if it's
|
|
# cheap to do so.
|
|
|
|
# Log the current directory bucketed to top-level directories, if enabled.
|
|
# This provides a very rough approximation of what area the users works in.
|
|
# developer config: sampling.logtopdir
|
|
if repo.ui.config("sampling", "logtopdir"):
|
|
topdir = gettopdir(repo)
|
|
if topdir:
|
|
ui.log("command_info", topdir=topdir)
|
|
|
|
# Allow environment variables to be directly mapped to metrics columns.
|
|
env = encoding.environ
|
|
tolog = {}
|
|
for conf in ui.configlist("sampling", "env_vars"):
|
|
if conf in env:
|
|
# The default name is a lowercased version of the environment
|
|
# variable name; in the future, an override config could be used to
|
|
# customize it.
|
|
tolog["env_" + conf.lower()] = env[conf]
|
|
ui.log("env_vars", **tolog)
|