Skip to content

Conversation

hkethi002
Copy link
Contributor

@hkethi002 hkethi002 commented Jun 13, 2017

Fixes #811

Review Checklist

  • Tests were added to cover all code changes
  • Documentation was added / updated
  • Code and tests follow standards in CONTRIBUTING.mdRequirements:

Requirements:

  • Add ability to specify singular subject query param that only returns records where context.subject.label matches that input
  • Add ability to specify multiple access_type query params that only return records where access_type matches one of those inputs
  • Add csv query param that, when True, returns a csv file of all matching records flattened into rows
  • Write integration tests to thoroughly test the new functionality
  • Create new endpoint (/api/report/accesslog/types ?) that returns the available access types for frontend use.

@hkethi002 hkethi002 requested a review from nagem June 13, 2017 21:21
@hkethi002 hkethi002 force-pushed the access-log-query branch 2 times, most recently from 6879e07 to 6eccabb Compare June 20, 2017 18:41
@nagem
Copy link
Contributor

nagem commented Jun 21, 2017

Nice work, Harsha. I worry that this endpoint would tip over an instance if asked to create a CSV or return everything in a very large access_log. We'll have to discuss with @ryansanford what limitations for safety seem reasonable and the possibility of a command line tool to generate the CSV when you really do want to have millions of logs returned.

@hkethi002 hkethi002 force-pushed the access-log-query branch 3 times, most recently from 722c295 to 795d2c0 Compare July 3, 2017 17:37
@ryansanford ryansanford self-assigned this Jul 6, 2017
@ryansanford
Copy link
Contributor

Somewhere between 70-80k results, we end up with the below error. That was indeed resolved by adding the index db.access_log.createIndex({timestamp: -1})

uwsgi_1           | 2017-07-13 02:01:26      scitran.api                  base.py   333:ERRO Traceback (most recent call last):
uwsgi_1           |   File "/usr/local/lib/python2.7/dist-packages/webapp2.py", line 570, in dispatch
uwsgi_1           |     return method(*args, **kwargs)
uwsgi_1           |   File "./api/handlers/reporthandler.py", line 77, in get
uwsgi_1           |     for doc in report.build():
uwsgi_1           |   File "./api/handlers/reporthandler.py", line 566, in build
uwsgi_1           |     return self.make_csv_ready(cursor)
uwsgi_1           |   File "./api/handlers/reporthandler.py", line 545, in make_csv_ready
uwsgi_1           |     return [self.flatten(json_obj, {}) for json_obj in cursor]
uwsgi_1           |   File "/usr/local/lib/python2.7/dist-packages/pymongo/cursor.py", line 1097, in next
uwsgi_1           |     if len(self.__data) or self._refresh():
uwsgi_1           |   File "/usr/local/lib/python2.7/dist-packages/pymongo/cursor.py", line 1019, in _refresh
uwsgi_1           |     self.__read_concern))
uwsgi_1           |   File "/usr/local/lib/python2.7/dist-packages/pymongo/cursor.py", line 905, in __send_message
uwsgi_1           |     helpers._check_command_response(doc['data'][0])
uwsgi_1           |   File "/usr/local/lib/python2.7/dist-packages/pymongo/helpers.py", line 196, in _check_command_response
uwsgi_1           |     raise OperationFailure(msg % errmsg, code, response)
uwsgi_1           | OperationFailure: Executor error during find command: OperationFailed: Sort operation used more than the maximum 33554432 bytes of RAM. Add an index, or specify a smaller limit.
uwsgi_1           |  request_id=c006d926-1499911285
uwsgi_1           | ./api/tempdir.py:42: Warning: start: Implicitly cleaning up <TemporaryDirectory u'/var/scitran/data/.tmpAdZzcl'>
uwsgi_1           |   Warning)
uwsgi_1           | ./api/tempdir.py:57: Warning: end: Implicitly cleaning up <TemporaryDirectory u'/var/scitran/data/.tmpAdZzcl'>
uwsgi_1           |   Warning)
uwsgi_1           | [pid: 46|app: 0|req: 27/121] 172.19.0.1 () {36 vars in 723 bytes} [Thu Jul 13 02:01:25 2017] GET /api/report/accesslog?user=ryansanford@flywheel.io&end_date=2017-07-11T00:00:00.000Z&start_date=2017-06-04T00:00:00.000Z&limit=80000&csv=true => generated 194 bytes in 557 msecs (HTTP/1.1 500) 3 headers in 131 bytes (2 switches on core 0)

@ryansanford
Copy link
Contributor

Next breakage is happening between 300-400k. uwsgi worker is dying. This is happening after 17 seconds.

mongodb_1         | 2017-07-13T02:25:24.840+0000 I NETWORK  [initandlisten] connection accepted from 172.19.0.6:50080 #65 (14 connections now open)
mongodb_1         | 2017-07-13T02:25:24.848+0000 I NETWORK  [initandlisten] connection accepted from 172.19.0.6:50082 #66 (15 connections now open)
uwsgi_1           | 2017-07-13 02:25:24      scitran.api                  base.py   403:DEBU from ryansanford@flywheel.io GET /api/report/accesslog {u'csv': u'true', u'limit': u'400000', u'user': u'ryansanford@flywheel.io', u'end_date': u'2017-07-11T00:00:00.000Z', u'start_date': u'2017-06-04T00:00:00.000Z'} request_id=af740af3-1499912724
uwsgi_1           | 2017-07-13 02:25:24      scitran.api                config.py   223:INFO Initializing database, creating indexes
mongodb_1         | 2017-07-13T02:25:24.885+0000 I NETWORK  [initandlisten] connection accepted from 172.19.0.6:50084 #67 (16 connections now open)
mongodb_1         | 2017-07-13T02:25:24.888+0000 I NETWORK  [initandlisten] connection accepted from 172.19.0.6:50086 #68 (17 connections now open)
uwsgi_1           | 2017-07-13 02:25:24      scitran.api                config.py   255:INFO Persisting configuration
mongodb_1         | 2017-07-13T02:25:39.525+0000 I NETWORK  [conn66] end connection 172.19.0.6:50082 (16 connections now open)
mongodb_1         | 2017-07-13T02:25:39.525+0000 I NETWORK  [conn65] end connection 172.19.0.6:50080 (16 connections now open)
mongodb_1         | 2017-07-13T02:25:39.525+0000 I NETWORK  [conn67] end connection 172.19.0.6:50084 (16 connections now open)
mongodb_1         | 2017-07-13T02:25:39.525+0000 I NETWORK  [conn68] end connection 172.19.0.6:50086 (16 connections now open)
uwsgi_1           | DAMN ! worker 2 (pid: 100) died, killed by signal 9 :( trying respawn ...
uwsgi_1           | Respawned uWSGI worker 2 (new pid: 105)


@ryansanford
Copy link
Contributor

@hkethi002 Would putting a python script in bin/ to handle arbitrary large exports make sense and be reliable, or would we have similar issue as uwsgi process dying as seen above?

@ryansanford
Copy link
Contributor

Regarding the uwsgi exiting, it's due to running out of memory. It reaches about 2.5 GB at the point of processing 360k results

@ryansanford ryansanford assigned hkethi002 and unassigned ryansanford Jul 17, 2017
@hkethi002 hkethi002 force-pushed the access-log-query branch 2 times, most recently from c4b0e03 to 66054cd Compare July 18, 2017 16:23
bin/database.py Outdated
"""
Indexes the timestamps of access logs
"""
config.log_db.access_log.createIndex({'timestamp': -1})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can put this in config.py and it will get added on startup if it's not already there.

@hkethi002
Copy link
Contributor Author

Ran into Unicode Errors caused by some labels having emojis in them, and it seems like csv library being used uses ASCII so should they just be skipped for now?

@nagem
Copy link
Contributor

nagem commented Jul 20, 2017

We're going to have to support unicode, especially if we are going to support users whose languages don't use the ASCII char set. Looks like there is a unicode replacement for the csv lib:

https://github.com/jdunck/python-unicodecsv

@hkethi002 hkethi002 force-pushed the access-log-query branch 2 times, most recently from d7ab4bd to 07de208 Compare July 25, 2017 16:35
raise APIReportParamsException('Limit must be an integer greater than 0.')
for access_type in access_types:
if access_type not in AccessTypeList:
raise APIReportParamsException('Not a valid access type')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should decide on a "safe" limit and reject requests that go over that limit. The rejection 400 could mention that an admin should run the script instead. @ryansanford what would you say the safe uwsgi log limit would be after your testing?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then make sure we add a test for failing when attempting to go over that limit.

@nagem nagem requested a review from ryansanford July 31, 2017 16:17
@hkethi002 hkethi002 force-pushed the access-log-query branch 2 times, most recently from 12a8976 to 52f6e63 Compare August 2, 2017 18:31
if limit < 1:
raise APIReportParamsException('Limit must be an integer greater than 0.')
elif limit > 10000:
raise APIReportParamsException('Limit exceeds 1000 entries, please contact admin to run script.')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need one more zero on the error :)

@nagem
Copy link
Contributor

nagem commented Aug 4, 2017

After error message change, LGTM! Feel free to merge.

@hkethi002 hkethi002 merged commit febf00c into master Aug 4, 2017
@hkethi002 hkethi002 deleted the access-log-query branch August 4, 2017 18:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants