{"action":"created","comment":{"url":"https://api.github.com/repos/open-craft/opencraft/pulls/comments/66019055","id":66019055,"diff_hunk":"@@ -0,0 +1,95 @@\n+# -*- coding: utf-8 -*-\n+#\n+# OpenCraft -- tools to aid developing and hosting free software projects\n+# Copyright (C) 2015-2016 OpenCraft <xavier@opencraft.com>\n+#\n+# This program is free software: you can redistribute it and/or modify\n+# it under the terms of the GNU Affero General Public License as\n+# published by the Free Software Foundation, either version 3 of the\n+# License, or (at your option) any later version.\n+#\n+# This program is distributed in the hope that it will be useful,\n+# but WITHOUT ANY WARRANTY; without even the implied warranty of\n+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n+# GNU Affero General Public License for more details.\n+#\n+# You should have received a copy of the GNU Affero General Public License\n+# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n+#\n+\"\"\"\n+Open edX instance monitoring mixin\n+\"\"\"\n+\n+# Imports #####################################################################\n+\n+from django.conf import settings\n+from django.db import models\n+\n+from instance import newrelic\n+\n+\n+# Classes #####################################################################\n+\n+class OpenEdXMonitoringMixin:\n+    \"\"\"\n+    Mixin that sets up availability monitoring for Open edX instances.\n+    \"\"\"\n+    def enable_monitoring(self):\n+        \"\"\"\n+        Enable monitoring on this instance.\n+        \"\"\"\n+        if not settings.NEWRELIC_ADMIN_USER_API_KEY:\n+            return\n+\n+        # Delete existing monitors if they don't monitor this instance's\n+        # public urls\n+        monitors = newrelic.get_synthetics_monitors()","path":"instance/models/mixins/openedx_monitoring.py","position":46,"original_position":46,"commit_id":"05578e947b97fcc5ce0bbd44ef53c848524e0c30","original_commit_id":"05578e947b97fcc5ce0bbd44ef53c848524e0c30","user":{"login":"mtyaka","id":32585,"avatar_url":"https://avatars.githubusercontent.com/u/32585?v=3","gravatar_id":"","url":"https://api.github.com/users/mtyaka","html_url":"https://github.com/mtyaka","followers_url":"https://api.github.com/users/mtyaka/followers","following_url":"https://api.github.com/users/mtyaka/following{/other_user}","gists_url":"https://api.github.com/users/mtyaka/gists{/gist_id}","starred_url":"https://api.github.com/users/mtyaka/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mtyaka/subscriptions","organizations_url":"https://api.github.com/users/mtyaka/orgs","repos_url":"https://api.github.com/users/mtyaka/repos","events_url":"https://api.github.com/users/mtyaka/events{/privacy}","received_events_url":"https://api.github.com/users/mtyaka/received_events","type":"User","site_admin":false},"body":"@omarkhan Nit: Maybe we should add a `uri` field to `NewRelicAvailabilityMonitor` model so that we don't have to fetch the full global list of monitors every time?","created_at":"2016-06-07T07:03:02Z","updated_at":"2016-06-07T07:03:02Z","html_url":"https://github.com/open-craft/opencraft/pull/99#discussion_r66019055","pull_request_url":"https://api.github.com/repos/open-craft/opencraft/pulls/99","_links":{"self":{"href":"https://api.github.com/repos/open-craft/opencraft/pulls/comments/66019055"},"html":{"href":"https://github.com/open-craft/opencraft/pull/99#discussion_r66019055"},"pull_request":{"href":"https://api.github.com/repos/open-craft/opencraft/pulls/99"}}},"pull_request":{"url":"https://api.github.com/repos/open-craft/opencraft/pulls/99","id":72340579,"html_url":"https://github.com/open-craft/opencraft/pull/99","diff_url":"https://github.com/open-craft/opencraft/pull/99.diff","patch_url":"https://github.com/open-craft/opencraft/pull/99.patch","issue_url":"https://api.github.com/repos/open-craft/opencraft/issues/99","number":99,"state":"open","locked":false,"title":"Add newrelic monitoring for instances","user":{"login":"omarkhan","id":793379,"avatar_url":"https://avatars.githubusercontent.com/u/793379?v=3","gravatar_id":"","url":"https://api.github.com/users/omarkhan","html_url":"https://github.com/omarkhan","followers_url":"https://api.github.com/users/omarkhan/followers","following_url":"https://api.github.com/users/omarkhan/following{/other_user}","gists_url":"https://api.github.com/users/omarkhan/gists{/gist_id}","starred_url":"https://api.github.com/users/omarkhan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/omarkhan/subscriptions","organizations_url":"https://api.github.com/users/omarkhan/orgs","repos_url":"https://api.github.com/users/omarkhan/repos","events_url":"https://api.github.com/users/omarkhan/events{/privacy}","received_events_url":"https://api.github.com/users/omarkhan/received_events","type":"User","site_admin":false},"body":"This pull request adds New Relic monitoring for instances. Monitoring is activated for new app servers by setting the `NEWRELIC_LICENSE_KEY` and `NEWRELIC_ADMIN_USER_API_KEY` settings.\r\n\r\nApp and server monitoring is activated if `NEWRELIC_LICENSE_KEY` is set, and is configured using the following ansible vars:\r\n\r\n- `COMMON_ENABLE_NEWRELIC` for server monitoring\r\n- `COMMON_ENABLE_NEWRELIC_APP` for app monitoring\r\n- `COMMON_ENVIRONMENT` global prefix for instances in the newrelic UI\r\n- `COMMON_DEPLOYMENT` instance-specific prefix in the newrelic UI\r\n- `NEWRELIC_LICENSE_KEY`\r\n\r\nAvailability monitoring using [Synthetics](https://newrelic.com/synthetics) is activated if the `NEWRELIC_ADMIN_USER_API_KEY` is set. Monitors are created when an app server is activated, and removed when an instance is deleted. Email alerts are set up for email addresses in the `ADMINS` list.\r\n\r\n#### Testing\r\n\r\n- Deploy this branch to stage\r\n- Provision a new instance\r\n- Open the LMS and Studio to cause data to be sent to New Relic\r\n- Go to the [New Relic applications page](https://rpm.newrelic.com/accounts/1346955/applications). The LMS, Studio, workers and xqueue for your instance should all be monitored\r\n- Go to the [Synthetics](https://synthetics.newrelic.com/accounts/1346955/synthetics) page. Availability monitors should be set up for the LMS, Studio, and LMS preview urls\r\n- Open each monitor and click on 'Alert notifications'. ops@opencraft.com should be in the notifications list\r\n- Kill the LMS and/or Studio for your instance. After a while an email alert should be sent to ops@opencraft.com\r\n- Delete the instance\r\n- Check that the Synthetics monitors have been removed","created_at":"2016-06-02T12:52:00Z","updated_at":"2016-06-07T07:03:02Z","closed_at":null,"merged_at":null,"merge_commit_sha":"86d227a1de40d4bb3c85186f2342be230995df07","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/open-craft/opencraft/pulls/99/commits","review_comments_url":"https://api.github.com/repos/open-craft/opencraft/pulls/99/comments","review_comment_url":"https://api.github.com/repos/open-craft/opencraft/pulls/comments{/number}","comments_url":"https://api.github.com/repos/open-craft/opencraft/issues/99/comments","statuses_url":"https://api.github.com/repos/open-craft/opencraft/statuses/05578e947b97fcc5ce0bbd44ef53c848524e0c30","head":{"label":"open-craft:omar/newrelic","ref":"omar/newrelic","sha":"05578e947b97fcc5ce0bbd44ef53c848524e0c30","user":{"login":"open-craft","id":7414786,"avatar_url":"https://avatars.githubusercontent.com/u/7414786?v=3","gravatar_id":"","url":"https://api.github.com/users/open-craft","html_url":"https://github.com/open-craft","followers_url":"https://api.github.com/users/open-craft/followers","following_url":"https://api.github.com/users/open-craft/following{/other_user}","gists_url":"https://api.github.com/users/open-craft/gists{/gist_id}","starred_url":"https://api.github.com/users/open-craft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/open-craft/subscriptions","organizations_url":"https://api.github.com/users/open-craft/orgs","repos_url":"https://api.github.com/users/open-craft/repos","events_url":"https://api.github.com/users/open-craft/events{/privacy}","received_events_url":"https://api.github.com/users/open-craft/received_events","type":"Organization","site_admin":false},"repo":{"id":40447973,"name":"opencraft","full_name":"open-craft/opencraft","owner":{"login":"open-craft","id":7414786,"avatar_url":"https://avatars.githubusercontent.com/u/7414786?v=3","gravatar_id":"","url":"https://api.github.com/users/open-craft","html_url":"https://github.com/open-craft","followers_url":"https://api.github.com/users/open-craft/followers","following_url":"https://api.github.com/users/open-craft/following{/other_user}","gists_url":"https://api.github.com/users/open-craft/gists{/gist_id}","starred_url":"https://api.github.com/users/open-craft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/open-craft/subscriptions","organizations_url":"https://api.github.com/users/open-craft/orgs","repos_url":"https://api.github.com/users/open-craft/repos","events_url":"https://api.github.com/users/open-craft/events{/privacy}","received_events_url":"https://api.github.com/users/open-craft/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/open-craft/opencraft","description":"OpenCraft - Instance Manager","fork":false,"url":"https://api.github.com/repos/open-craft/opencraft","forks_url":"https://api.github.com/repos/open-craft/opencraft/forks","keys_url":"https://api.github.com/repos/open-craft/opencraft/keys{/key_id}","collaborators_url":"https://api.github.com/repos/open-craft/opencraft/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/open-craft/opencraft/teams","hooks_url":"https://api.github.com/repos/open-craft/opencraft/hooks","issue_events_url":"https://api.github.com/repos/open-craft/opencraft/issues/events{/number}","events_url":"https://api.github.com/repos/open-craft/opencraft/events","assignees_url":"https://api.github.com/repos/open-craft/opencraft/assignees{/user}","branches_url":"https://api.github.com/repos/open-craft/opencraft/branches{/branch}","tags_url":"https://api.github.com/repos/open-craft/opencraft/tags","blobs_url":"https://api.github.com/repos/open-craft/opencraft/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/open-craft/opencraft/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/open-craft/opencraft/git/refs{/sha}","trees_url":"https://api.github.com/repos/open-craft/opencraft/git/trees{/sha}","statuses_url":"https://api.github.com/repos/open-craft/opencraft/statuses/{sha}","languages_url":"https://api.github.com/repos/open-craft/opencraft/languages","stargazers_url":"https://api.github.com/repos/open-craft/opencraft/stargazers","contributors_url":"https://api.github.com/repos/open-craft/opencraft/contributors","subscribers_url":"https://api.github.com/repos/open-craft/opencraft/subscribers","subscription_url":"https://api.github.com/repos/open-craft/opencraft/subscription","commits_url":"https://api.github.com/repos/open-craft/opencraft/commits{/sha}","git_commits_url":"https://api.github.com/repos/open-craft/opencraft/git/commits{/sha}","comments_url":"https://api.github.com/repos/open-craft/opencraft/comments{/number}","issue_comment_url":"https://api.github.com/repos/open-craft/opencraft/issues/comments{/number}","contents_url":"https://api.github.com/repos/open-craft/opencraft/contents/{+path}","compare_url":"https://api.github.com/repos/open-craft/opencraft/compare/{base}...{head}","merges_url":"https://api.github.com/repos/open-craft/opencraft/merges","archive_url":"https://api.github.com/repos/open-craft/opencraft/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/open-craft/opencraft/downloads","issues_url":"https://api.github.com/repos/open-craft/opencraft/issues{/number}","pulls_url":"https://api.github.com/repos/open-craft/opencraft/pulls{/number}","milestones_url":"https://api.github.com/repos/open-craft/opencraft/milestones{/number}","notifications_url":"https://api.github.com/repos/open-craft/opencraft/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/open-craft/opencraft/labels{/name}","releases_url":"https://api.github.com/repos/open-craft/opencraft/releases{/id}","deployments_url":"https://api.github.com/repos/open-craft/opencraft/deployments","created_at":"2015-08-09T19:35:05Z","updated_at":"2016-05-25T11:23:15Z","pushed_at":"2016-06-07T02:37:36Z","git_url":"git://github.com/open-craft/opencraft.git","ssh_url":"git@github.com:open-craft/opencraft.git","clone_url":"https://github.com/open-craft/opencraft.git","svn_url":"https://github.com/open-craft/opencraft","homepage":null,"size":2201,"stargazers_count":7,"watchers_count":7,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":8,"mirror_url":null,"open_issues_count":9,"forks":8,"open_issues":9,"watchers":7,"default_branch":"master"}},"base":{"label":"open-craft:master","ref":"master","sha":"f131c8bcca6fe1036e1fe2d6d98e488a1d46d71e","user":{"login":"open-craft","id":7414786,"avatar_url":"https://avatars.githubusercontent.com/u/7414786?v=3","gravatar_id":"","url":"https://api.github.com/users/open-craft","html_url":"https://github.com/open-craft","followers_url":"https://api.github.com/users/open-craft/followers","following_url":"https://api.github.com/users/open-craft/following{/other_user}","gists_url":"https://api.github.com/users/open-craft/gists{/gist_id}","starred_url":"https://api.github.com/users/open-craft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/open-craft/subscriptions","organizations_url":"https://api.github.com/users/open-craft/orgs","repos_url":"https://api.github.com/users/open-craft/repos","events_url":"https://api.github.com/users/open-craft/events{/privacy}","received_events_url":"https://api.github.com/users/open-craft/received_events","type":"Organization","site_admin":false},"repo":{"id":40447973,"name":"opencraft","full_name":"open-craft/opencraft","owner":{"login":"open-craft","id":7414786,"avatar_url":"https://avatars.githubusercontent.com/u/7414786?v=3","gravatar_id":"","url":"https://api.github.com/users/open-craft","html_url":"https://github.com/open-craft","followers_url":"https://api.github.com/users/open-craft/followers","following_url":"https://api.github.com/users/open-craft/following{/other_user}","gists_url":"https://api.github.com/users/open-craft/gists{/gist_id}","starred_url":"https://api.github.com/users/open-craft/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/open-craft/subscriptions","organizations_url":"https://api.github.com/users/open-craft/orgs","repos_url":"https://api.github.com/users/open-craft/repos","events_url":"https://api.github.com/users/open-craft/events{/privacy}","received_events_url":"https://api.github.com/users/open-craft/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/open-craft/opencraft","description":"OpenCraft - Instance Manager","fork":false,"url":"https://api.github.com/repos/open-craft/opencraft","forks_url":"https://api.github.com/repos/open-craft/opencraft/forks","keys_url":"https://api.github.com/repos/open-craft/opencraft/keys{/key_id}","collaborators_url":"https://api.github.com/repos/open-craft/opencraft/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/open-craft/opencraft/teams","hooks_url":"https://api.github.com/repos/open-craft/opencraft/hooks","issue_events_url":"https://api.github.com/repos/open-craft/opencraft/issues/events{/number}","events_url":"https://api.github.com/repos/open-craft/opencraft/events","assignees_url":"https://api.github.com/repos/open-craft/opencraft/assignees{/user}","branches_url":"https://api.github.com/repos/open-craft/opencraft/branches{/branch}","tags_url":"https://api.github.com/repos/open-craft/opencraft/tags","blobs_url":"https://api.github.com/repos/open-craft/opencraft/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/open-craft/opencraft/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/open-craft/opencraft/git/refs{/sha}","trees_url":"https://api.github.com/repos/open-craft/opencraft/git/trees{/sha}","statuses_url":"https://api.github.com/repos/open-craft/opencraft/statuses/{sha}","languages_url":"https://api.github.com/repos/open-craft/opencraft/languages","stargazers_url":"https://api.github.com/repos/open-craft/opencraft/stargazers","contributors_url":"https://api.github.com/repos/open-craft/opencraft/contributors","subscribers_url":"https://api.github.com/repos/open-craft/opencraft/subscribers","subscription_url":"https://api.github.com/repos/open-craft/opencraft/subscription","commits_url":"https://api.github.com/repos/open-craft/opencraft/commits{/sha}","git_commits_url":"https://api.github.com/repos/open-craft/opencraft/git/commits{/sha}","comments_url":"https://api.github.com/repos/open-craft/opencraft/comments{/number}","issue_comment_url":"https://api.github.com/repos/open-craft/opencraft/issues/comments{/number}","contents_url":"https://api.github.com/repos/open-craft/opencraft/contents/{+path}","compare_url":"https://api.github.com/repos/open-craft/opencraft/compare/{base}...{head}","merges_url":"https://api.github.com/repos/open-craft/opencraft/merges","archive_url":"https://api.github.com/repos/open-craft/opencraft/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/open-craft/opencraft/downloads","issues_url":"https://api.github.com/repos/open-craft/opencraft/issues{/number}","pulls_url":"https://api.github.com/repos/open-craft/opencraft/pulls{/number}","milestones_url":"https://api.github.com/repos/open-craft/opencraft/milestones{/number}","notifications_url":"https://api.github.com/repos/open-craft/opencraft/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/open-craft/opencraft/labels{/name}","releases_url":"https://api.github.com/repos/open-craft/opencraft/releases{/id}","deployments_url":"https://api.github.com/repos/open-craft/opencraft/deployments","created_at":"2015-08-09T19:35:05Z","updated_at":"2016-05-25T11:23:15Z","pushed_at":"2016-06-07T02:37:36Z","git_url":"git://github.com/open-craft/opencraft.git","ssh_url":"git@github.com:open-craft/opencraft.git","clone_url":"https://github.com/open-craft/opencraft.git","svn_url":"https://github.com/open-craft/opencraft","homepage":null,"size":2201,"stargazers_count":7,"watchers_count":7,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":8,"mirror_url":null,"open_issues_count":9,"forks":8,"open_issues":9,"watchers":7,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/open-craft/opencraft/pulls/99"},"html":{"href":"https://github.com/open-craft/opencraft/pull/99"},"issue":{"href":"https://api.github.com/repos/open-craft/opencraft/issues/99"},"comments":{"href":"https://api.github.com/repos/open-craft/opencraft/issues/99/comments"},"review_comments":{"href":"https://api.github.com/repos/open-craft/opencraft/pulls/99/comments"},"review_comment":{"href":"https://api.github.com/repos/open-craft/opencraft/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/open-craft/opencraft/pulls/99/commits"},"statuses":{"href":"https://api.github.com/repos/open-craft/opencraft/statuses/05578e947b97fcc5ce0bbd44ef53c848524e0c30"}}}}
{"actor":{"display_login":"mtyaka"}}