Exemple #1
0
    def CheckStats(self):
        """Checks if the last transmission of client stats is too long ago."""
        if self.last_stats_sent_time is None:
            self.last_stats_sent_time = rdfvalue.RDFDatetime().Now()
            stats.STATS.SetGaugeValue(
                "grr_client_last_stats_sent_time",
                self.last_stats_sent_time.AsSecondsFromEpoch())

        time_since_last_check = (rdfvalue.RDFDatetime().Now() -
                                 self.last_stats_sent_time)

        # No matter what, we don't want to send stats more often than
        # once per STATS_MIN_SEND_INTERVAL.
        if time_since_last_check < self.STATS_MIN_SEND_INTERVAL:
            return

        if (time_since_last_check > self.STATS_MAX_SEND_INTERVAL
                or self._is_active or self._send_stats_on_check):

            self._send_stats_on_check = False

            logging.info("Sending back client statistics to the server.")

            action_cls = actions.ActionPlugin.classes.get(
                "GetClientStatsAuto", actions.ActionPlugin)
            action = action_cls(grr_worker=self)
            action.Run(
                rdf_client.GetClientStatsRequest(
                    start_time=self.last_stats_sent_time))

            self.last_stats_sent_time = rdfvalue.RDFDatetime().Now()
            stats.STATS.SetGaugeValue(
                "grr_client_last_stats_sent_time",
                self.last_stats_sent_time.AsSecondsFromEpoch())
Exemple #2
0
    def Run(self, arg):
        """Returns the client stats."""
        if arg is None:
            arg = rdf_client.GetClientStatsRequest()

        proc = psutil.Process(os.getpid())
        meminfo = proc.memory_info()
        response = rdf_client.ClientStats(
            RSS_size=meminfo.rss,
            VMS_size=meminfo.vms,
            memory_percent=proc.memory_percent(),
            bytes_received=stats.STATS.GetMetricValue(
                "grr_client_received_bytes"),
            bytes_sent=stats.STATS.GetMetricValue("grr_client_sent_bytes"),
            create_time=long(proc.create_time() * 1e6),
            boot_time=long(psutil.boot_time() * 1e6))

        samples = self.grr_worker.stats_collector.cpu_samples
        for (timestamp, user, system, percent) in samples:
            if arg.start_time < timestamp < arg.end_time:
                sample = rdf_client.CpuSample(timestamp=timestamp,
                                              user_cpu_time=user,
                                              system_cpu_time=system,
                                              cpu_percent=percent)
                response.cpu_samples.Append(sample)

        samples = self.grr_worker.stats_collector.io_samples
        for (timestamp, read_bytes, write_bytes) in samples:
            if arg.start_time < timestamp < arg.end_time:
                sample = rdf_client.IOSample(timestamp=timestamp,
                                             read_bytes=read_bytes,
                                             write_bytes=write_bytes)
                response.io_samples.Append(sample)

        self.Send(response)
Exemple #3
0
    def Run(self, arg):
        """Returns the client stats."""
        if arg is None:
            arg = rdf_client.GetClientStatsRequest()

        proc = psutil.Process(os.getpid())
        meminfo = proc.memory_info()
        boot_time = rdfvalue.RDFDatetime.FromSecondsSinceEpoch(
            psutil.boot_time())
        create_time = rdfvalue.RDFDatetime.FromSecondsSinceEpoch(
            proc.create_time())
        response = rdf_client.ClientStats(
            RSS_size=meminfo.rss,
            VMS_size=meminfo.vms,
            memory_percent=proc.memory_percent(),
            bytes_received=stats.STATS.GetMetricValue(
                "grr_client_received_bytes"),
            bytes_sent=stats.STATS.GetMetricValue("grr_client_sent_bytes"),
            create_time=create_time,
            boot_time=boot_time)

        response.cpu_samples = self.grr_worker.stats_collector.CpuSamplesBetween(
            start_time=arg.start_time, end_time=arg.end_time)
        response.io_samples = self.grr_worker.stats_collector.IOSamplesBetween(
            start_time=arg.start_time, end_time=arg.end_time)

        self.Send(response)
Exemple #4
0
  def testReturnsAllDataByDefault(self):
    """Checks that stats collection works."""

    stats.STATS.RegisterCounterMetric("grr_client_received_bytes")
    stats.STATS.IncrementCounter("grr_client_received_bytes", 1566)

    stats.STATS.RegisterCounterMetric("grr_client_sent_bytes")
    stats.STATS.IncrementCounter("grr_client_sent_bytes", 2000)

    results = self.RunAction(
        admin.GetClientStats,
        grr_worker=MockClientWorker(),
        arg=rdf_client.GetClientStatsRequest())

    response = results[0]
    self.assertEqual(response.bytes_received, 1566)
    self.assertEqual(response.bytes_sent, 2000)

    self.assertEqual(len(response.cpu_samples), 3)
    for i in range(3):
      self.assertEqual(response.cpu_samples[i].timestamp,
                       rdfvalue.RDFDatetime.FromSecondsSinceEpoch(100 + i * 10))
      self.assertAlmostEqual(response.cpu_samples[i].user_cpu_time, 0.1)
      self.assertAlmostEqual(response.cpu_samples[i].system_cpu_time,
                             0.1 * (i + 1))
      self.assertAlmostEqual(response.cpu_samples[i].cpu_percent, 10.0 + 5 * i)

    self.assertEqual(len(response.io_samples), 3)
    for i in range(3):
      self.assertEqual(response.io_samples[i].timestamp,
                       rdfvalue.RDFDatetime.FromSecondsSinceEpoch(100 + i * 10))
      self.assertEqual(response.io_samples[i].read_bytes, 100 * (i + 1))
      self.assertEqual(response.io_samples[i].write_bytes, 100 * (i + 1))

    self.assertEqual(response.boot_time, long(100 * 1e6))
Exemple #5
0
  def testFiltersDataPointsByEndTime(self):
    end_time = rdfvalue.RDFDatetime().FromSecondsFromEpoch(102)
    results = self.RunAction(
        "GetClientStats", grr_worker=MockClientWorker(),
        arg=rdf_client.GetClientStatsRequest(end_time=end_time))

    response = results[0]
    self.assertEqual(len(response.cpu_samples), 1)
    self.assertEqual(response.cpu_samples[0].timestamp,
                     rdfvalue.RDFDatetime().FromSecondsFromEpoch(100))

    self.assertEqual(len(response.io_samples), 1)
    self.assertEqual(response.io_samples[0].timestamp,
                     rdfvalue.RDFDatetime().FromSecondsFromEpoch(100))
Exemple #6
0
    def testFiltersDataPointsByStartTime(self):
        start_time = rdfvalue.RDFDatetime().FromSecondsFromEpoch(117)
        results = self.RunAction(
            admin.GetClientStats,
            grr_worker=MockClientWorker(),
            arg=rdf_client.GetClientStatsRequest(start_time=start_time))

        response = results[0]
        self.assertEqual(len(response.cpu_samples), 1)
        self.assertEqual(response.cpu_samples[0].timestamp,
                         rdfvalue.RDFDatetime().FromSecondsFromEpoch(120))

        self.assertEqual(len(response.io_samples), 1)
        self.assertEqual(response.io_samples[0].timestamp,
                         rdfvalue.RDFDatetime().FromSecondsFromEpoch(120))
Exemple #7
0
    def _Send(self):
        if not self._ShouldSend():
            return

        # TODO(hanuszczak): We shouldn't manually create action instances. Instead,
        # we should refactor action code to some other function and make the action
        # class use that function. Then here we should use that function as well.
        #
        # Also, it looks like there is a very weird dependency triangle: the worker
        # creates stat collector (which requires a worker), then the stats action
        # requires a worker and uses stat collector internally. But this action is
        # spawned by the stat collector. What...?
        action = admin.GetClientStatsAuto(grr_worker=self._worker)
        request = rdf_client.GetClientStatsRequest(
            start_time=self._last_send_time)
        action.Run(request)

        self._should_send = False
        self._last_send_time = rdfvalue.RDFDatetime.Now()
        stats.STATS.SetGaugeValue("grr_client_last_stats_sent_time",
                                  self._last_send_time.AsSecondsSinceEpoch())