summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornicolargo <nicolas@nicolargo.com>2018-04-29 22:15:12 +0200
committernicolargo <nicolas@nicolargo.com>2018-04-29 22:15:12 +0200
commit4d32e070870f9dce972d6b0d9b2c7357ad49b345 (patch)
tree5d57788004a0f8d60a6a78b9a6667c53fc771e60
parente3e1aaf303872ec1f4447900a56d1e54c744260d (diff)
Stats updated during export (thread issue) #1250
-rw-r--r--NEWS1
-rw-r--r--glances/__init__.py2
-rw-r--r--glances/plugins/glances_alert.py10
-rw-r--r--glances/plugins/glances_amps.py36
-rw-r--r--glances/plugins/glances_batpercent.py21
-rw-r--r--glances/plugins/glances_cloud.py23
-rw-r--r--glances/plugins/glances_core.py20
-rw-r--r--glances/plugins/glances_cpu.py69
-rw-r--r--glances/plugins/glances_diskio.py22
-rw-r--r--glances/plugins/glances_docker.py20
-rw-r--r--glances/plugins/glances_folders.py17
-rw-r--r--glances/plugins/glances_fs.py24
-rw-r--r--glances/plugins/glances_gpu.py40
-rw-r--r--glances/plugins/glances_hddtemp.py19
-rw-r--r--glances/plugins/glances_ip.py27
-rw-r--r--glances/plugins/glances_irq.py24
-rw-r--r--glances/plugins/glances_load.py41
-rw-r--r--glances/plugins/glances_mem.py55
-rw-r--r--glances/plugins/glances_memswap.py48
-rw-r--r--glances/plugins/glances_network.py22
-rw-r--r--glances/plugins/glances_percpu.py19
-rw-r--r--glances/plugins/glances_plugin.py16
-rw-r--r--glances/plugins/glances_ports.py7
-rw-r--r--glances/plugins/glances_processcount.py15
-rw-r--r--glances/plugins/glances_processlist.py24
-rw-r--r--glances/plugins/glances_quicklook.py28
-rw-r--r--glances/plugins/glances_raid.py16
-rw-r--r--glances/plugins/glances_sensors.py27
-rw-r--r--glances/plugins/glances_system.py72
-rw-r--r--glances/plugins/glances_uptime.py17
-rw-r--r--glances/plugins/glances_wifi.py26
31 files changed, 373 insertions, 435 deletions
diff --git a/NEWS b/NEWS
index 0d43733c..9bd761fb 100644
--- a/NEWS
+++ b/NEWS
@@ -51,6 +51,7 @@ Bugs corrected:
* [WEB UI] Minor issue on the Web UI #1240
* [Glances 3.0 RC1] Client/Server is broken #1244
* Fixing horizontal scrolling #1248
+ * Stats updated during export (thread issue) #1250
Backward-incompatible changes:
diff --git a/glances/__init__.py b/glances/__init__.py
index b97d62a8..bf0bbe2d 100644
--- a/glances/__init__.py
+++ b/glances/__init__.py
@@ -27,7 +27,7 @@ import signal
import sys
# Global name
-__version__ = '3.0.rc2'
+__version__ = '3.0.rc3'
__author__ = 'Nicolas Hennion <nicolas@nicolargo.com>'
__license__ = 'LGPLv3'
diff --git a/glances/plugins/glances_alert.py b/glances/plugins/glances_alert.py
index e1c4ec62..159254c7 100644
--- a/glances/plugins/glances_alert.py
+++ b/glances/plugins/glances_alert.py
@@ -85,7 +85,8 @@ class Plugin(GlancesPlugin):
def __init__(self, args=None):
"""Init the plugin."""
- super(Plugin, self).__init__(args=args)
+ super(Plugin, self).__init__(args=args,
+ stats_init_value=[])
# We want to display the stat in the curse interface
self.display_curse = True
@@ -93,13 +94,6 @@ class Plugin(GlancesPlugin):
# Set the message position
self.align = 'bottom'
- # Init the stats
- self.reset()
-
- def reset(self):
- """Reset/init the stats."""
- self.stats = []
-
def update(self):
"""Nothing to do here. Just return the global glances_log."""
# Set the stats to the glances_logs
diff --git a/glances/plugins/glances_amps.py b/glances/plugins/glances_amps.py
index 9b85fe88..797556a0 100644
--- a/glances/plugins/glances_amps.py
+++ b/glances/plugins/glances_amps.py
@@ -2,7 +2,7 @@
#
# This file is part of Glances.
#
-# Copyright (C) 2017 Nicolargo <nicolas@nicolargo.com>
+# Copyright (C) 2018 Nicolargo <nicolas@nicolargo.com>
#
# Glances is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
@@ -29,7 +29,8 @@ class Plugin(GlancesPlugin):
def __init__(self, args=None, config=None):
"""Init the plugin."""
- super(Plugin, self).__init__(args=args)
+ super(Plugin, self).__init__(args=args,
+ stats_init_value=[])
self.args = args
self.config = config
@@ -39,35 +40,30 @@ class Plugin(GlancesPlugin):
# Init the list of AMP (classe define in the glances/amps_list.py script)
self.glances_amps = glancesAmpsList(self.args, self.config)
- # Init stats
- self.reset()
-
- def reset(self):
- """Reset/init the stats."""
- self.stats = []
-
@GlancesPlugin._check_decorator
@GlancesPlugin._log_result_decorator
def update(self):
"""Update the AMP list."""
- # Reset stats
- self.reset()
+ # Init new stats
+ stats = self.get_init_value()
if self.input_method == 'local':
for k, v in iteritems(self.glances_amps.update()):
- # self.stats.append({k: v.result()})
- self.stats.append({'key': k,
- 'name': v.NAME,
- 'result': v.result(),
- 'refresh': v.refresh(),
- 'timer': v.time_until_refresh(),
- 'count': v.count(),
- 'countmin': v.count_min(),
- 'countmax': v.count_max()})
+ stats.append({'key': k,
+ 'name': v.NAME,
+ 'result': v.result(),
+ 'refresh': v.refresh(),
+ 'timer': v.time_until_refresh(),
+ 'count': v.count(),
+ 'countmin': v.count_min(),
+ 'countmax': v.count_max()})
else:
# Not available in SNMP mode
pass
+ # Update the stats
+ self.stats = stats
+
return self.stats
def get_alert(self, nbprocess=0, countmin=None, countmax=None, header="", log=False):
diff --git a/glances/plugins/glances_batpercent.py b/glances/plugins/glances_batpercent.py
index c8aa5944..df7d9a77 100644
--- a/glances/plugins/glances_batpercent.py
+++ b/glances/plugins/glances_batpercent.py
@@ -2,7 +2,7 @@
#
# This file is part of Glances.
#
-# Copyright (C) 2017 Nicolargo <nicolas@nicolargo.com>
+# Copyright (C) 2018 Nicolargo <nicolas@nicolargo.com>
#
# Glances is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
@@ -51,7 +51,8 @@ class Plugin(GlancesPlugin):
def __init__(self, args=None):
"""Init the plugin."""
- super(Plugin, self).__init__(args=args)
+ super(Plugin, self).__init__(args=args,
+ stats_init_value=[])
# Init the sensor class
self.glancesgrabbat = GlancesGrabBat()
@@ -60,30 +61,26 @@ class Plugin(GlancesPlugin):
# The HDD temp is displayed within the sensors plugin
self.display_curse = False
- # Init stats
- self.reset()
-
- def reset(self):
- """Reset/init the stats."""
- self.stats = []
-
@GlancesPlugin._check_decorator
@GlancesPlugin._log_result_decorator
def update(self):
"""Update battery capacity stats using the input method."""
- # Reset stats
- self.reset()
+ # Init new stats
+ stats = self.get_init_value()
if self.input_method == 'local':
# Update stats
self.glancesgrabbat.update()
- self.stats = self.glancesgrabbat.get()
+ stats = self.glancesgrabbat.get()
elif self.input_method == 'snmp':
# Update stats using SNMP
# Not avalaible
pass
+ # Update the stats
+ self.stats = stats
+
return self.stats
diff --git a/glances/plugins/glances_cloud.py b/glances/plugins/glances_cloud.py
index 9ef29970..6f512e8c 100644
--- a/glances/plugins/glances_cloud.py
+++ b/glances/plugins/glances_cloud.py
@@ -67,10 +67,6 @@ class Plugin(GlancesPlugin):
# Run the thread
self.aws_ec2. start()
- def reset(self):
- """Reset/init the stats."""
- self.stats = {}
-
def exit(self):
"""Overwrite the exit method to close threads."""
self.aws_ec2.stop()
@@ -84,21 +80,24 @@ class Plugin(GlancesPlugin):
Return the stats (dict)
"""
- # Reset stats
- self.reset()
+ # Init new stats
+ stats = self.get_init_value()
# Requests lib is needed to get stats from the Cloud API
if import_error_tag:
- return self.stats
+ return stats
# Update the stats
if self.input_method == 'local':
# Example:
- # self.stats = {'ami-id': 'ami-id',
- # 'instance-id': 'instance-id',
- # 'instance-type': 'instance-type',
- # 'region': 'placement/availability-zone'}
- self.stats = self.aws_ec2.stats
+ # stats = {'ami-id': 'ami-id',
+ # 'instance-id': 'instance-id',
+ # 'instance-type': 'instance-type',
+ # 'region': 'placement/availability-zone'}
+ stats = self.aws_ec2.stats
+
+ # Update the stats
+ self.stats = stats
return self.stats
diff --git a/glances/plugins/glances_core.py b/glances/plugins/glances_core.py
index cfdf16a6..15d8025c 100644
--- a/glances/plugins/glances_core.py
+++ b/glances/plugins/glances_core.py
@@ -2,7 +2,7 @@
#
# This file is part of Glances.
#
-# Copyright (C) 2017 Nicolargo <nicolas@nicolargo.com>
+# Copyright (C) 2018 Nicolargo <nicolas@nicolargo.com>
#
# Glances is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
@@ -40,20 +40,13 @@ class Plugin(GlancesPlugin):
# The core number is displayed by the load plugin
self.display_curse = False
- # Init the stat
- self.reset()
-
- def reset(self):
- """Reset/init the stat using the input method."""
- self.stats = {}
-
def update(self):
"""Update core stats.
Stats is a dict (with both physical and log cpu number) instead of a integer.
"""
- # Reset the stats
- self.reset()
+ # Init new stats
+ stats = self.get_init_value()
if self.input_method == 'local':
# Update stats using the standard system lib
@@ -64,8 +57,8 @@ class Plugin(GlancesPlugin):
# - log: logical CPUs in the system
# Return None if undefine
try:
- self.stats["phys"] = psutil.cpu_count(logical=False)
- self.stats["log"] = psutil.cpu_count()
+ stats["phys"] = psutil.cpu_count(logical=False)
+ stats["log"] = psutil.cpu_count()
except NameError:
self.reset()
@@ -74,4 +67,7 @@ class Plugin(GlancesPlugin):
# http://stackoverflow.com/questions/5662467/how-to-find-out-the-number-of-cpus-using-snmp
pass
+ # Update the stats
+ self.stats = stats
+
return self.stats
diff --git a/glances/plugins/glances_cpu.py b/glances/plugins/glances_cpu.py
index cc824470..32a913ef 100644
--- a/glances/plugins/glances_cpu.py
+++ b/glances/plugins/glances_cpu.py
@@ -66,31 +66,27 @@ class Plugin(GlancesPlugin):
# We want to display the stat in the curse interface
self.display_curse = True
- # Init stats
- self.reset()
-
# Call CorePlugin in order to display the core number
try:
self.nb_log_core = CorePlugin(args=self.args).update()["log"]
except Exception:
self.nb_log_core = 1
- def reset(self):
- """Reset/init the stats."""
- self.stats = {}
-
@GlancesPlugin._check_decorator
@GlancesPlugin._log_result_decorator
def update(self):
"""Update CPU stats using the input method."""
- # Reset stats
- self.reset()
# Grab stats into self.stats
if self.input_method == 'local':
- self.update_local()
+ stats = self.update_local()
elif self.input_method == 'snmp':
- self.update_snmp()
+ stats = self.update_snmp()
+ else:
+ stats = self.get_init_value()
+
+ # Update the stats
+ self.stats = stats
return self.stats
@@ -101,12 +97,16 @@ class Plugin(GlancesPlugin):
# nice (UNIX), iowait (Linux), irq (Linux, FreeBSD), steal (Linux 2.6.11+)
# The following stats are returned by the API but not displayed in the UI:
# softirq (Linux), guest (Linux 2.6.24+), guest_nice (Linux 3.2.0+)
- self.stats['total'] = cpu_percent.get()
+
+ # Init new stats
+ stats = self.get_init_value()
+
+ stats['total'] = cpu_percent.get()
cpu_times_percent = psutil.cpu_times_percent(interval=0.0)
for stat in ['user', 'system', 'idle', 'nice', 'iowait',
'irq', 'softirq', 'steal', 'guest', 'guest_nice']:
if hasattr(cpu_times_percent, stat):
- self.stats[stat] = getattr(cpu_times_percent, stat)
+ stats[stat] = getattr(cpu_times_percent, stat)
# Additional CPU stats (number of events not as a %; psutil>=4.1.0)
# ctx_switches: number of context switches (voluntary + involuntary) per second
@@ -126,18 +126,24 @@ class Plugin(GlancesPlugin):
else:
for stat in cpu_stats._fields:
if getattr(cpu_stats, stat) is not None:
- self.stats[stat] = getattr(cpu_stats, stat) - getattr(self.cpu_stats_old, stat)
+ stats[stat] = getattr(cpu_stats, stat) - getattr(self.cpu_stats_old, stat)
- self.stats['time_since_update'] = time_since_update
+ stats['time_since_update'] = time_since_update
# Core number is needed to compute the CTX switch limit
- self.stats['cpucore'] = self.nb_log_core
+ stats['cpucore'] = self.nb_log_core
# Save stats to compute next step
self.cpu_stats_old = cpu_stats
+ return stats
+
def update_snmp(self):
"""Update CPU stats using SNMP."""
+
+ # Init new stats
+ stats = self.get_init_value()
+
# Update stats using SNMP
if self.short_system_name in ('windows', 'esxi'):
# Windows or VMWare ESXi
@@ -150,35 +156,36 @@ class Plugin(GlancesPlugin):
self.reset()
# Iter through CPU and compute the idle CPU stats
- self.stats['nb_log_core'] = 0
- self.stats['idle'] = 0
+ stats['nb_log_core'] = 0
+ stats['idle'] = 0
for c in cpu_stats:
if c.startswith('percent'):
- self.stats['idle'] += float(cpu_stats['percent.3'])
- self.stats['nb_log_core'] += 1
- if self.stats['nb_log_core'] > 0:
- self.stats['idle'] = self.stats[
- 'idle'] / self.stats['nb_log_core']
- self.stats['idle'] = 100 - self.stats['idle']
- self.stats['total'] = 100 - self.stats['idle']
+ stats['idle'] += float(cpu_stats['percent.3'])
+ stats['nb_log_core'] += 1
+ if stats['nb_log_core'] > 0:
+ stats['idle'] = stats['idle'] / stats['nb_log_core']
+ stats['idle'] = 100 - stats['idle']
+ stats['total'] = 100 - stats['idle']
else:
# Default behavor
try:
- self.stats = self.get_stats_snmp(
+ stats = self.get_stats_snmp(
snmp_oid=snmp_oid[self.short_system_name])
except KeyError:
- self.stats = self.get_stats_snmp(
+ stats = self.get_stats_snmp(
snmp_oid=snmp_oid['default'])
- if self.stats['idle'] == '':
+ if stats['idle'] == '':
self.reset()
return self.stats
# Convert SNMP stats to float
- for key in iterkeys(self.stats):
- self.stats[key] = float(self.stats[key])
- self.stats['total'] = 100 - self.stats['idle']
+ for key in iterkeys(stats):
+ stats[key] = float(stats[key])
+ stats['total'] = 100 - stats['idle']
+
+ return stats
def update_views(self):
"""Update stats views."""
diff --git a/glances/plugins/glances_diskio.py b/glances/plugins/glances_diskio.py
index 8ec3e312..535c8f5c 100644
--- a/glances/plugins/glances_diskio.py
+++ b/glances/plugins/glances_diskio.py
@@ -43,28 +43,23 @@ class Plugin(GlancesPlugin):
def __init__(self, args=None):
"""Init the plugin."""
- super(Plugin, self).__init__(args=args, items_history_list=items_history_list)
+ super(Plugin, self).__init__(args=args,
+ items_history_list=items_history_list,
+ stats_init_value=[])
# We want to display the stat in the curse interface
self.display_curse = True
- # Init the stats
- self.reset()
-
def get_key(self):
"""Return the key of the list."""
return 'disk_name'
- def reset(self):
- """Reset/init the stats."""
- self.stats = []
-
@GlancesPlugin._check_decorator
@GlancesPlugin._log_result_decorator
def update(self):
"""Update disk I/O stats using the input method."""
- # Reset stats
- self.reset()
+ # Init new stats
+ stats = self.get_init_value()
if self.input_method == 'local':
# Update stats using the standard system lib
@@ -78,7 +73,7 @@ class Plugin(GlancesPlugin):
try:
diskiocounters = psutil.disk_io_counters(perdisk=True)
except Exception:
- return self.stats
+ return stats
# Previous disk IO stats are stored in the diskio_old variable
if not hasattr(self, 'diskio_old'):
@@ -127,7 +122,7 @@ class Plugin(GlancesPlugin):
continue
else:
diskstat['key'] = self.get_key()
- self.stats.append(diskstat)
+ stats.append(diskstat)
# Save stats to compute next bitrate
self.diskio_old = diskio_new
@@ -136,6 +131,9 @@ class Plugin(GlancesPlugin):
# No standard way for the moment...
pass
+ # Update the stats
+ self.stats = stats
+
return self.stats
def update_views(self):
diff --git a/glances/plugins/glances_docker.py b/glances/plugins/glances_docker.py
index 08a875ff..fc396a3f 100644
--- a/glances/plugins/glances_docker.py
+++ b/glances/plugins/glances_docker.py
@@ -90,9 +90,6 @@ class Plugin(GlancesPlugin):
# value: instance of ThreadDockerGrabber
self.thread_list = {}
- # Init the stats
- self.reset()
-
def exit(self):
"""Overwrite the exit method to close threads."""
for t in itervalues(self.thread_list):
@@ -127,10 +124,6 @@ class Plugin(GlancesPlugin):
return ret
- def reset(self):
- """Reset/init the stats."""
- self.stats = {}
-
def _all_tag(self):
"""Return the all tag of the Glances/Docker configuration file.
@@ -148,8 +141,8 @@ class Plugin(GlancesPlugin):
@GlancesPlugin._log_result_decorator
def update(self):
"""Update Docker stats using the input method."""
- # Reset stats
- self.reset()
+ # Init new stats
+ stats = self.get_init_value()
# The Docker-py lib is mandatory
if import_error_tag:
@@ -169,7 +162,7 @@ class Plugin(GlancesPlugin):
# "GoVersion": "go1.3.3"
# }
try:
- self.stats['version'] = self.docker_client.version()
+ stats['version'] = self.docker_client.version()
except Exception as e:
# Correct issue#649
logger.error("{} plugin - Cannot get Docker version ({})".format(self.plugin_name, e))
@@ -204,7 +197,7 @@ class Plugin(GlancesPlugin):
del self.thread_list[container_id]
# Get stats for all containers
- self.stats['containers'] = []
+ stats['containers'] = []
for container in containers:
# Init the stats for the current container
container_stats = {}
@@ -245,13 +238,16 @@ class Plugin(GlancesPlugin):
container_stats['network_rx'] = None
container_stats['network_tx'] = None
# Add current container stats to the stats list
- self.stats['containers'].append(container_stats)
+ stats['containers'].append(container_stats)
elif self.input_method == 'snmp':
# Update stats using SNMP
# Not available
pass
+ # Update the stats
+ self.stats = stats
+
return self.stats
def get_docker_cpu(self, container_id, all_stats):
diff --git a/glances/plugins/glances_folders.py b/glances/plugins/glances_folders.py
index f9bee535..f5275482 100644
--- a/glances/plugins/glances_folders.py
+++ b/glances/plugins/glances_folders.py
@@ -31,23 +31,19 @@ class Plugin(GlancesPlugin):
def __init__(self, args=None):
"""Init the plugin."""
- super(Plugin, self).__init__(args=args)
+ super(Plugin, self).__init__(args=args,
+ stats_init_value=[])
# We want to display the stat in the curse interface
self.display_curse = True
# Init stats
self.glances_folders = None
- self.reset()
def get_key(self):
"""Return the key of the list."""
return 'path'
- def reset(self):
- """Reset/init the stats."""
- self.stats = []
-
def load_limits(self, config):
"""Load the foldered list from the config file, if it exists."""
self.glances_folders = glancesFolderList(config)
@@ -56,8 +52,8 @@ class Plugin(GlancesPlugin):
@GlancesPlugin._log_result_decorator
def update(self):
"""Update the foldered list."""
- # Reset the list
- self.reset()
+ # Init new stats
+ stats = self.get_init_value()
if self.input_method == 'local':
# Folder list only available in a full Glances environment
@@ -69,10 +65,13 @@ class Plugin(GlancesPlugin):
self.glances_folders.update()
# Put it on the stats var
- self.stats = self.glances_folders.get()
+ stats = self.glances_folders.get()
else:
pass
+ # Update the stats
+ self.stats = stats
+
return self.stats
def get_alert(self, stat):
diff --git a/glances/plugins/glances_fs.py b/glances/plugins/glances_fs.py
index 6dfef0c1..5e229b3d 100644
--- a/glances/plugins/glances_fs.py
+++ b/glances/plugins/glances_fs.py
@@ -71,28 +71,23 @@ class Plugin(GlancesPlugin):
def __init__(self, args=None):
"""Init the plugin."""
- super(Plugin, self).__init__(args=args, items_history_list=items_history_list)
+ super(Plugin, self).__init__(args=args,
+ items_history_list=items_history_list,
+ stats_init_value=[])
# We want to display the stat in the curse interface
self.display_curse = True
- # Init the stats
- self.reset()
-
def get_key(self):
"""Return the key of the list."""
return 'mnt_point'
- def reset(self):
- """Reset/init the stats."""
- self.stats = []
-
@GlancesPlugin._check_decorator
@GlancesPlugin._log_result_decorator
def update(self):
"""Update the FS stats using the input method."""
- # Reset the list
- self.reset()
+ # Init new stats
+ stats = self.get_init_value()
if self.input_method == 'local':
# Update stats using the standard system lib
@@ -136,7 +131,7 @@ class Plugin(GlancesPlugin):
'free': fs_usage.free,
'percent': fs_usage.percent,
'key': self.get_key()}
- self.stats.append(fs_current)
+ stats.append(fs_current)
elif self.input_method == 'snmp':
# Update stats using SNMP
@@ -166,7 +161,7 @@ class Plugin(GlancesPlugin):
'used': used,
'percent': percent,
'key': self.get_key()}
- self.stats.append(fs_current)
+ stats.append(fs_current)
else:
# Default behavior
for fs in fs_stat:
@@ -177,7 +172,10 @@ class Plugin(GlancesPlugin):
'used': int(fs_stat[fs]['used']) * 1024,
'percent': float(fs_stat[fs]['percent']),
'key': self.get_key()}
- self.stats.append(fs_current)
+ stats.append(fs_current)
+
+ # Update the stats
+ self.stats = stats
return self.stats
diff --git a/glances/plugins/glances_gpu.py b/glances/plugins/glances_gpu.py
index fc6c2367..19826811 100644
--- a/glances/plugins/glances_gpu.py
+++ b/glances/plugins/glances_gpu.py
@@ -2,7 +2,7 @@
#
# This file is part of Glances.
#
-# Copyright (C) 2017 Kirby Banman <kirby.banman@gmail.com>
+# Copyright (C) 2018 Kirby Banman <kirby.banman@gmail.com>
#
# Glances is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
@@ -41,7 +41,8 @@ class Plugin(GlancesPlugin):
def __init__(self, args=None):
"""Init the plugin."""
- super(Plugin, self).__init__(args=args)
+ super(Plugin, self).__init__(args=args,
+ stats_init_value=[])
# Init the NVidia API
self.init_nvidia()
@@ -49,13 +50,6 @@ class Plugin(GlancesPlugin):
# We want to display the stat in the curse interface
self.display_curse = True
- # Init the stats
- self.reset()
-
- def reset(self):
- """Reset/init the stats."""