hi @lwintergerst ,
Thanks for your reply. Appreciate your help !!
Here is the Code Snippet where am trying to INJECT ELASTIC CODE into my Application (Custom Instrumentation)
############################################################### # Copyright (c) 2002 **Zope Foundation** and Contributors. ############################################################### """Python Object Publisher -- Publish Python objects on web servers """ import os import sys from thread import allocate_lock import transaction from urlparse import urlparse from AccessControl.SecurityManagement import newSecurityManager from AccessControl.SecurityManagement import noSecurityManager from six import reraise from zExceptions import Redirect from zope.event import notify from zope.globalrequest import setRequest, clearRequest from zope.publisher.interfaces import ISkinnable from zope.publisher.interfaces.browser import IBrowserPage from zope.publisher.skinnable import setDefaultSkin from zope.security.management import newInteraction, endInteraction from ZPublisher.mapply import mapply from ZPublisher import pubevents from ZPublisher import Retry from ZPublisher.HTTPRequest import HTTPRequest as Request from ZPublisher.HTTPResponse import HTTPResponse as Response from ZPublisher.utils import recordMetaData ####### ELASTIC APM INTEGRATION ####### from elasticapm import Client import elasticapm #import elasticapm.instrumentation.control #from elasticapm.base import Client #from elasticapm.conf import constants, setup_logging #from elasticapm.handlers.logging import LoggingHandler #from elasticapm.traces import execution_context #from elasticapm.utils.disttracing import TraceParent #from elasticapm.utils.logging import get_logger #logger = get_logger("elasticapm.errors.client") client = elasticapm.Client(service_name="Zope-POCWQAAPM51-5003-Aug25", framework_name="Zope", framework_version="4.0", server_url="http://172.27.2.33:8200") #client = elasticapm.Client(service_name="Zope-POCWQAAPM51-5003-maapply", framework_name="Zope", framework_version="4.0", server_url="http://172.27.2.33:8200") elasticapm.instrumentation.control.instrument() _default_debug_mode = False _default_realm = None def call_object(object, args, request): return object(*args) def missing_name(name, request): if name == 'self': return request['PARENTS'][0] request.response.badRequestError(name) def dont_publish_class(klass, request): request.response.forbiddenError("class %s" % klass.__name__) def validate_user(request, user): newSecurityManager(request, user) def set_default_debug_mode(debug_mode): global _default_debug_mode _default_debug_mode = debug_mode def set_default_authentication_realm(realm): global _default_realm _default_realm = realm @elasticapm.capture_span() def publish(request, module_name, after_list, debug=0, # Optimize: call_object=call_object, missing_name=missing_name, dont_publish_class=dont_publish_class, mapply=mapply, ): (bobo_before, bobo_after, object, realm, debug_mode, err_hook, validated_hook, transactions_manager) = get_module_info(module_name) parents = None response = None #client.begin_transaction('request_mapply') try: notify(pubevents.PubStart(request)) # TODO pass request here once BaseRequest implements IParticipation newInteraction() request.processInputs() request_get = request.get response = request.response # First check for "cancel" redirect: if request_get('SUBMIT', '').strip().lower() == 'cancel': cancel = request_get('CANCEL_ACTION', '') if cancel: # Relative URLs aren't part of the spec, but are accepted by # some browsers. for part, base in zip(urlparse(cancel)[:3], urlparse(request['BASE1'])[:3]): if not part: continue if not part.startswith(base): cancel = '' break if cancel: raise Redirect(cancel) after_list[0] = bobo_after if debug_mode: response.debug_mode = debug_mode if realm and not request.get('REMOTE_USER', None): response.realm = realm noSecurityManager() if bobo_before is not None: bobo_before() # Get the path list. # According to RFC1738 a trailing space in the path is valid. path = request_get('PATH_INFO') request['PARENTS'] = parents = [object] if transactions_manager: transactions_manager.begin() object = request.traverse(path, validated_hook=validated_hook) if IBrowserPage.providedBy(object): request.postProcessInputs() notify(pubevents.PubAfterTraversal(request)) if transactions_manager: recordMetaData(object, request) #Elastic Code - Client txn starts client.begin_transaction('request_mapply') result = mapply(object, request.args, request, call_object, 1, missing_name, dont_publish_class, request, bind=1) #import pdb; pdb.set_trace() #Elastic Code - Client txn ends client.end_transaction(request.method + " " + request.get('PATH_INFO'), response.status) if result is not response: response.setBody(result) notify(pubevents.PubBeforeCommit(request)) client.end_transaction(request.method + " " + request.get('PATH_INFO'), response.status) if transactions_manager: transactions_manager.commit() notify(pubevents.PubSuccess(request)) endInteraction() #client.end_transaction(request.method + " " + request.get('PATH_INFO'), response.status) return response except: # save in order to give 'PubFailure' the original exception info exc_info = sys.exc_info() # DM: provide nicer error message for FTP sm = None if response is not None: sm = getattr(response, "setMessage", None) if sm is not None: from asyncore import compact_traceback cl, val = sys.exc_info()[:2] sm('%s: %s %s' % ( getattr(cl, '__name__', cl), val, debug_mode and compact_traceback()[-1] or '')) # debug is just used by tests (has nothing to do with debug_mode!) if not debug and err_hook is not None: retry = False if parents: parents = parents[0] try: try: return err_hook(parents, request, sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2], ) except Retry: if not request.supports_retry(): return err_hook(parents, request, sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2], ) retry = True finally: # Note: 'abort's can fail. # Nevertheless, we want end request handling. try: try: notify(pubevents.PubBeforeAbort( request, exc_info, retry)) finally: if transactions_manager: transactions_manager.abort() finally: endInteraction() notify(pubevents.PubFailure(request, exc_info, retry)) # Only reachable if Retry is raised and request supports retry. newrequest = request.retry() request.close() # Free resources held by the request. # Set the default layer/skin on the newly generated request if ISkinnable.providedBy(newrequest): setDefaultSkin(newrequest) try: return publish(newrequest, module_name, after_list, debug) finally: newrequest.close() else: # Note: 'abort's can fail. # Nevertheless, we want end request handling. try: try: notify(pubevents.PubBeforeAbort(request, exc_info, False)) finally: if transactions_manager: transactions_manager.abort() finally: endInteraction() notify(pubevents.PubFailure(request, exc_info, False)) raise #@elasticapm.capture_span() def publish_module_standard( module_name, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr, environ=os.environ, debug=0, request=None, response=None): #client.begin_transaction('request') must_die = 0 status = 200 after_list = [None] try: try: if response is None: response = Response(stdout=stdout, stderr=stderr) else: stdout = response.stdout # debug is just used by tests (has nothing to do with debug_mode!) response.handle_errors = not debug if request is None: request = Request(stdin, environ, response) setRequest(request) # make sure that the request we hand over has the # default layer/skin set on it; subsequent code that # wants to look up views will likely depend on it if ISkinnable.providedBy(request): setDefaultSkin(request) #traceparent_string = elasticapm.get_trace_parent_header() #parent = elasticapm.trace_parent_from_headers(traceparent_string) #with elasticapm.capture_span('jiva_span', labels={"type": "jiva_publish"}): #client.begin_transaction('request') #client.begin_transaction(transaction_type="request", trace_parent=parent) response = publish(request, module_name, after_list, debug=debug) #import pdb; pdb.set_trace() #elasticapm.set_context(lambda: get_data_from_request(request), "request") #elasticapm.set_context(lambda: get_data_from_response(response), "response") #client.end_transaction(request.method + " " + request.get('PATH_INFO'), response.status) except (SystemExit, ImportError): # XXX: Rendered ImportErrors were never caught here because they # were re-raised as string exceptions. Maybe we should handle # ImportErrors like all other exceptions. Currently they are not # re-raised at all, so they don't show up here. must_die = sys.exc_info() request.response.exception(1) except: # debug is just used by tests (has nothing to do with debug_mode!) if debug: raise request.response.exception() status = response.getStatus() if response: outputBody = getattr(response, 'outputBody', None) if outputBody is not None: outputBody() else: response = str(response) if response: stdout.write(response) # The module defined a post-access function, call it if after_list[0] is not None: after_list[0]() finally: if request is not None: request.close() clearRequest() if must_die: # Try to turn exception value into an exit code. try: if hasattr(must_die[1], 'code'): code = must_die[1].code else: code = int(must_die[1]) except: code = must_die[1] and 1 or 0 if hasattr(request.response, '_requestShutdown'): request.response._requestShutdown(code) try: reraise(must_die[0], must_die[1], must_die[2]) finally: must_die = None return status _l = allocate_lock() #@elasticapm.capture_span() def get_module_info(module_name, modules={}, acquire=_l.acquire, release=_l.release): if module_name in modules: return modules[module_name] if module_name[-4:] == '.cgi': module_name = module_name[:-4] acquire() tb = None g = globals() try: try: module = __import__(module_name, g, g, ('__doc__',)) # Let the app specify a realm if hasattr(module, '__bobo_realm__'): realm = module.__bobo_realm__ elif _default_realm is not None: realm = _default_realm else: realm = module_name # Check for debug mode if hasattr(module, '__bobo_debug_mode__'): debug_mode = bool(module.__bobo_debug_mode__) else: debug_mode = _default_debug_mode bobo_before = getattr(module, "__bobo_before__", None) bobo_after = getattr(module, "__bobo_after__", None) if hasattr(module, 'bobo_application'): object = module.bobo_application elif hasattr(module, 'web_objects'): object = module.web_objects else: object = module error_hook = getattr(module, 'zpublisher_exception_hook', None) validated_hook = getattr( module, 'zpublisher_validated_hook', validate_user) transactions_manager = getattr( module, 'zpublisher_transactions_manager', None) if not transactions_manager: # Create a default transactions manager for use # by software that uses ZPublisher and ZODB but # not the rest of Zope. transactions_manager = DefaultTransactionsManager() info = (bobo_before, bobo_after, object, realm, debug_mode, error_hook, validated_hook, transactions_manager) modules[module_name] = modules[module_name + '.cgi'] = info return info except Exception: t, v, tb = sys.exc_info() reraise(t, str(v), tb) finally: tb = None release() class DefaultTransactionsManager(object): def begin(self): transaction.begin() def commit(self): if transaction.isDoomed(): transaction.abort() else: transaction.commit() def abort(self): transaction.abort() def publish_module(module_name, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr, environ=os.environ, debug=0, request=None, response=None): """ publish a Python module """ return publish_module_standard(module_name, stdin, stdout, stderr, environ, debug, request, response)