Created
November 14, 2017 02:39
-
-
Save mhammond/77af60618b3ed3e9cb7abde6f0a69d26 to your computer and use it in GitHub Desktop.
Number of "Services.logins is undefined" errors per day
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# coding: utf-8 | |
# In[1]: | |
from moztelemetry import get_pings | |
import datetime | |
import time | |
import re | |
channel = None # None, "nightly", etc | |
fraction = 0.2 | |
ndays = 200 # number of days in the past | |
earliest = time.time() - ndays * 24 * 60 * 60 | |
latest = time.time() # - 1 * 24 * 60 * 60 # one day back | |
# for efficiency, we only ask for ping submitted within these dates. | |
earliest_ping = (datetime.date.fromtimestamp(earliest) - datetime.timedelta(days=2)).strftime("%Y%m%d") | |
latest_ping = datetime.date.fromtimestamp(latest).strftime("%Y%m%d") | |
valueKeys = ["error", "from", "code"] | |
reOSError = re.compile("(Win|Unix) error (\\d+) .*", re.DOTALL) | |
reInvalidProperty = re.compile("(Invalid value for property '.*'): .*$") | |
def getPlatform(ping): | |
application = ping["application"] | |
if "name" not in application or application.get("name") == "Fennec": | |
return "android" # ?? | |
return "iOS" if application.get("architecture") == "arm" else "desktop" | |
def isOurFailure(failure): | |
name = failure["name"] | |
value = "<none>" | |
for maybe in valueKeys: | |
if maybe in failure: | |
value = unicode(failure[maybe]).strip() | |
break | |
if "Services.logins is undefined" in value: | |
return True | |
return False | |
def mapFailures(ping): | |
try: | |
syncs = ping["payload"]["syncs"] | |
if getPlatform(ping) != "desktop": | |
return [] | |
except KeyError: | |
return [] | |
result = [] | |
for sync in syncs: | |
try: | |
day = datetime.date.fromtimestamp(sync["when"] / 1000.0) | |
when = sync["when"] / 1000 | |
except (ValueError, KeyError): | |
continue # ignore bad timestamps | |
if when < earliest or when > latest: | |
continue | |
for engine in sync.get("engines", []): | |
if type(engine) != dict: # seeing a float here too in one ping! | |
continue | |
if engine.get("name") != "passwords": | |
continue | |
if "failureReason" in engine and isOurFailure(engine["failureReason"]): | |
result.append((day, 1)) | |
return result | |
s = get_pings(sc, doc_type='sync', submission_date=(earliest_ping, latest_ping), channel=channel, fraction=fraction).flatMap(mapFailures) | |
# In[2]: | |
from matplotlib.dates import date2num | |
r = s.reduceByKey(lambda a, b: a+b).sortByKey() | |
dates = r.map(lambda r: date2num(r[0])).collect() | |
counts = r.map(lambda r: r[1]).collect() | |
# In[3]: | |
import matplotlib.pyplot as plt | |
import matplotlib.ticker as ticker | |
from matplotlib.dates import date2num, DateFormatter | |
from pylab import rcParams | |
import itertools | |
get_ipython().magic(u"config InlineBackend.figure_format = 'svg'") | |
rcParams['figure.figsize'] = 102, 10 | |
rcParams.update({'font.size': 6}) | |
fig, ax = plt.subplots() | |
ax.plot_date(dates, counts, ls='-') | |
dateFmt = DateFormatter('%Y-%m-%d') | |
ax.xaxis.set_major_formatter(dateFmt) | |
ax.xaxis.set_ticks(dates) | |
for tick in ax.get_xticklabels(): | |
tick.set_rotation(45) | |
plt.show() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment