New Relic integration

(imported from commit a108f4c6e90d857263453036f6d5f09279302b7e)
This commit is contained in:
Kevin Mehall
2013-07-23 15:50:29 -04:00
parent 04ad610263
commit eb6bc91c22
8 changed files with 88 additions and 0 deletions

View File

@@ -136,6 +136,7 @@ urlpatterns += patterns('zephyr.views',
url(r'^api/v1/external/github$', 'api_github_landing'),
url(r'^api/v1/external/jira$', 'api_jira_webhook'),
url(r'^api/v1/external/pivotal$', 'api_pivotal_webhook'),
url(r'^api/v1/external/newrelic$', 'api_newrelic_webhook'),
)
v1_api_and_json_patterns = patterns('zephyr.views',

View File

@@ -52,6 +52,7 @@
<li><a href="#jira">Jira (hosted or v5.2+)</a></li>
<li><a href="#jira-plugin">Jira (locally installed)</a></li>
<li><a href="#nagios">Nagios</a></li>
<li><a href="#newrelic">New Relic</a></li>
<li><a href="#pivotal">Pivotal Tracker</a></li>
<li><a href="#svn">Subversion</a></li>
<li><a href="#trac">Trac</a></li>
@@ -394,6 +395,29 @@ key=NAGIOS_BOT_API_KEY
<a href="#services">^ Back to top</a>
</p>
</div>
{#--------------------------------------------------------------------#}
<div id="newrelic" class="integration">
<h4>New Relic</h4>
<p>New Relic can send messages to a Zulip stream for alerts and deploys.
In your Account Settings page, click "Integrations", then
"Alerting notifications". On the "Webhook" tab, enter the following
webhook URL:</p>
<p><code>https://api.humbughq.com/v1/external/newrelic?api_key=abcdefgh&amp;stream=newrelic</code></p>
<p>where <code>api_key</code> is the API key of the user you
want updates to be sent as, and <code>stream</code> is the stream name you want the notifications sent to. The stream must already exist.</p>
<img class="screenshot" src="/static/images/integrations/newrelic/001.png">
<p><b>Congratulations! You're done!</b><br /> Your New Relic events will
appear in Zulip:
<img class="screenshot" src="/static/images/integrations/newrelic/002.png">
<p>
<a href="#services">^ Back to top</a>
</p>
</div>
{#--------------------------------------------------------------------#}
<div id="svn" class="integration">
<h4>Subversion</h4>

View File

@@ -0,0 +1 @@
alert=%7B%22created_at%22%3A%222013-07-23T20%3A14%3A15%2B00%3A00%22%2C%22application_name%22%3A%22Application%20name%22%2C%22account_name%22%3A%22Account%20name%22%2C%22severity%22%3A%22critical%22%2C%22message%22%3A%22Apdex%20score%20fell%20below%20critical%20level%20of%200.90%22%2C%22short_description%22%3A%22%5Bapplication%20name%5D%20alert%20opened%22%2C%22long_description%22%3A%22Alert%20opened%20on%20%5Bapplication%20name%5D%3A%20Apdex%20score%20fell%20below%20critical%20level%20of%200.90%22%2C%22alert_url%22%3A%22https%3A%2F%2Frpm.newrelc.com%2Faccounts%2F%5Baccount_id%5D%2Fapplications%2F%5Bapplication_id%5D%2Fincidents%2F%5Bincident_id%5D%22%7D

View File

@@ -0,0 +1 @@
deployment=%7B%22created_at%22%3A%222013-07-23T20%3A14%3A25Z%22%2C%22deployed_by%22%3A%22Zulip%20Test%22%2C%22revision%22%3A%221242%22%2C%22description%22%3A%22Description%20sent%20via%20curl%22%2C%22application_name%22%3A%22Test%20App%22%2C%22account_name%22%3A%22Zulip%20Test%22%2C%22changelog%22%3A%22Changelog%20string%22%2C%22deployment_url%22%3A%22https%3A%2F%2Frpm.newrelic.com%2Faccounts%2F382116%2Fapplications%2F2135922%2Fdeployments%2F679885%22%7D

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -2988,6 +2988,28 @@ class PivotalHookTests(AuthedTestCase):
self.assertEqual(msg.content, 'Leo Franchi edited "My new Feature story" \
[(view)](https://www.pivotaltracker.com/s/projects/807213/stories/48276573)')
class NewRelicHookTests(AuthedTestCase):
def send_new_relic_message(self, name):
email = "hamlet@humbughq.com"
api_key = self.get_api_key(email)
return self.send_json_payload(email, "/api/v1/external/newrelic?api_key=%s&stream=%s" % (api_key,"newrelic"),
self.fixture_data('newrelic', name, file_type='txt'),
stream_name="newrelic",
content_type="application/x-www-form-urlencoded")
def test_alert(self):
msg = self.send_new_relic_message('alert')
self.assertEqual(msg.subject, "Apdex score fell below critical level of 0.90")
self.assertEqual(msg.content, 'Alert opened on [application name]: \
Apdex score fell below critical level of 0.90\n\
[View alert](https://rpm.newrelc.com/accounts/[account_id]/applications/[application_id]/incidents/[incident_id])')
def test_deployment(self):
msg = self.send_new_relic_message('deployment')
self.assertEqual(msg.subject, 'Test App deploy')
self.assertEqual(msg.content, '`1242` deployed by **Zulip Test**\n\
Description sent via curl\n\nChangelog string')
class RateLimitTests(AuthedTestCase):
def setUp(self):

View File

@@ -1829,6 +1829,45 @@ def api_beanstalk_webhook(request, user_profile,
return json_error(ret)
return json_success()
@csrf_exempt
@has_request_variables
def api_newrelic_webhook(request, alert=REQ(converter=json_to_dict, default=None),
deployment=REQ(converter=json_to_dict, default=None)):
try:
api_key = request.GET['api_key']
stream = request.GET['stream']
except (AttributeError, KeyError):
return json_error("Missing api_key or stream parameter.")
try:
user_profile = UserProfile.objects.get(api_key=api_key)
request.user = user_profile
except UserProfile.DoesNotExist:
return json_error("Failed to find user with API key: %s" % (api_key,))
rate_limit_user(request, user_profile, domain='all')
if alert:
# Use the message as the subject because it stays the same for
# "opened", "acknowledged", and "closed" messages that should be
# grouped.
subject = alert['message']
content = "%(long_description)s\n[View alert](%(alert_url)s)" % (alert)
elif deployment:
subject = "%s deploy" % (deployment['application_name'])
content = """`%(revision)s` deployed by **%(deployed_by)s**
%(description)s
%(changelog)s""" % (deployment)
else:
return json_error("Unknown webhook request")
subject = elide_subject(subject)
ret = check_send_message(user_profile, get_client("API"), "stream", [stream], subject, content)
if ret is not None:
return json_error(ret)
return json_success()
def get_status_list(requesting_user_profile):
return {'presences': get_status_dict(requesting_user_profile),
'server_timestamp': time.time()}