import newrelic.agent import newrelic.api from Products.ZCatalog.ZCatalog import ZCatalog from collective.newrelic.utils import logger ZCatalog.original_zope_catalogtool_searchResults = ZCatalog.searchResults def newrelic_searchResults(self, REQUEST=None, **kw): trans = newrelic.agent.current_transaction() with newrelic.api.database_trace.DatabaseTrace(trans, str(kw), self): result = self.original_zope_catalogtool_searchResults(REQUEST, **kw) return result ZCatalog.searchResults = newrelic_searchResults logger.info( "Patched Products.ZCatalog.ZCatalog:ZCatalog.searchResults with instrumentation" )
from collective.newrelic.utils import logger from zope import event from zope.event import subscribers import newrelic.agent def newrelic_notify(event): """ Notify all subscribers of ``event``. """ for subscriber in subscribers: nr_relic_subscriber = newrelic.agent.FunctionTraceWrapper(subscriber, event.__class__.__name__, "Zope/Dispatch") nr_relic_subscriber(event) event.notify = newrelic_notify logger.info("Patched zope.event:notify with instrumentation")
from collective.newrelic.utils import logger from newrelic.api.transaction import Transaction original__init__ = Transaction.__init__ original__exit__ = Transaction.__exit__ def patched__init__(self, *args, **kwargs): original__init__(self, *args, **kwargs) self._transaction_id = id(self) Transaction.__init__ = patched__init__ logger.info("Patched newrelic.api.transaction:Transaction.__init__ to add _transaction_id") def patched__exit__(self, *args, **kwargs): if self._transaction_id != id(self): logger.exception("Checking my id: {0} against {1}".format(self._transaction_id, id(self))) return original__exit__(self, *args, **kwargs) Transaction.__exit__ = patched__exit__ logger.info("Patched newrelic.api.transaction:Transaction.__exit__ to check _transaction_id")
# This is one is required: it creates the 'webtransaction' import zserverpublisher # Enable/disable as you like import zpublisher_mapply import transformchains import zope_event import catalog_tool import talinterpreter import cron4plone import Globals import os from collective.newrelic.utils import logger try: # if the environment var was set, use this instead of the default (local) newrelic ini file config_file = os.environ.get('NEW_RELIC_CONFIG_FILE', 'newrelic.ini' ) newrelic.agent.initialize(config_file) logger.info('New Relic Python Agent configuration set from %s.' % config_file) except: pass
group='Zope2', priority=1) trans.__enter__() publish_module(name, request=a, response=b) finally: b._finish() if trans: if trans.name == 'PLACEHOLDER': newrelic.agent.ignore_transaction() trans.__exit__(None, None, None) a = b = None elif name == "Zope2WSGI": try: res = publish_wsgi(a, b) for r in res: a['wsgi.output'].write(r) finally: # TODO: Support keeping connections open. a['wsgi.output']._close = 1 a['wsgi.output'].close() except: LOG.error('exception caught', exc_info=True) ZServerPublisher.__init__ = newrelic__init__ logger.info( "Patched ZServer.PubCore.ZServerPublisher:ZServerPublisher.__init__ with WebTransaction creation, entering and exiting" )
import ZPublisher from ZPublisher.mapply import (default_missing_name, default_handle_class) import newrelic.agent import newrelic.api from collective.newrelic.utils import logger #Keep original for further use original_mapply = ZPublisher.mapply.mapply def newrelic_mapply(object, positional=(), keyword={}, debug=None, maybe=None, missing_name=default_missing_name, handle_class=default_handle_class, context=None, bind=0, ): trans = newrelic.agent.current_transaction() with newrelic.api.function_trace.FunctionTrace(trans, name=object.__class__.__name__, group='Zope'): result = original_mapply(object, positional, keyword, debug, maybe, missing_name, handle_class, context, bind) return result ZPublisher.mapply.mapply = newrelic_mapply logger.info("Patched ZPublisher.mapply:mapply with instrumentation")
trans.name_transaction(PLACEHOLDER, group='Zope2', priority=1) trans.__enter__() publish_module( name, request=a, response=b) finally: b._finish() if trans: if trans.name == 'PLACEHOLDER': newrelic.agent.ignore_transaction() trans.__exit__(None, None, None) a = b = None elif name == "Zope2WSGI": try: res = publish_wsgi(a, b) for r in res: a['wsgi.output'].write(r) finally: # TODO: Support keeping connections open. a['wsgi.output']._close = 1 a['wsgi.output'].close() except: LOG.error('exception caught', exc_info=True) ZServerPublisher.__init__ = newrelic__init__ logger.info("Patched ZServer.PubCore.ZServerPublisher:ZServerPublisher.__init__ with WebTransaction creation, entering and exiting")
from zope.tal.talinterpreter import TALInterpreter import newrelic.agent from collective.newrelic.utils import logger original_function = TALInterpreter.__call__ def monkeypatch(self): probable_name = self.program[2][1] name = "Value (non-file)" if type(probable_name) in [str, unicode]: name = probable_name.split('/') name = name[-1] newrelic_monkeypatch = newrelic.agent.FunctionTraceWrapper(original_function, name, 'Zope/TAL') newrelic_monkeypatch(self) TALInterpreter.__call__ = monkeypatch logger.info("Patched zope.tal.talinterpreter:TALInterpreter.__call__ with instrumentation")
import newrelic.agent import newrelic.api from Products.CMFPlone.CatalogTool import CatalogTool from collective.newrelic.utils import logger CatalogTool.original_cmfplone_catalogtool_searchResults = CatalogTool.searchResults def newrelic_searchResults(self, REQUEST=None, **kw): trans = newrelic.agent.current_transaction() with newrelic.api.database_trace.DatabaseTrace(trans, str(kw), self): result = self.original_cmfplone_catalogtool_searchResults( REQUEST, **kw) return result CatalogTool.searchResults = newrelic_searchResults logger.info( "Patched Products.CMFPlone.CatalogTool:CatalogTool.searchResults with instrumentation" )
from collective.newrelic.utils import logger from zope import event from zope.event import subscribers import newrelic.agent def newrelic_notify(event): """ Notify all subscribers of ``event``. """ for subscriber in subscribers: nr_relic_subscriber = newrelic.agent.FunctionTraceWrapper(subscriber, event.__class__.__name__, 'Zope/Dispatch') nr_relic_subscriber(event) event.notify = newrelic_notify logger.info("Patched zope.event:notify with instrumentation")
#Patch newrelic_application to work with a threading.local for early (own thread!) lock checking # import newrelic_application import newrelic_transaction # This is one is required: it creates the 'webtransaction' import zserverpublisher # Enable/disable as you like import zpublisher_mapply import zope_event import catalog_tool import talinterpreter import Globals import os from collective.newrelic.utils import logger try: # if the environment var was set, use this instead of the default (local) newrelic ini file config_file = os.environ.get('NEW_RELIC_CONFIG_FILE', 'newrelic.ini') newrelic.agent.initialize(config_file) logger.info('New Relic Python Agent configuration set from %s.' % config_file) except: pass
[v[1] for v in getAdapters((published, request,), ITransform)], key=attrgetter('order') ) trans = newrelic.agent.current_transaction() for handler in handlers: with newrelic.agent.FunctionTrace(trans, handler.__class__.__name__, 'Zope/Transform'): if isinstance(result, unicode): newResult = handler.transformUnicode(result, encoding) elif isinstance(result, str): newResult = handler.transformBytes(result, encoding) else: newResult = handler.transformIterable(result, encoding) if newResult is not None: result = newResult return result except ConflictError: raise except Exception: LOGGER.exception( u'Unexpected error whilst trying to apply transform chain' ) Transformer.__call__ = newrelic_transform__call__ logger.info( 'Patched plone.transformchain.transformer:Transformer.__call__ with instrumentation' )
from zope.tal.talinterpreter import TALInterpreter import newrelic.agent from collective.newrelic.utils import logger original_function = TALInterpreter.__call__ def monkeypatch(self): name = self.program[2][1].split('/') newrelic_monkeypatch = newrelic.agent.FunctionTraceWrapper(original_function, name[-1], 'Zope/TAL') newrelic_monkeypatch(self) TALInterpreter.__call__ = monkeypatch logger.info("Patched zope.tal.talinterpreter:TALInterpreter.__call__ with instrumentation")
import newrelic.agent import newrelic.api from Products.CMFPlone.CatalogTool import CatalogTool from collective.newrelic.utils import logger CatalogTool.original_cmfplone_catalogtool_searchResults = CatalogTool.searchResults def newrelic_searchResults(self, REQUEST=None, **kw): trans = newrelic.agent.current_transaction() with newrelic.api.database_trace.DatabaseTrace(trans, str(kw), self): result = self.original_cmfplone_catalogtool_searchResults(REQUEST, **kw) return result CatalogTool.searchResults = newrelic_searchResults logger.info("Patched Products.CMFPlone.CatalogTool:CatalogTool.searchResults with instrumentation")
trans = newrelic.agent.current_transaction() for handler in handlers: with newrelic.agent.FunctionTrace(trans, handler.__class__.__name__, 'Zope/Transform'): if isinstance(result, unicode): newResult = handler.transformUnicode(result, encoding) elif isinstance(result, str): newResult = handler.transformBytes(result, encoding) else: newResult = handler.transformIterable(result, encoding) if newResult is not None: result = newResult return result except ConflictError: raise except Exception, e: LOGGER.exception( u"Unexpected error whilst trying to apply transform chain") Transformer.__call__ = newrelic_transform__call__ logger.info( "Patched plone.transformchain.transformer:Transformer.__call__ with instrumentation" )
HAS_CRON4PLONE = False import newrelic.agent from collective.newrelic.utils import logger try: from Products.cron4plone.browser.views.cron_tick import CronTick HAS_CRON4PLONE = True except ImportError, e: # Doesn't have it! pass if HAS_CRON4PLONE: original_tick = CronTick.tick @newrelic.agent.background_task(name='crontick') def patched_tick(self, *args, **kwargs): original_tick(self, *args, **kwargs) CronTick.tick = patched_tick logger.info("Patched Products.cron4plone.browser.CronTick:tick to become a background task") else: logger.info("Unable to patched Products.cron4plone, probably not used.")