diff --git a/ldms/python/ldms.pxd b/ldms/python/ldms.pxd index b6def8cd0..f6ff1d1d4 100644 --- a/ldms/python/ldms.pxd +++ b/ldms/python/ldms.pxd @@ -820,9 +820,9 @@ cdef extern from "ldms.h" nogil: void ldms_stream_stats_tq_free(ldms_stream_stats_tq_s *tq) char *ldms_stream_stats_tq_to_str(ldms_stream_stats_tq_s *tq) char *ldms_stream_stats_str(char *match, int is_regex) - ldms_stream_client_stats_tq_s *ldms_stream_client_stats_tq_get() + ldms_stream_client_stats_tq_s *ldms_stream_client_stats_tq_get(int is_reset) void ldms_stream_client_stats_tq_free(ldms_stream_client_stats_tq_s *tq) - ldms_stream_client_stats_s *ldms_stream_client_get_stats(ldms_stream_client_t cli) + ldms_stream_client_stats_s *ldms_stream_client_get_stats(ldms_stream_client_t cli, int is_reset) void ldms_stream_client_stats_free(ldms_stream_client_stats_s *cs) char *ldms_stream_client_stats_tq_to_str(ldms_stream_client_stats_tq_s *tq) char *ldms_stream_client_stats_str() diff --git a/ldms/python/ldms.pyx b/ldms/python/ldms.pyx index e0705cf6d..dc2076cbb 100644 --- a/ldms/python/ldms.pyx +++ b/ldms/python/ldms.pyx @@ -4003,11 +4003,11 @@ def stream_stats_get(stream_match=None, is_regex=0, is_reset=0): ldms_stream_stats_tq_free(tq) return ret -def stream_client_stats_get(): +def stream_client_stats_get(is_reset=0): """Get a collection of stats of stream clients in this process""" cdef ldms_stream_client_stats_tq_s *tq cdef ldms_stream_client_stats_s *cs - tq = ldms_stream_client_stats_tq_get() + tq = ldms_stream_client_stats_tq_get(is_reset) ret = list() if not tq: if errno == ENOENT: @@ -4071,12 +4071,12 @@ cdef class StreamClient(object): except Empty as e: return None - def stats(self): + def stats(self, is_reset=0): """Get the client stats""" cdef ldms_stream_client_stats_s *cs; if not self.c: raise RuntimeError("client has been closed") - cs = ldms_stream_client_get_stats(self.c) + cs = ldms_stream_client_get_stats(self.c, is_reset) if not cs: raise RuntimeError(f"error: {ERRNO_SYM(errno)}({errno})") try: diff --git a/ldms/python/ldmsd/ldmsd_communicator.py b/ldms/python/ldmsd/ldmsd_communicator.py index 35b981326..bad637ab0 100644 --- a/ldms/python/ldmsd/ldmsd_communicator.py +++ b/ldms/python/ldmsd/ldmsd_communicator.py @@ -143,7 +143,7 @@ 'stream_client_dump': {'req_attr': [], 'opt_attr': []}, 'stream_status' : {'req_attr': [], 'opt_attr': ['reset']}, 'stream_stats' : {'req_attr': [], 'opt_attr': ['regex', 'stream', 'json', 'reset']}, - 'stream_client_stats' : {'req_attr': [], 'opt_attr': ['json']}, + 'stream_client_stats' : {'req_attr': [], 'opt_attr': ['json', 'reset']}, ##### Daemon ##### 'daemon_status': {'req_attr': [], 'opt_attr': ['thread_stats']}, ##### Misc. ##### @@ -1417,7 +1417,7 @@ def stream_stats(self, regex=None, stream=None, reset=None): except Exception as e: return errno.ENOTCONN, str(e) - def stream_client_stats(self): + def stream_client_stats(self, reset=None): """ Dump stream stats @@ -1425,7 +1425,10 @@ def stream_client_stats(self): regex - The regular expression matching the stream names stream - The exact match of the stearm name """ - req = LDMSD_Request(command_id=LDMSD_Request.STREAM_CLIENT_STATS, attrs = []) + attr_list = [] + if reset is not None: + attr_list = [LDMSD_Req_Attr(attr_name='reset', value=reset)] + req = LDMSD_Request(command_id=LDMSD_Request.STREAM_CLIENT_STATS, attrs = attr_list) try: req.send(self) resp = req.receive(self) diff --git a/ldms/python/ldmsd/ldmsd_controller b/ldms/python/ldmsd/ldmsd_controller index 0f30898e2..92e2151ab 100755 --- a/ldms/python/ldmsd/ldmsd_controller +++ b/ldms/python/ldmsd/ldmsd_controller @@ -2617,7 +2617,7 @@ class LdmsdCmdParser(cmd.Cmd): arg = self.handle_args('stream_stats', arg) if arg is None: return - rc, msg = self.comm.stream_client_stats() + rc, msg = self.comm.stream_client_stats(arg['reset']) if rc: emsg = f"stream_client_stats error: {rc}, msg: {msg}" print(emsg) diff --git a/ldms/src/core/ldms.h b/ldms/src/core/ldms.h index caddac459..1261b4131 100644 --- a/ldms/src/core/ldms.h +++ b/ldms/src/core/ldms.h @@ -1349,8 +1349,10 @@ char *ldms_stream_stats_str(const char *match, int is_regex, int is_reset); /** * Returns a collection of stats of stream clients. + * + * \param is_reset A non-zero value means to reset the statistics */ -struct ldms_stream_client_stats_tq_s *ldms_stream_client_stats_tq_get(); +struct ldms_stream_client_stats_tq_s *ldms_stream_client_stats_tq_get(int is_reset); /** * Free the stats entries in the \c tq and the \c tq itself. @@ -1359,8 +1361,11 @@ void ldms_stream_client_stats_tq_free(struct ldms_stream_client_stats_tq_s *tq); /** * Get stats from a client. + * + * \param is_reset A non-zero value means to reset the statistics */ -struct ldms_stream_client_stats_s *ldms_stream_client_get_stats(ldms_stream_client_t cli); +struct ldms_stream_client_stats_s * +ldms_stream_client_get_stats(ldms_stream_client_t cli, int is_reset); /** * Free the stream client stats obtained form \c ldms_stream_client_get_stats(). @@ -1378,8 +1383,10 @@ char *ldms_stream_client_stats_tq_to_str(struct ldms_stream_client_stats_tq_s *t * \brief Return a string describing statuses/statistics of stream clients in this process. * \retval str The string describing the stats. * \note The caller is responsible for freeing the returned string. + * + * \param is_reset non-zero means to reset the statistics */ -char *ldms_stream_client_stats_str(); +char *ldms_stream_client_stats_str(int is_reset); /** \} */ diff --git a/ldms/src/core/ldms_stream.c b/ldms/src/core/ldms_stream.c index bec2d191f..54293fe73 100644 --- a/ldms/src/core/ldms_stream.c +++ b/ldms/src/core/ldms_stream.c @@ -1762,7 +1762,7 @@ char *ldms_stream_stats_str(const char *match, int is_regex, int is_reset) } struct ldms_stream_client_stats_s * -ldms_stream_client_get_stats(ldms_stream_client_t cli) +ldms_stream_client_get_stats(ldms_stream_client_t cli, int is_reset) { struct ldms_stream_client_stats_s *cs = NULL; struct ldms_stream_client_entry_s *sce; @@ -1781,6 +1781,11 @@ ldms_stream_client_get_stats(ldms_stream_client_t cli) cs->tx = cli->tx; cs->is_regex = cli->is_regex; + if (is_reset) { + LDMS_STREAM_COUNTERS_INIT(&cli->tx); + LDMS_STREAM_COUNTERS_INIT(&cli->drops); + } + TAILQ_FOREACH(sce, &cli->stream_tq, client_stream_entry) { /* name_len included '\0' */ cps = malloc(sizeof(*cps) + sce->stream->name_len); @@ -1794,6 +1799,10 @@ ldms_stream_client_get_stats(ldms_stream_client_t cli) cps->is_regex = sce->client->is_regex; cps->tx = sce->tx; cps->drops = sce->drops; + if (is_reset) { + LDMS_STREAM_COUNTERS_INIT(&sce->tx); + LDMS_STREAM_COUNTERS_INIT(&sce->drops); + } TAILQ_INSERT_TAIL(&cs->pair_tq, cps, entry); } @@ -1820,7 +1829,7 @@ void ldms_stream_client_stats_free(struct ldms_stream_client_stats_s *cs) free(cs); } -struct ldms_stream_client_stats_tq_s *ldms_stream_client_stats_tq_get() +struct ldms_stream_client_stats_tq_s *ldms_stream_client_stats_tq_get(int is_reset) { struct ldms_stream_client_stats_tq_s *tq; struct ldms_stream_client_stats_s *cs; @@ -1838,7 +1847,7 @@ struct ldms_stream_client_stats_tq_s *ldms_stream_client_stats_tq_get() /* go through regex clients first */ TAILQ_FOREACH(cli, &__regex_client_tq, entry) { - cs = ldms_stream_client_get_stats(cli); + cs = ldms_stream_client_get_stats(cli, is_reset); if (!cs) goto err_0; TAILQ_INSERT_TAIL(tq, cs, entry); @@ -1854,7 +1863,7 @@ struct ldms_stream_client_stats_tq_s *ldms_stream_client_stats_tq_get() continue; if (cli->is_regex) continue; /* already handled above */ - cs = ldms_stream_client_get_stats(cli); + cs = ldms_stream_client_get_stats(cli, is_reset); if (!cs) { pthread_rwlock_unlock(&s->rwlock); goto err_0; @@ -1948,11 +1957,11 @@ char *ldms_stream_client_stats_tq_to_str(struct ldms_stream_client_stats_tq_s *t return ret; } -char *ldms_stream_client_stats_str() +char *ldms_stream_client_stats_str(int is_reset) { struct ldms_stream_client_stats_tq_s *tq; char *ret = NULL; - tq = ldms_stream_client_stats_tq_get(); + tq = ldms_stream_client_stats_tq_get(is_reset); if (!tq) { if (errno == ENOENT) { ret = strdup("[]"); diff --git a/ldms/src/ldmsd/ldmsd_request.c b/ldms/src/ldmsd/ldmsd_request.c index e0b66ced1..b5bbcd98f 100644 --- a/ldms/src/ldmsd/ldmsd_request.c +++ b/ldms/src/ldmsd/ldmsd_request.c @@ -8049,8 +8049,13 @@ static int stream_client_stats_handler(ldmsd_req_ctxt_t reqc) int rc = 0; size_t len; struct ldmsd_req_attr_s attr; + char *reset_s = ldmsd_req_attr_str_value_get_by_id(reqc, LDMSD_ATTR_RESET); + int is_reset = 0; + + if (reset_s && (0 == strcasecmp(reset_s, "true"))) + is_reset = 1; - s = ldms_stream_client_stats_str(); + s = ldms_stream_client_stats_str(is_reset); if (!s) { reqc->errcode = errno; snprintf(buff, sizeof(buff), "ldms_stream_client_stats_str() error: %d",