diff --git a/mycroft/api/__init__.py b/mycroft/api/__init__.py index 615fd905e9..46db84a6d4 100644 --- a/mycroft/api/__init__.py +++ b/mycroft/api/__init__.py @@ -169,6 +169,13 @@ class DeviceApi(Api): "json": {"title": title, "body": body, "sender": sender} }) + def report_metric(self, name, data): + return self.request({ + "method": "POST", + "path": "/" + self.identity.uuid + "/metric/" + name, + "json": data + }) + def get(self): """ Retrieve all device information from the web backend """ return self.request({ diff --git a/mycroft/metrics/__init__.py b/mycroft/metrics/__init__.py index c71c9ea814..a9495f38e4 100644 --- a/mycroft/metrics/__init__.py +++ b/mycroft/metrics/__init__.py @@ -18,12 +18,23 @@ import time import requests +from mycroft.api import DeviceApi from mycroft.configuration import Configuration from mycroft.session import SessionManager from mycroft.util.log import LOG from mycroft.util.setup_base import get_version -config = Configuration.get().get('server') + +def report_metric(name, data): + """ + Report a general metric to the Mycroft servers + + Args: + name (str): Name of metric + data (dict): JSON dictionary to report. Must be valid JSON + """ + if Configuration().get()['opt_in']: + DeviceApi().report_metric(name, data) class Stopwatch(object): @@ -104,9 +115,10 @@ class MetricsAggregator(object): class MetricsPublisher(object): - def __init__(self, url=config.get("url"), enabled=config.get("metrics")): - self.url = url - self.enabled = enabled + def __init__(self, url=None, enabled=False): + conf = Configuration().get()['server'] + self.url = url or conf['url'] + self.enabled = enabled or conf['metrics'] def publish(self, events): if 'session_id' not in events: diff --git a/mycroft/skills/core.py b/mycroft/skills/core.py index c469b4b034..af7325b4d4 100644 --- a/mycroft/skills/core.py +++ b/mycroft/skills/core.py @@ -31,6 +31,7 @@ from mycroft.configuration import Configuration from mycroft.dialog import DialogLoader from mycroft.filesystem import FileSystemAccess from mycroft.messagebus.message import Message +from mycroft.metrics import report_metric from mycroft.skills.settings import SkillSettings from mycroft.util.log import LOG @@ -326,6 +327,16 @@ class MycroftSkill(object): """ return False + def report_metric(self, name, data): + """ + Report a skill metric to the Mycroft servers + + Args: + name (str): Name of metric + data (dict): JSON dictionary to report. Must be valid JSON + """ + report_metric(basename(self.root_dir) + '/' + name, data) + def send_email(self, title, body): """ Send an email to the registered user's email diff --git a/test/unittests/api/test_api.py b/test/unittests/api/test_api.py index 4f108db886..82ea705abf 100644 --- a/test/unittests/api/test_api.py +++ b/test/unittests/api/test_api.py @@ -170,6 +170,26 @@ class TestApi(unittest.TestCase): self.assertEquals( url, 'https://api-test.mycroft.ai/v1/device/1234/setting') + @mock.patch('mycroft.api.IdentityManager.get') + @mock.patch('mycroft.api.requests.request') + def test_device_report_metric(self, mock_request, mock_identity_get): + mock_request.return_value = create_response(200, {}) + mock_identity = mock.MagicMock() + mock_identity.is_expired.return_value = False + mock_identity.uuid = '1234' + mock_identity_get.return_value = mock_identity + device = mycroft.api.DeviceApi() + device.report_metric('mymetric', {'data': 'mydata'}) + url = mock_request.call_args[0][1] + params = mock_request.call_args[1] + + content_type = params['headers']['Content-Type'] + correct_json = {'data': 'mydata'} + self.assertEquals(content_type, 'application/json') + self.assertEquals(params['json'], correct_json) + self.assertEquals( + url, 'https://api-test.mycroft.ai/v1/device/1234/metric/mymetric') + @mock.patch('mycroft.api.IdentityManager.get') @mock.patch('mycroft.api.requests.request') def test_device_send_email(self, mock_request, mock_identity_get):