class Middleware: def __init__(self, get_response): self.get_response = get_response self.recorder = Recorder() def __call__(self, request): if self.recorder.enabled: start = time.monotonic() call_event = HttpRequestEvent( request_method=request.method, path_info=request.path_info, protocol=request.META['SERVER_PROTOCOL']) self.recorder.add_event(call_event) response = self.get_response(request) if self.recorder.enabled: duration = time.monotonic() - start return_event = HttpResponseEvent( parent_id=call_event.id, elapsed=duration, status_code=response.status_code, mime_type=response.get('Content-Type', None) or 'unknown') self.recorder.add_event(return_event) return response
class ExecuteWrapper: def __init__(self): self.recorder = Recorder() def __call__(self, execute, sql, params, many, context): start = time.monotonic() try: return execute(sql, params, many, context) finally: if self.recorder.enabled: stop = time.monotonic() duration = stop - start # Note this logic is based on django.db.backends.utils.CursorDebugWrapper. if many: # Sometimes the same query is executed with different parameter sets. # Instead of substituting them all, just say how many times it was run. try: times = len(params) except TypeError: times = '?' sql = '%s times %s' % (times, sql) else: db = context['connection'] cursor = context['cursor'] sql = db.ops.last_executed_query(cursor, sql, params) call_event = SqlEvent(sql) self.recorder.add_event(call_event) return_event = ReturnEvent(parent_id=call_event.id, elapsed=duration) self.recorder.add_event(return_event)
def capture_sql_call(conn, cursor, statement, parameters, context, executemany): """Capture SQL query callinto appmap.""" recorder = Recorder() if is_instrumentation_disabled(): # We must be in the middle of fetching object representation. # Don't record this query in the appmap. pass elif recorder.enabled: Metadata.add_framework('SQLAlchemy', sqlalchemy.__version__) if executemany: # Sometimes the same query is executed with different parameter sets. # Instead of substituting them all, just say how many times it was run. try: times = len(parameters) except TypeError: times = '?' sql = '-- %s times\n%s' % (times, statement) else: sql = statement dialect = conn.dialect call_event = SqlEvent(sql, vendor=dialect.name, version=dialect.server_version_info) recorder.add_event(call_event) setattr(context, 'appmap', { 'start_time': time.monotonic(), 'call_event_id': call_event.id })
def events(): """Enables appmap recording and allows examining events.""" rec = Recorder() rec.events.clear() rec.enabled = True yield rec.events rec.enabled = False rec.events.clear()
def events(): rec = Recorder() rec.events().clear() rec.enabled = True yield rec.events() rec.enabled = False rec.events().clear()
def capture_sql(conn, cursor, statement, parameters, context, executemany): """Capture SQL query return into appmap.""" recorder = Recorder() if is_instrumentation_disabled(): # We must be in the middle of fetching object representation. # Don't record this query in the appmap. pass elif recorder.enabled: stop = time.monotonic() duration = stop - context.appmap['start_time'] return_event = ReturnEvent(parent_id=context.appmap['call_event_id'], elapsed=duration) del context.appmap recorder.add_event(return_event)
def before_request(self): if self.recording.is_running() and request.path != self.record_url: call_event = HttpRequestEvent( request_method=request.method, path_info=request.path, normalized_path_info=request.url_rule.rule, protocol=request.environ.get('SERVER_PROTOCOL')) Recorder().add_event(call_event) g.appmap_request_event = call_event g.appmap_request_start = time.monotonic()
def after_request(self, response): if self.recording.is_running() and request.path != self.record_url: parent_id = g.appmap_request_event.id duration = time.monotonic() - g.appmap_request_start return_event = HttpResponseEvent(parent_id=parent_id, elapsed=duration, status_code=response.status_code, mime_type=response.content_type) Recorder().add_event(return_event) return response
def after_request(self, response): if self.recording.is_running() and request.path != self.record_url: appctx = _app_ctx_stack.top parent_id = appctx.appmap_request_event.id duration = time.monotonic() - appctx.appmap_request_start return_event = HttpServerResponseEvent( parent_id=parent_id, elapsed=duration, status_code=response.status_code, headers=response.headers) Recorder().add_event(return_event) return response
class ExecuteWrapper: def __init__(self): self.recorder = Recorder() def __call__(self, execute, sql, params, many, context): start = time.monotonic() try: return execute(sql, params, many, context) finally: if is_instrumentation_disabled(): # We must be in the middle of fetching object representation. # Don't record this query in the appmap. pass elif self.recorder.enabled: add_metadata() stop = time.monotonic() duration = stop - start conn = context['connection'] # Note this logic is based on django.db.backends.utils.CursorDebugWrapper. if many: # Sometimes the same query is executed with different parameter sets. # Instead of substituting them all, just say how many times it was run. try: times = len(params) except TypeError: times = '?' sql = '%s times %s' % (times, sql) else: cursor = context['cursor'] sql = conn.ops.last_executed_query(cursor, sql, params) call_event = SqlEvent(sql, vendor=conn.vendor, version=database_version(conn)) self.recorder.add_event(call_event) return_event = ReturnEvent(parent_id=call_event.id, elapsed=duration) self.recorder.add_event(return_event)
def render(self, orig, *args, **kwargs): """Calls the original implementation. If recording is enabled, adds appropriate TemplateEvent and ReturnEvent. """ rec = Recorder() if rec.enabled: start = time.monotonic() call_event = TemplateEvent(self.filename, self) # pylint: disable=no-member rec.add_event(call_event) try: return orig(self, *args, **kwargs) finally: if rec.enabled: rec.add_event( ReturnEvent(call_event.id, time.monotonic() - start))
def before_request(self): if self.recording.is_running() and request.path != self.record_url: Metadata.add_framework('flask', flask.__version__) np = None # See # https://github.com/pallets/werkzeug/blob/2.0.0/src/werkzeug/routing.py#L213 # for a description of parse_rule. if request.url_rule: np = ''.join([ f'{{{p}}}' if c else p for c, _, p in parse_rule(request.url_rule.rule) ]) call_event = HttpServerRequestEvent( request_method=request.method, path_info=request.path, message_parameters=request_params(request), normalized_path_info=np, protocol=request.environ.get('SERVER_PROTOCOL'), headers=request.headers) Recorder().add_event(call_event) appctx = _app_ctx_stack.top appctx.appmap_request_event = call_event appctx.appmap_request_start = time.monotonic()
def __init__(self, get_response): self.get_response = get_response self.recorder = Recorder()
def __init__(self): self.recorder = Recorder()
class Middleware: def __init__(self, get_response): self.get_response = get_response self.recorder = Recorder() def __call__(self, request): if not Env.current.enabled: return self.get_response(request) if request.path_info == '/_appmap/record': return self.recording(request) if self.recorder.enabled: add_metadata() start = time.monotonic() params = request_params(request) try: resolved = resolve(request.path_info) params.update(resolved.kwargs) normalized_path_info = normalize_path_info( request.path_info, resolved) except Resolver404: # If the request was for a bad path (e.g. when an app # is testing 404 handling), resolving will fail. normalized_path_info = None call_event = HttpServerRequestEvent( request_method=request.method, path_info=request.path_info, message_parameters=params, normalized_path_info=normalized_path_info, protocol=request.META['SERVER_PROTOCOL'], headers=request.headers) self.recorder.add_event(call_event) try: response = self.get_response(request) except: if self.recorder.enabled: duration = time.monotonic() - start exception_event = ExceptionEvent(parent_id=call_event.id, elapsed=duration, exc_info=sys.exc_info()) self.recorder.add_event(exception_event) raise if self.recorder.enabled: duration = time.monotonic() - start return_event = HttpServerResponseEvent( parent_id=call_event.id, elapsed=duration, status_code=response.status_code, headers=dict(response.items())) self.recorder.add_event(return_event) return response def recording(self, request): """Handle recording requests.""" if request.method == 'GET': return JsonResponse({'enabled': self.recorder.enabled}) if request.method == 'POST': if self.recorder.enabled: return HttpResponse('Recording is already in progress', status=409) self.recorder.clear() self.recorder.start_recording() return HttpResponse() if request.method == 'DELETE': if not self.recorder.enabled: return HttpResponse('No recording is in progress', status=404) self.recorder.stop_recording() return HttpResponse(generation.dump(self.recorder), content_type='application/json') return HttpResponseBadRequest()