示例#1
0
    def _collect_runtime_snapshot(self, plugin_data):
        """ Gathers Python specific Snapshot information for this process """
        snapshot_payload = {}
        try:
            snapshot_payload['name'] = determine_service_name()
            snapshot_payload['version'] = sys.version
            snapshot_payload['f'] = platform.python_implementation()  # flavor
            snapshot_payload['a'] = platform.architecture()[0]  # architecture
            snapshot_payload['versions'] = self.gather_python_packages()
            snapshot_payload['iv'] = VERSION

            if 'AUTOWRAPT_BOOTSTRAP' in os.environ:
                snapshot_payload['m'] = 'Autowrapt'
            elif 'INSTANA_MAGIC' in os.environ:
                snapshot_payload['m'] = 'AutoTrace'
            else:
                snapshot_payload['m'] = 'Manual'

            try:
                from django.conf import settings  # pylint: disable=import-outside-toplevel
                if hasattr(settings,
                           'MIDDLEWARE') and settings.MIDDLEWARE is not None:
                    snapshot_payload['djmw'] = settings.MIDDLEWARE
                elif hasattr(settings, 'MIDDLEWARE_CLASSES'
                             ) and settings.MIDDLEWARE_CLASSES is not None:
                    snapshot_payload['djmw'] = settings.MIDDLEWARE_CLASSES
            except Exception:
                pass
        except Exception:
            logger.debug("collect_snapshot: ", exc_info=True)

        plugin_data['data']['snapshot'] = snapshot_payload
    def _collect_gc_metrics(self, plugin_data, with_snapshot):
        try:
            gc_count = gc.get_count()
            gc_threshold = gc.get_threshold()

            self.apply_delta(gc_count[0],
                             self.previous['data']['metrics']['gc'],
                             plugin_data['data']['metrics']['gc'], "collect0",
                             with_snapshot)
            self.apply_delta(gc_count[1],
                             self.previous['data']['metrics']['gc'],
                             plugin_data['data']['metrics']['gc'], "collect1",
                             with_snapshot)
            self.apply_delta(gc_count[2],
                             self.previous['data']['metrics']['gc'],
                             plugin_data['data']['metrics']['gc'], "collect2",
                             with_snapshot)

            self.apply_delta(gc_threshold[0],
                             self.previous['data']['metrics']['gc'],
                             plugin_data['data']['metrics']['gc'],
                             "threshold0", with_snapshot)
            self.apply_delta(gc_threshold[1],
                             self.previous['data']['metrics']['gc'],
                             plugin_data['data']['metrics']['gc'],
                             "threshold1", with_snapshot)
            self.apply_delta(gc_threshold[2],
                             self.previous['data']['metrics']['gc'],
                             plugin_data['data']['metrics']['gc'],
                             "threshold2", with_snapshot)
        except Exception:
            logger.debug("_collect_gc_metrics", exc_info=True)
示例#3
0
    def collect(instance, args, kwargs):
        """ Build and return a fully qualified URL for this request """
        try:
            kvs = {}

            kvs['host'] = instance.host
            kvs['port'] = instance.port

            if args is not None and len(args) is 2:
                kvs['method'] = args[0]
                kvs['path'] = args[1]
            else:
                kvs['method'] = kwargs['method']
                kvs['path'] = kwargs['url']

            if type(instance) is urllib3.connectionpool.HTTPSConnectionPool:
                kvs['url'] = 'https://%s:%d%s' % (kvs['host'], kvs['port'],
                                                  kvs['path'])
            else:
                kvs['url'] = 'http://%s:%d%s' % (kvs['host'], kvs['port'],
                                                 kvs['path'])
        except Exception as e:
            logger.debug(e)
            return kvs
        else:
            return kvs
 def jsonable(self, value):
     try:
         if callable(value):
             try:
                 result = value()
             except Exception:
                 result = 'Unknown'
         elif isinstance(value, ModuleType):
             result = value
         else:
             result = value
         return str(result)
     except Exception:
         logger.debug("jsonable: ", exc_info=True)
    def collect_metrics(self, with_snapshot=False):
        plugin_data = dict()
        try:
            plugin_data["name"] = "com.instana.plugin.python"
            plugin_data["entityId"] = str(os.getpid())
            plugin_data["data"] = DictionaryOfStan()
            plugin_data["data"]["pid"] = str(os.getpid())

            self._collect_runtime_metrics(plugin_data, with_snapshot)

            if with_snapshot is True:
                self._collect_runtime_snapshot(plugin_data)
        except Exception:
            logger.debug("_collect_metrics: ", exc_info=True)
        return [plugin_data]
示例#6
0
    def collect_metrics(self, with_snapshot=False):
        plugin_data = dict()
        try:
            plugin_data["name"] = "com.instana.plugin.process"
            plugin_data["entityId"] = str(os.getpid())
            plugin_data["data"] = DictionaryOfStan()
            plugin_data["data"]["pid"] = int(os.getpid())
            plugin_data["data"]["containerType"] = "docker"
            if self.collector.root_metadata is not None:
                plugin_data["data"]["container"] = self.collector.root_metadata.get("DockerId")

            if with_snapshot:
                self._collect_process_snapshot(plugin_data)
        except Exception:
            logger.debug("ProcessHelper.collect_metrics: ", exc_info=True)
        return [plugin_data]
示例#7
0
    def process_request(self, request):
        try:
            env = request.environ
            if 'HTTP_X_INSTANA_T' in env and 'HTTP_X_INSTANA_S' in env:
                ctx = internal_tracer.extract(ot.Format.HTTP_HEADERS, env)
                span = internal_tracer.start_span("django", child_of=ctx)
            else:
                span = internal_tracer.start_span("django")

            span.set_tag(ext.HTTP_URL, env['PATH_INFO'])
            span.set_tag("http.params", env['QUERY_STRING'])
            span.set_tag(ext.HTTP_METHOD, request.method)
            span.set_tag("http.host", env['HTTP_HOST'])
            self.span = span
        except Exception as e:
            logger.debug("Instana middleware @ process_response: ", e)
示例#8
0
def eum_test_snippet(trace_id=None, eum_api_key=None, meta=None):
    """
    Return an EUM snippet for use in views, templates and layouts that reports
    client side metrics to Instana that will automagically be linked to the
    current trace.

    @param trace_id [optional] the trace ID to insert into the EUM string
    @param eum_api_key [optional] the EUM API key from your Instana dashboard
    @param meta [optional] optional additional KVs you want reported with the
                EUM metrics

    @return string
    """

    try:
        eum_file = open(os.path.dirname(__file__) + '/eum_test.js')
        eum_src = Template(eum_file.read())

        # Prepare the standard required IDs
        ids = {}
        ids['meta_kvs'] = ''

        parent_span = tracer.active_span
        if trace_id or parent_span:
            ids['trace_id'] = trace_id or parent_span.trace_id
        else:
            # No trace_id passed in and tracer doesn't show an active span so
            # return nothing, nada & zip.
            return ''

        if eum_api_key:
            ids['eum_api_key'] = eum_api_key
        else:
            ids['eum_api_key'] = global_eum_api_key

        # Process passed in EUM 'meta' key/values
        if meta is not None:
            for key, value in meta.items():
                ids['meta_kvs'] += ("'ineum('meta', '%s', '%s');'" %
                                    (key, value))

        return eum_src.substitute(ids)
    except Exception:
        logger.debug("eum_snippet: ", exc_info=True)
        return ''
示例#9
0
    def process_response(self, request, response):
        try:
            if self.span:
                if 500 <= response.status_code <= 511:
                    self.span.set_tag("error", True)
                    ec = self.span.tags.get('ec', 0)
                    if ec is 0:
                        self.span.set_tag("ec", ec + 1)

                self.span.set_tag(ext.HTTP_STATUS_CODE, response.status_code)
                internal_tracer.inject(self.span.context,
                                       ot.Format.HTTP_HEADERS, response)
                self.span.finish()
                self.span = None
        except Exception as e:
            logger.debug("Instana middleware @ process_response: ", e)
        finally:
            return response
示例#10
0
    def gather_python_packages(self):
        """ Collect up the list of modules in use """
        versions = dict()
        try:
            sys_packages = sys.modules.copy()

            for pkg_name in sys_packages:
                # Don't report submodules (e.g. django.x, django.y, django.z)
                # Skip modules that begin with underscore
                if ('.' in pkg_name) or pkg_name[0] == '_':
                    continue

                # Skip builtins
                if pkg_name in ["sys", "curses"]:
                    continue

                if sys_packages[pkg_name]:
                    try:
                        pkg_info = sys_packages[pkg_name].__dict__
                        if "__version__" in pkg_info:
                            if isinstance(pkg_info["__version__"], str):
                                versions[pkg_name] = pkg_info["__version__"]
                            else:
                                versions[pkg_name] = self.jsonable(
                                    pkg_info["__version__"])
                        elif "version" in pkg_info:
                            versions[pkg_name] = self.jsonable(
                                pkg_info["version"])
                        else:
                            versions[pkg_name] = get_distribution(
                                pkg_name).version
                    except DistributionNotFound:
                        pass
                    except Exception:
                        logger.debug(
                            "gather_python_packages: could not process module: %s",
                            pkg_name)

            # Manually set our package version
            versions['instana'] = VERSION
        except Exception:
            logger.debug("gather_python_packages", exc_info=True)

        return versions
示例#11
0
    def _collect_process_snapshot(self, plugin_data):
        try:
            env = dict()
            for key in os.environ:
                if contains_secret(key,
                                   self.collector.agent.options.secrets_matcher,
                                   self.collector.agent.options.secrets_list):
                    env[key] = "<ignored>"
                else:
                    env[key] = os.environ[key]
            plugin_data["data"]["env"] = env
            if os.path.isfile("/proc/self/exe"):
                plugin_data["data"]["exec"] = os.readlink("/proc/self/exe")
            else:
                logger.debug("Can't access /proc/self/exe...")

            cmdline = get_proc_cmdline()
            if len(cmdline) > 1:
                # drop the exe
                cmdline.pop(0)
            plugin_data["data"]["args"] = cmdline
            try:
                euid = os.geteuid()
                egid = os.getegid()
                plugin_data["data"]["user"] = pwd.getpwuid(euid)
                plugin_data["data"]["group"] = grp.getgrgid(egid).gr_name
            except Exception:
                logger.debug("euid/egid detection: ", exc_info=True)

            plugin_data["data"]["start"] = 1 # FIXME: process start time reporting
            if self.collector.task_metadata is not None:
                plugin_data["data"]["com.instana.plugin.host.name"] = self.collector.task_metadata.get("TaskArn")
        except Exception:
            logger.debug("ProcessHelper._collect_process_snapshot: ", exc_info=True)
示例#12
0
    def _collect_thread_metrics(self, plugin_data, with_snapshot):
        try:
            threads = threading.enumerate()
            daemon_threads = [thread.daemon is True
                              for thread in threads].count(True)
            self.apply_delta(daemon_threads, self.previous['data']['metrics'],
                             plugin_data['data']['metrics'], "daemon_threads",
                             with_snapshot)

            alive_threads = [thread.daemon is False
                             for thread in threads].count(True)
            self.apply_delta(alive_threads, self.previous['data']['metrics'],
                             plugin_data['data']['metrics'], "alive_threads",
                             with_snapshot)

            dummy_threads = [
                isinstance(thread, threading._DummyThread)
                for thread in threads
            ].count(True)  # pylint: disable=protected-access
            self.apply_delta(dummy_threads, self.previous['data']['metrics'],
                             plugin_data['data']['metrics'], "dummy_threads",
                             with_snapshot)
        except Exception:
            logger.debug("_collect_thread_metrics", exc_info=True)
示例#13
0
    def _collect_runtime_metrics(self, plugin_data, with_snapshot):
        """ Collect up and return the runtime metrics """
        try:
            rusage = resource.getrusage(resource.RUSAGE_SELF)
            if gc.isenabled():
                self._collect_gc_metrics(plugin_data, with_snapshot)

            self._collect_thread_metrics(plugin_data, with_snapshot)

            value_diff = rusage.ru_utime - self.previous_rusage.ru_utime
            self.apply_delta(value_diff, self.previous['data']['metrics'],
                             plugin_data['data']['metrics'], "ru_utime",
                             with_snapshot)

            value_diff = rusage.ru_stime - self.previous_rusage.ru_stime
            self.apply_delta(value_diff, self.previous['data']['metrics'],
                             plugin_data['data']['metrics'], "ru_stime",
                             with_snapshot)

            self.apply_delta(rusage.ru_maxrss,
                             self.previous['data']['metrics'],
                             plugin_data['data']['metrics'], "ru_maxrss",
                             with_snapshot)
            self.apply_delta(rusage.ru_ixrss, self.previous['data']['metrics'],
                             plugin_data['data']['metrics'], "ru_ixrss",
                             with_snapshot)
            self.apply_delta(rusage.ru_idrss, self.previous['data']['metrics'],
                             plugin_data['data']['metrics'], "ru_idrss",
                             with_snapshot)
            self.apply_delta(rusage.ru_isrss, self.previous['data']['metrics'],
                             plugin_data['data']['metrics'], "ru_isrss",
                             with_snapshot)

            value_diff = rusage.ru_minflt - self.previous_rusage.ru_minflt
            self.apply_delta(value_diff, self.previous['data']['metrics'],
                             plugin_data['data']['metrics'], "ru_minflt",
                             with_snapshot)

            value_diff = rusage.ru_majflt - self.previous_rusage.ru_majflt
            self.apply_delta(value_diff, self.previous['data']['metrics'],
                             plugin_data['data']['metrics'], "ru_majflt",
                             with_snapshot)

            value_diff = rusage.ru_nswap - self.previous_rusage.ru_nswap
            self.apply_delta(value_diff, self.previous['data']['metrics'],
                             plugin_data['data']['metrics'], "ru_nswap",
                             with_snapshot)

            value_diff = rusage.ru_inblock - self.previous_rusage.ru_inblock
            self.apply_delta(value_diff, self.previous['data']['metrics'],
                             plugin_data['data']['metrics'], "ru_inblock",
                             with_snapshot)

            value_diff = rusage.ru_oublock - self.previous_rusage.ru_oublock
            self.apply_delta(value_diff, self.previous['data']['metrics'],
                             plugin_data['data']['metrics'], "ru_oublock",
                             with_snapshot)

            value_diff = rusage.ru_msgsnd - self.previous_rusage.ru_msgsnd
            self.apply_delta(value_diff, self.previous['data']['metrics'],
                             plugin_data['data']['metrics'], "ru_msgsnd",
                             with_snapshot)

            value_diff = rusage.ru_msgrcv - self.previous_rusage.ru_msgrcv
            self.apply_delta(value_diff, self.previous['data']['metrics'],
                             plugin_data['data']['metrics'], "ru_msgrcv",
                             with_snapshot)

            value_diff = rusage.ru_nsignals - self.previous_rusage.ru_nsignals
            self.apply_delta(value_diff, self.previous['data']['metrics'],
                             plugin_data['data']['metrics'], "ru_nsignals",
                             with_snapshot)

            value_diff = rusage.ru_nvcsw - self.previous_rusage.ru_nvcsw
            self.apply_delta(value_diff, self.previous['data']['metrics'],
                             plugin_data['data']['metrics'], "ru_nvcsw",
                             with_snapshot)

            value_diff = rusage.ru_nivcsw - self.previous_rusage.ru_nivcsw
            self.apply_delta(value_diff, self.previous['data']['metrics'],
                             plugin_data['data']['metrics'], "ru_nivcsw",
                             with_snapshot)
        except Exception:
            logger.debug("_collect_runtime_metrics", exc_info=True)
        finally:
            self.previous_rusage = rusage