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)
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))
def testFiltersDataPointsByEndTime(self): end_time = rdfvalue.RDFDatetime.FromSecondsSinceEpoch(102) results = self.RunAction( admin.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.FromSecondsSinceEpoch(100)) self.assertEqual(len(response.io_samples), 1) self.assertEqual(response.io_samples[0].timestamp, rdfvalue.RDFDatetime.FromSecondsSinceEpoch(100))
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())