summaryrefslogtreecommitdiffstats
path: root/pcp/PCPDynamicMeter.c
diff options
context:
space:
mode:
authorSohaib Mohamed <sohaib.amhmd@gmail.com>2021-07-11 03:11:29 +0200
committerNathan Scott <nathans@redhat.com>2021-08-13 07:32:57 +0200
commit6f2021f3d95e02fc54e59fdeeb006e34c209b9c3 (patch)
treea31ea1264b871e5a7e7785398a382a7813eb1749 /pcp/PCPDynamicMeter.c
parented82ce6456f0f904a0ab2b346b85d7cf46df109c (diff)
PCP: support for 'dynamic columns' added at runtime
Implements support for arbitrary Performance Co-Pilot metrics with per-process instance domains to form new htop columns. The column-to-metric mappings are setup using configuration files which will be documented via man pages as part of a follow-up commit. We provide an initial set of column configurations so as to provide new capabilities to pcp-htop: including configs for containers, open fd counts, scheduler run queue time, tcp/udp bytes/calls sent/recv, delay acct, virtual machine guests, detailed virtual memory, swap. Note there is a change to the configuration file path resolution algorithm introduced for 'dynamic meters'. First, look in any custom PCP_HTOP_DIR location. Then iterate, in priority order, users home directory, then local sysadmins files in /etc/pcp/htop, then readonly configuration files below /usr/share/pcp/htop. This final location becomes the preferred place for our own shipped meter and column files. The Settings file (htoprc) writing code is updated to not using the numeric identifier for dynamic columns. The same strategy used for dynamic meters is used here where we write Dynamic(name) so the name can be setup once more at start. Regular (static) columns writing to htoprc - i.e. numerically indexed - is unchanged.
Diffstat (limited to 'pcp/PCPDynamicMeter.c')
-rw-r--r--pcp/PCPDynamicMeter.c65
1 files changed, 34 insertions, 31 deletions
diff --git a/pcp/PCPDynamicMeter.c b/pcp/PCPDynamicMeter.c
index ffde2b4f..b90511ec 100644
--- a/pcp/PCPDynamicMeter.c
+++ b/pcp/PCPDynamicMeter.c
@@ -1,7 +1,7 @@
/*
htop - PCPDynamicMeter.c
(C) 2021 htop dev team
-(C) 2021 Red Hat, Inc. All Rights Reserved.
+(C) 2021 Red Hat, Inc.
Released under the GNU GPLv2, see the COPYING file
in the source distribution for its full text.
*/
@@ -18,13 +18,14 @@ in the source distribution for its full text.
#include "Settings.h"
#include "XUtils.h"
+
static PCPDynamicMetric* PCPDynamicMeter_lookupMetric(PCPDynamicMeters* meters, PCPDynamicMeter* meter, const char* name) {
- size_t bytes = 8 + strlen(meter->super.name) + strlen(name);
+ size_t bytes = 16 + strlen(meter->super.name) + strlen(name);
char* metricName = xMalloc(bytes);
- xSnprintf(metricName, bytes, "htop.%s.%s", meter->super.name, name);
+ xSnprintf(metricName, bytes, "htop.meter.%s.%s", meter->super.name, name);
PCPDynamicMetric* metric;
- for (unsigned int i = 0; i < meter->totalMetrics; i++) {
+ for (size_t i = 0; i < meter->totalMetrics; i++) {
metric = &meter->metrics[i];
if (String_eq(metric->name, metricName)) {
free(metricName);
@@ -33,7 +34,7 @@ static PCPDynamicMetric* PCPDynamicMeter_lookupMetric(PCPDynamicMeters* meters,
}
/* not an existing metric in this meter - add it */
- unsigned int n = meter->totalMetrics + 1;
+ size_t n = meter->totalMetrics + 1;
meter->metrics = xReallocArray(meter->metrics, n, sizeof(PCPDynamicMetric));
meter->totalMetrics = n;
metric = &meter->metrics[n - 1];
@@ -139,13 +140,8 @@ static bool PCPDynamicMeter_validateMeterName(char* key, const char* path, unsig
}
// Ensure a meter name has not been defined previously
-static bool PCPDynamicMeter_uniqueName(char* key, const char* path, unsigned int line, PCPDynamicMeters* meters) {
- if (DynamicMeter_search(meters->table, key, NULL) == false)
- return true;
-
- fprintf(stderr, "%s: duplicate name at %s line %u: \"%s\", ignored\n",
- pmGetProgname(), path, line, key);
- return false;
+static bool PCPDynamicMeter_uniqueName(char* key, PCPDynamicMeters* meters) {
+ return !DynamicMeter_search(meters->table, key, NULL);
}
static PCPDynamicMeter* PCPDynamicMeter_new(PCPDynamicMeters* meters, const char* name) {
@@ -188,7 +184,7 @@ static void PCPDynamicMeter_parseFile(PCPDynamicMeters* meters, const char* path
if (key[0] == '[') { /* new section heading - i.e. new meter */
ok = PCPDynamicMeter_validateMeterName(key + 1, path, lineno);
if (ok)
- ok = PCPDynamicMeter_uniqueName(key + 1, path, lineno, meters);
+ ok = PCPDynamicMeter_uniqueName(key + 1, meters);
if (ok)
meter = PCPDynamicMeter_new(meters, key + 1);
} else if (!ok) {
@@ -241,40 +237,47 @@ static void PCPDynamicMeter_scanDir(PCPDynamicMeters* meters, char* path) {
}
void PCPDynamicMeters_init(PCPDynamicMeters* meters) {
+ const char* share = pmGetConfig("PCP_SHARE_DIR");
const char* sysconf = pmGetConfig("PCP_SYSCONF_DIR");
const char* xdgConfigHome = getenv("XDG_CONFIG_HOME");
+ const char* override = getenv("PCP_HTOP_DIR");
const char* home = getenv("HOME");
char* path;
meters->table = Hashtable_new(0, true);
- /* search in the users home directory first of all */
- if (xdgConfigHome) {
+ /* developer paths - PCP_HTOP_DIR=./pcp ./pcp-htop */
+ if (override) {
+ path = String_cat(override, "/meters/");
+ PCPDynamicMeter_scanDir(meters, path);
+ free(path);
+ }
+
+ /* next, search in home directory alongside htoprc */
+ if (xdgConfigHome)
path = String_cat(xdgConfigHome, "/htop/meters/");
- } else {
- if (!home)
- home = "";
+ else if (home)
path = String_cat(home, "/.config/htop/meters/");
+ else
+ path = NULL;
+ if (path) {
+ PCPDynamicMeter_scanDir(meters, path);
+ free(path);
}
- PCPDynamicMeter_scanDir(meters, path);
- free(path);
- /* secondly search in the system meters directory */
+ /* next, search in the system meters directory */
path = String_cat(sysconf, "/htop/meters/");
PCPDynamicMeter_scanDir(meters, path);
free(path);
- /* check the working directory, as a final option */
- char cwd[PATH_MAX];
- if (getcwd(cwd, sizeof(cwd)) != NULL) {
- path = String_cat(cwd, "/pcp/meters/");
- PCPDynamicMeter_scanDir(meters, path);
- free(path);
- }
+ /* next, try the readonly system meters directory */
+ path = String_cat(share, "/htop/meters/");
+ PCPDynamicMeter_scanDir(meters, path);
+ free(path);
}
void PCPDynamicMeter_enable(PCPDynamicMeter* this) {
- for (unsigned int i = 0; i < this->totalMetrics; i++)
+ for (size_t i = 0; i < this->totalMetrics; i++)
Metric_enable(this->metrics[i].id, true);
}
@@ -283,7 +286,7 @@ void PCPDynamicMeter_updateValues(PCPDynamicMeter* this, Meter* meter) {
size_t size = sizeof(meter->txtBuffer);
size_t bytes = 0;
- for (unsigned int i = 0; i < this->totalMetrics; i++) {
+ for (size_t i = 0; i < this->totalMetrics; i++) {
if (i > 0 && bytes < size - 1)
buffer[bytes++] = '/'; /* separator */
@@ -357,7 +360,7 @@ void PCPDynamicMeter_updateValues(PCPDynamicMeter* this, Meter* meter) {
void PCPDynamicMeter_display(PCPDynamicMeter* this, ATTR_UNUSED const Meter* meter, RichString* out) {
int nodata = 1;
- for (unsigned int i = 0; i < this->totalMetrics; i++) {
+ for (size_t i = 0; i < this->totalMetrics; i++) {
PCPDynamicMetric* metric = &this->metrics[i];
const pmDesc* desc = Metric_desc(metric->id);
pmAtomValue atom, raw;

© 2014-2024 Faster IT GmbH | imprint | privacy policy