Log GitHub API rate limit

* remaining API calls
* timestamp when the limit is going to be reset

Change-Id: Ib3aa2e09989180bb754d3dab2ccb785fe6723b63
diff --git a/zuul/driver/github/githubconnection.py b/zuul/driver/github/githubconnection.py
index 0c4434f..9b505ba 100644
--- a/zuul/driver/github/githubconnection.py
+++ b/zuul/driver/github/githubconnection.py
@@ -205,6 +205,7 @@
 
 
 class GithubUser(collections.Mapping):
+    log = logging.getLogger('zuul.GithubUser')
 
     def __init__(self, github, username):
         self._github = github
@@ -224,6 +225,7 @@
 
     def _init_data(self):
         user = self._github.user(self._username)
+        log_rate_limit(self.log, self._github)
         data = {
             'username': user.login,
             'name': user.name,
@@ -326,6 +328,7 @@
         owner, proj = project.name.split('/')
         repository = self.github.repository(owner, proj)
         branches = [branch.name for branch in repository.branches()]
+        log_rate_limit(self.log, self.github)
         return branches
 
     def getPullUrl(self, project, number):
@@ -333,7 +336,9 @@
 
     def getPull(self, project_name, number):
         owner, proj = project_name.split('/')
-        return self.github.pull_request(owner, proj, number).as_dict()
+        pr = self.github.pull_request(owner, proj, number).as_dict()
+        log_rate_limit(self.log, self.github)
+        return pr
 
     def canMerge(self, change, allow_needs):
         # This API call may get a false (null) while GitHub is calculating
@@ -350,8 +355,10 @@
 
     def getPullFileNames(self, project, number):
         owner, proj = project.name.split('/')
-        return [f.filename for f in
-                self.github.pull_request(owner, proj, number).files()]
+        filenames = [f.filename for f in
+                     self.github.pull_request(owner, proj, number).files()]
+        log_rate_limit(self.log, self.github)
+        return filenames
 
     def getUser(self, login):
         return GithubUser(self.github, login)
@@ -364,6 +371,7 @@
         repository = self.github.repository(owner, proj)
         pull_request = repository.issue(pr_number)
         pull_request.create_comment(message)
+        log_rate_limit(self.log, self.github)
 
     def mergePull(self, project, pr_number, commit_message='', sha=None):
         owner, proj = project.split('/')
@@ -373,6 +381,7 @@
         except MethodNotAllowed as e:
             raise MergeFailure('Merge was not successful due to mergeability'
                                ' conflict, original error is %s' % e)
+        log_rate_limit(self.log, self.github)
         if not result:
             raise Exception('Pull request was not merged')
 
@@ -381,21 +390,35 @@
         owner, proj = project.split('/')
         repository = self.github.repository(owner, proj)
         repository.create_status(sha, state, url, description, context)
+        log_rate_limit(self.log, self.github)
 
     def labelPull(self, project, pr_number, label):
         owner, proj = project.split('/')
         pull_request = self.github.issue(owner, proj, pr_number)
         pull_request.add_labels(label)
+        log_rate_limit(self.log, self.github)
 
     def unlabelPull(self, project, pr_number, label):
         owner, proj = project.split('/')
         pull_request = self.github.issue(owner, proj, pr_number)
         pull_request.remove_label(label)
+        log_rate_limit(self.log, self.github)
 
     def _ghTimestampToDate(self, timestamp):
         return time.strptime(timestamp, '%Y-%m-%dT%H:%M:%SZ')
 
 
+def log_rate_limit(log, github):
+    try:
+        rate_limit = github.rate_limit()
+        remaining = rate_limit['resources']['core']['remaining']
+        reset = rate_limit['resources']['core']['reset']
+    except:
+        return
+    log.debug('GitHub API rate limit remaining: %s reset: %s' %
+              (remaining, reset))
+
+
 def getSchema():
     github_connection = v.Any(str, v.Schema({}, extra=True))
     return github_connection