Skip to content
This repository was archived by the owner on Aug 3, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions playbooks/openedx_native.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
ECOMMERCE_ENABLE_COMPREHENSIVE_THEMING: false
EDXAPP_ENABLE_MEMCACHE: true
EDXAPP_ENABLE_ELASTIC_SEARCH: true
ENABLE_UPTIME_REPORT: true
roles:
- role: swapfile
SWAPFILE_SIZE: 4GB
Expand Down Expand Up @@ -107,3 +108,5 @@
- role: user_retirement_pipeline
when: COMMON_RETIREMENT_SERVICE_SETUP
- role: mfe_deployer
- role: uptime_report
when: ENABLE_UPTIME_REPORT
24 changes: 24 additions & 0 deletions playbooks/roles/uptime_report/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#
# Open edX Retirement Pipeline Configuration
#
# github: https://github.com/edx/configuration
# wiki: https://openedx.atlassian.net/wiki/display/OpenOPS
# code style: https://openedx.atlassian.net/wiki/display/OpenOPS/Ansible+Code+Conventions
# license: https://github.com/edx/configuration/blob/master/LICENSE.TXT
#
#
# Deploy uptime_report
#
# See documentation in README.rst

#
# This file contains the variables you'll need to pass to the role, and some
# example values.

uptime_report_script: "/edx/var/upload_uptime_report.py"
uptime_report_cron_job_days: 6
uptime_report_cron_job_minutes: 0
newrelic_query_key: ""
newrelic_query_api_url: ""
uptime_report_s3_bucket: ""
uptime_report_s3_bucket_folder: ""
36 changes: 36 additions & 0 deletions playbooks/roles/uptime_report/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
#
# edX Configuration
#
# github: https://github.com/edx/configuration
# wiki: https://openedx.atlassian.net/wiki/display/OpenOPS
# code style: https://openedx.atlassian.net/wiki/display/OpenOPS/Ansible+Code+Conventions
# license: https://github.com/edx/configuration/blob/master/LICENSE.TXT
#
#
#
# Tasks for role uptime_report
#
# Overview:
# This role will be used to set up automatic querying of daily uptime reports
# and upload it onto an S3 bucket
#
# Example play:
#
#

- name: Create python script to upload query and upload uptime reports
template:
dest: "{{ uptime_report_script }}"
src: "uptime_report_script.j2"
mode: 0755
owner: root
group: root

- name: Install cron job for automatically running the uptime report script
cron:
name: "Run uptime report script"
job: "{{ uptime_report_script }}"
hour: "{{ uptime_report_cron_job_days }}"
minute: "{{ uptime_report_cron_job_minutes }}"
day: "*"
59 changes: 59 additions & 0 deletions playbooks/roles/uptime_report/templates/uptime_report_script.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/python

import boto3
import json
import datetime
from six.moves import urllib

newrelic_query_key = '{{ newrelic_query_key }}'
newrelic_query_api_url = '{{ newrelic_query_api_url }}'
uptime_report_s3_bucket = '{{ uptime_report_s3_bucket }}'
uptime_report_s3_bucket_folder = '{{ uptime_report_s3_bucket_folder }}'
newrelic_monitor_name = 'https://{{ EDXAPP_SITE_NAME }}/'
aws_access_key_id = '{{ AWS_S3_LOGS_ACCESS_KEY_ID }}'
aws_secret_access_key = '{{ AWS_S3_LOGS_SECRET_KEY }}'

nr_query = ("SELECT percentage(count(*), WHERE result = 'SUCCESS') as 'UPTIME' "
"FROM SyntheticCheck WHERE monitorName = '{0}' "
"FACET dateOf(timestamp), hourOf(timestamp) "
"SINCE '{1} 00:00:00' UNTIL '{2} 00:00:00' "
"LIMIT MAX")

def get_uptime_data(date):
from_time = (date+datetime.timedelta(days=-1)).strftime("%Y-%m-%d")
to_time = date.strftime("%Y-%m-%d")
data = urllib.parse.urlencode({
'nrql': nr_query.format(newrelic_monitor_name, from_time, to_time)
})
headers = {'X-Query-Key': newrelic_query_key, 'Accept': 'application/json'}
request = urllib.request.Request(newrelic_query_api_url+'?'+data, headers=headers)

response = urllib.request.urlopen(request)
data = json.loads(response.read().decode('utf-8'))
response.close()
times = []

for facet in data['facets']:
date, time = facet['name'][0], facet['name'][1]
times.append({
'time': datetime.datetime.strptime('{0} {1}'.format(date, time), '%B %d, %Y %H:%M').strftime("%Y-%m-%d %H:%M"),
'uptime_percentage': float(facet['results'][0]['result']),
})
times = sorted(times, key=lambda x: x['time'])
return times

def upload_to_s3(uptime_data, date):
filepath = 'uptime/'
if uptime_report_s3_bucket_folder:
filepath = '{0}{1}/'.format(filepath, uptime_report_s3_bucket_folder)

filename = '{0}uptime-{1}.json'.format(filepath, (date+datetime.timedelta(days=-1)).strftime("%Y-%m-%d"))
uptime_data = json.dumps(uptime_data)

s3_client = boto3.client('s3',aws_access_key_id=aws_access_key_id, aws_secret_access_key=aws_secret_access_key)
s3_client.put_object(Body=uptime_data, Bucket=uptime_report_s3_bucket, Key=filename)

if __name__ == "__main__":
today = datetime.datetime.now()
uptime_data = get_uptime_data(today)
upload_to_s3(uptime_data, today)