def test_allowed_schemas(): """ Events should be emitted only if their schemas are allowed """ schema = { '$id': 'test/test', 'version': 1, 'properties': { 'something': { 'type': 'string', 'categories': ['unrestricted'] }, }, } output = io.StringIO() handler = logging.StreamHandler(output) el = EventLog(handlers=[handler]) # Just register schema, but do not mark it as allowed el.register_schema(schema) el.record_event('test/test', 1, { 'something': 'blah', }) handler.flush() assert output.getvalue() == ''
def test_timestamp_override(): """ Simple test for overriding timestamp """ schema = { '$id': 'test/test', 'version': 1, 'properties': { 'something': { 'type': 'string', 'categories': ['unrestricted'] }, }, } output = io.StringIO() handler = logging.StreamHandler(output) el = EventLog(handlers=[handler]) el.register_schema(schema) el.allowed_schemas = ['test/test'] timestamp_override = datetime.utcnow() - timedelta(days=1) el.record_event('test/test', 1, { 'something': 'blah', }, timestamp_override=timestamp_override) handler.flush() event_capsule = json.loads(output.getvalue()) assert event_capsule['__timestamp__'] == timestamp_override.isoformat( ) + 'Z'
def test_record_event_badschema(): """ Fail fast when an event doesn't conform to its schema """ schema = { '$id': 'test/test', 'version': 1, 'properties': { 'something': { 'type': 'string', 'categories': ['unrestricted'] }, 'status': { 'enum': ['success', 'failure'], 'categories': ['unrestricted'] } } } el = EventLog(handlers=[logging.NullHandler()]) el.register_schema(schema) el.allowed_schemas = ['test/test'] with pytest.raises(jsonschema.ValidationError): el.record_event( 'test/test', 1, { 'something': 'blah', 'status': 'hi' #'not-in-enum' })
def main(): eventlog = EventLog(allowed_schemas=["hub.jupyter.org/server-action"], handlers=[logging.StreamHandler(sys.stdout)]) hmac_key = secrets.token_bytes(32) for dirname, _, files in os.walk( pathlib.Path(__file__).parent / "event-schemas"): for file in files: if not file.endswith('.yaml'): continue eventlog.register_schema_file(os.path.join(dirname, file)) for l in sys.stdin: if 'seconds to' not in l: continue timestamp, user, action = parse_activity_line(l) eventlog.record_event( "hub.jupyter.org/server-action", 1, { "action": action, "username": hmac.new(key=hmac_key, msg=user.encode(), digestmod='sha256').hexdigest(), "servername": "" }, timestamp_override=timestamp)
def test_record_event(): """ Simple test for emitting valid events """ schema = { '$id': 'test/test', 'version': 1, 'properties': { 'something': { 'type': 'string' }, }, } output = io.StringIO() handler = logging.StreamHandler(output) el = EventLog(handlers=[handler]) el.register_schema(schema) el.allowed_schemas = ['test/test'] el.record_event('test/test', 1, { 'something': 'blah', }) handler.flush() event_capsule = json.loads(output.getvalue()) assert '__timestamp__' in event_capsule # Remove timestamp from capsule when checking equality, since it is gonna vary del event_capsule['__timestamp__'] assert event_capsule == { '__schema__': 'test/test', '__version__': 1, 'something': 'blah' }
def test_allowed_schemas(schema, allowed_schemas, expected_output): sink = io.StringIO() # Create a handler that captures+records events with allowed tags. handler = logging.StreamHandler(sink) e = EventLog(handlers=[handler], allowed_schemas=allowed_schemas) e.register_schema(schema) event = { 'nothing-exciting': 'hello, world', 'id': 'test id', 'email': '*****@*****.**', } # Record event and read output e.record_event(SCHEMA_ID, VERSION, EVENT_DATA) recorded_event = json.loads(sink.getvalue()) event_data = { key: value for key, value in recorded_event.items() if not key.startswith('__') } # Verify that *exactly* the right properties are recorded. assert expected_output == event_data
def main(): eventlog = EventLog( allowed_schemas=[ "hub.jupyter.org/server-action" ], handlers=[ logging.StreamHandler() ] ) for dirname, _, files in os.walk(pathlib.Path(__file__).parent / "event-schemas"): for file in files: if not file.endswith('.yaml'): continue eventlog.register_schema_file(os.path.join(dirname, file)) for l in sys.stdin: if 'seconds to' not in l: continue timestamp, user, action = parse_activity_line(l) eventlog.record_event( "hub.jupyter.org/server-action", 1, { "action": action, "username": user, "servername": "" }, timestamp_override=timestamp )
def get_event_data(event, schema, schema_id, version, allowed_schemas): sink = io.StringIO() # Create a handler that captures+records events with allowed tags. handler = logging.StreamHandler(sink) e = EventLog(handlers=[handler], allowed_schemas=allowed_schemas) e.register_schema(schema) # Record event and read output e.record_event(schema_id, version, deepcopy(event)) recorded_event = json.loads(sink.getvalue()) return { key: value for key, value in recorded_event.items() if not key.startswith('__') }
def test_unique_logger_instances(): schema0 = { '$id': 'test/test0', 'version': 1, 'properties': { 'something': { 'type': 'string', 'categories': ['unrestricted'] }, }, } schema1 = { '$id': 'test/test1', 'version': 1, 'properties': { 'something': { 'type': 'string', 'categories': ['unrestricted'] }, }, } output0 = io.StringIO() output1 = io.StringIO() handler0 = logging.StreamHandler(output0) handler1 = logging.StreamHandler(output1) el0 = EventLog(handlers=[handler0]) el0.register_schema(schema0) el0.allowed_schemas = ['test/test0'] el1 = EventLog(handlers=[handler1]) el1.register_schema(schema1) el1.allowed_schemas = ['test/test1'] el0.record_event('test/test0', 1, { 'something': 'blah', }) el1.record_event('test/test1', 1, { 'something': 'blah', }) handler0.flush() handler1.flush() event_capsule0 = json.loads(output0.getvalue()) assert '__timestamp__' in event_capsule0 # Remove timestamp from capsule when checking equality, since it is gonna vary del event_capsule0['__timestamp__'] assert event_capsule0 == { '__schema__': 'test/test0', '__schema_version__': 1, '__metadata_version__': 1, 'something': 'blah' } event_capsule1 = json.loads(output1.getvalue()) assert '__timestamp__' in event_capsule1 # Remove timestamp from capsule when checking equality, since it is gonna vary del event_capsule1['__timestamp__'] assert event_capsule1 == { '__schema__': 'test/test1', '__schema_version__': 1, '__metadata_version__': 1, 'something': 'blah' }