if BUILD_PLUGIN_TURBOSTAT
pkglib_LTLIBRARIES += turbostat.la
-turbostat_la_SOURCES = src/turbostat.c
+turbostat_la_SOURCES = \
+ src/turbostat.c \
+ src/msr-index.h
turbostat_la_LDFLAGS = $(PLUGIN_LDFLAGS)
endif
]]
)
# For the turbostat plugin
- AC_CHECK_HEADERS([asm/msr-index.h],
- [have_asm_msrindex_h="yes"],
- [have_asm_msrindex_h="no"]
- )
-
- if test "x$have_asm_msrindex_h" = "xyes"; then
- AC_CACHE_CHECK([whether asm/msr-index.h has MSR_PKG_C10_RESIDENCY],
- [c_cv_have_usable_asm_msrindex_h],
- [
- AC_COMPILE_IFELSE(
- [
- AC_LANG_PROGRAM(
- [[#include<asm/msr-index.h>]],
- [[
- int y = MSR_PKG_C10_RESIDENCY;
- return(y);
- ]]
- )
- ],
- [c_cv_have_usable_asm_msrindex_h="yes"],
- [c_cv_have_usable_asm_msrindex_h="no"],
- )
- ]
- )
- fi
-
AC_CHECK_HEADERS([cpuid.h],
[have_cpuid_h="yes"],
[have_cpuid_h="no (cpuid.h not found)"]
plugin_ipvs="yes"
fi
- if test "x$c_cv_have_usable_asm_msrindex_h" = "xyes" && test "x$have_cpuid_h" = "xyes"; then
+ if test "x$have_cpuid_h" = "xyes"; then
plugin_turbostat="yes"
fi
#<Plugin filecount>
# <Directory "/path/to/dir">
+# #Plugin "foo"
# Instance "foodir"
# Name "*.conf"
# MTime "-5m"
# Size "+10k"
# Recursive true
# IncludeHidden false
+# #FilesSizeType "bytes"
+# #FilesCountType "files"
+# #TypeInstance "instance"
# </Directory>
#</Plugin>
=over 4
+=item B<Plugin> I<Plugin>
+
+Use I<Plugin> as the plugin name when submitting values.
+Defaults to B<filecount>.
+
=item B<Instance> I<Instance>
-Sets the plugin instance to I<Instance>. That instance name must be unique, but
-it's your responsibility, the plugin doesn't check for that. If not given, the
-instance is set to the directory name with all slashes replaced by underscores
-and all leading underscores removed.
+Sets the plugin instance to I<Instance>. If not given, the instance is set to
+the directory name with all slashes replaced by underscores and all leading
+underscores removed. Empty value is allowed.
=item B<Name> I<Pattern>
"Hidden" files and directories are those, whose name begins with a dot.
Defaults to I<false>, i.e. by default hidden files and directories are ignored.
+=item B<FilesSizeType> I<Type>
+
+Sets the type used to dispatch files combined size. Empty value ("") disables
+reporting. Defaults to B<bytes>.
+
+=item B<FilesCountType> I<Type>
+
+Sets the type used to dispatch number of files. Empty value ("") disables
+reporting. Defaults to B<files>.
+
+=item B<TypeInstance> I<Instance>
+
+Sets the I<type instance> used to dispatch values. Defaults to an empty string
+(no plugin instance).
+
=back
=head2 Plugin C<GenericJMX>
Boolean enabling the use of logical core numbering for per core statistics.
When enabled, C<cpuE<lt>nE<gt>> is used as plugin instance, where I<n> is a
-sequential number assigned by the kernel. Otherwise, C<coreE<lt>nE<gt>> is used
-where I<n> is the n-th core of the socket, causing name conflicts when there is
-more than one socket.
+dynamic number assigned by the kernel. Otherwise, C<coreE<lt>nE<gt>> is used
+if there is only one package and C<pkgE<lt>nE<gt>-coreE<lt>mE<gt>> if there is
+more than one, where I<n> is the n-th core of package I<m>.
=back
if (recv(fd, buffer, sizeof(buffer), MSG_PEEK | MSG_DONTWAIT) == 0) {
/* if recv returns zero (even though poll() said there is data to be
* read), that means the connection has been closed */
- return errno ? errno : -1;
+ errno = ECONNRESET;
+ return -1;
}
}
struct fc_directory_conf_s {
char *path;
+ char *plugin_name;
char *instance;
+ char *files_size_type;
+ char *files_num_type;
+ char *type_instance;
int options;
static fc_directory_conf_t **directories = NULL;
static size_t directories_num = 0;
+void fc_free_dir(fc_directory_conf_t *dir) {
+ sfree(dir->path);
+ sfree(dir->plugin_name);
+ sfree(dir->instance);
+ sfree(dir->files_size_type);
+ sfree(dir->files_num_type);
+ sfree(dir->type_instance);
+ sfree(dir->name);
+
+ sfree(dir);
+} /* void fc_free_dir */
+
static void fc_submit_dir(const fc_directory_conf_t *dir) {
value_list_t vl = VALUE_LIST_INIT;
- vl.values = &(value_t){.gauge = (gauge_t)dir->files_num};
- vl.values_len = 1;
- sstrncpy(vl.plugin, "filecount", sizeof(vl.plugin));
- sstrncpy(vl.plugin_instance, dir->instance, sizeof(vl.plugin_instance));
- sstrncpy(vl.type, "files", sizeof(vl.type));
+ sstrncpy(vl.plugin, dir->plugin_name, sizeof(vl.plugin));
+ if (dir->instance != NULL)
+ sstrncpy(vl.plugin_instance, dir->instance, sizeof(vl.plugin_instance));
+ if (dir->type_instance != NULL)
+ sstrncpy(vl.type_instance, dir->type_instance, sizeof(vl.type_instance));
- plugin_dispatch_values(&vl);
+ vl.values_len = 1;
- vl.values = &(value_t){.gauge = (gauge_t)dir->files_size};
- sstrncpy(vl.type, "bytes", sizeof(vl.type));
+ if (dir->files_num_type != NULL) {
+ vl.values = &(value_t){.gauge = (gauge_t)dir->files_num};
+ sstrncpy(vl.type, dir->files_num_type, sizeof(vl.type));
+ plugin_dispatch_values(&vl);
+ }
- plugin_dispatch_values(&vl);
+ if (dir->files_size_type != NULL) {
+ vl.values = &(value_t){.gauge = (gauge_t)dir->files_size};
+ sstrncpy(vl.type, dir->files_size_type, sizeof(vl.type));
+ plugin_dispatch_values(&vl);
+ }
} /* void fc_submit_dir */
/*
* Config:
* <Plugin filecount>
* <Directory /path/to/dir>
+ * Plugin "foo"
* Instance "foobar"
* Name "*.conf"
* MTime -3600
* Size "+10M"
+ * Recursive true
+ * IncludeHidden false
+ * FilesSizeType "bytes"
+ * FilesCountType "files"
+ * TypeInstance "instance"
* </Directory>
* </Plugin>
*
static int fc_config_set_instance(fc_directory_conf_t *dir, const char *str) {
char buffer[1024];
char *ptr;
- char *copy;
sstrncpy(buffer, str, sizeof(buffer));
for (ptr = buffer; *ptr != 0; ptr++)
for (ptr = buffer; *ptr == '_'; ptr++)
/* do nothing */;
- if (*ptr == 0)
- return -1;
-
- copy = strdup(ptr);
+ char *copy = strdup(ptr);
if (copy == NULL)
return -1;
static int fc_config_add_dir_name(fc_directory_conf_t *dir,
oconfig_item_t *ci) {
- char *temp;
-
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("filecount plugin: The `Name' config option needs exactly one "
"string argument.");
return -1;
}
- temp = strdup(ci->values[0].value.string);
+ char *temp = strdup(ci->values[0].value.string);
if (temp == NULL) {
ERROR("filecount plugin: strdup failed.");
return -1;
static int fc_config_add_dir_mtime(fc_directory_conf_t *dir,
oconfig_item_t *ci) {
- char *endptr;
- double temp;
-
if ((ci->values_num != 1) || ((ci->values[0].type != OCONFIG_TYPE_STRING) &&
(ci->values[0].type != OCONFIG_TYPE_NUMBER))) {
WARNING("filecount plugin: The `MTime' config option needs exactly one "
}
errno = 0;
- endptr = NULL;
- temp = strtod(ci->values[0].value.string, &endptr);
+ char *endptr = NULL;
+ double temp = strtod(ci->values[0].value.string, &endptr);
if ((errno != 0) || (endptr == NULL) ||
(endptr == ci->values[0].value.string)) {
WARNING("filecount plugin: Converting `%s' to a number failed.",
static int fc_config_add_dir_size(fc_directory_conf_t *dir,
oconfig_item_t *ci) {
- char *endptr;
- double temp;
-
if ((ci->values_num != 1) || ((ci->values[0].type != OCONFIG_TYPE_STRING) &&
(ci->values[0].type != OCONFIG_TYPE_NUMBER))) {
WARNING("filecount plugin: The `Size' config option needs exactly one "
}
errno = 0;
- endptr = NULL;
- temp = strtod(ci->values[0].value.string, &endptr);
+ char *endptr = NULL;
+ double temp = strtod(ci->values[0].value.string, &endptr);
if ((errno != 0) || (endptr == NULL) ||
(endptr == ci->values[0].value.string)) {
WARNING("filecount plugin: Converting `%s' to a number failed.",
} /* int fc_config_add_dir_option */
static int fc_config_add_dir(oconfig_item_t *ci) {
- fc_directory_conf_t *dir;
- int status;
-
if ((ci->values_num != 1) || (ci->values[0].type != OCONFIG_TYPE_STRING)) {
WARNING("filecount plugin: `Directory' needs exactly one string "
"argument.");
}
/* Initialize `dir' */
- dir = calloc(1, sizeof(*dir));
+ fc_directory_conf_t *dir = calloc(1, sizeof(*dir));
if (dir == NULL) {
ERROR("filecount plugin: calloc failed.");
return -1;
dir->path = strdup(ci->values[0].value.string);
if (dir->path == NULL) {
ERROR("filecount plugin: strdup failed.");
- sfree(dir);
+ fc_free_dir(dir);
return -1;
}
- fc_config_set_instance(dir, dir->path);
-
dir->options = FC_RECURSIVE;
dir->name = NULL;
+ dir->plugin_name = strdup("filecount");
+ dir->instance = NULL;
+ dir->type_instance = NULL;
dir->mtime = 0;
dir->size = 0;
- status = 0;
+ dir->files_size_type = strdup("bytes");
+ dir->files_num_type = strdup("files");
+
+ if (dir->plugin_name == NULL || dir->files_size_type == NULL ||
+ dir->files_num_type == NULL) {
+ ERROR("filecount plugin: strdup failed.");
+ fc_free_dir(dir);
+ return -1;
+ }
+
+ int status = 0;
for (int i = 0; i < ci->children_num; i++) {
oconfig_item_t *option = ci->children + i;
- if (strcasecmp("Instance", option->key) == 0)
+ if (strcasecmp("Plugin", option->key) == 0)
+ status = cf_util_get_string(option, &dir->plugin_name);
+ else if (strcasecmp("Instance", option->key) == 0)
status = fc_config_add_dir_instance(dir, option);
else if (strcasecmp("Name", option->key) == 0)
status = fc_config_add_dir_name(dir, option);
status = fc_config_add_dir_option(dir, option, FC_RECURSIVE);
else if (strcasecmp("IncludeHidden", option->key) == 0)
status = fc_config_add_dir_option(dir, option, FC_HIDDEN);
+ else if (strcasecmp("FilesSizeType", option->key) == 0)
+ status = cf_util_get_string(option, &dir->files_size_type);
+ else if (strcasecmp("FilesCountType", option->key) == 0)
+ status = cf_util_get_string(option, &dir->files_num_type);
+ else if (strcasecmp("TypeInstance", option->key) == 0)
+ status = cf_util_get_string(option, &dir->type_instance);
else {
WARNING("filecount plugin: fc_config_add_dir: "
"Option `%s' not allowed here.",
break;
} /* for (ci->children) */
- if (status == 0) {
- fc_directory_conf_t **temp;
+ if (status != 0) {
+ fc_free_dir(dir);
+ return -1;
+ }
- temp = realloc(directories, sizeof(*directories) * (directories_num + 1));
- if (temp == NULL) {
- ERROR("filecount plugin: realloc failed.");
- status = -1;
- } else {
- directories = temp;
- directories[directories_num] = dir;
- directories_num++;
+ /* Set default plugin instance */
+ if (dir->instance == NULL) {
+ fc_config_set_instance(dir, dir->path);
+ if (dir->instance == NULL || strlen(dir->instance) == 0) {
+ ERROR("filecount plugin: failed to build plugin instance name.");
+ fc_free_dir(dir);
+ return -1;
}
}
- if (status != 0) {
- sfree(dir->name);
+ /* Handle disabled types */
+ if (strlen(dir->instance) == 0)
sfree(dir->instance);
- sfree(dir->path);
- sfree(dir);
+
+ if (strlen(dir->files_size_type) == 0)
+ sfree(dir->files_size_type);
+
+ if (strlen(dir->files_num_type) == 0)
+ sfree(dir->files_num_type);
+
+ if (dir->files_size_type == NULL && dir->files_num_type == NULL) {
+ WARNING("filecount plugin: Both `FilesSizeType' and `FilesCountType ' "
+ "are disabled for '%s'. There's no types to report.",
+ dir->path);
+ fc_free_dir(dir);
+ return -1;
+ }
+
+ /* Ready to add it to list */
+ fc_directory_conf_t **temp =
+ realloc(directories, sizeof(*directories) * (directories_num + 1));
+ if (temp == NULL) {
+ ERROR("filecount plugin: realloc failed.");
+ fc_free_dir(dir);
return -1;
}
+ directories = temp;
+ directories[directories_num] = dir;
+ directories_num++;
+
return 0;
} /* int fc_config_add_dir */
fc_directory_conf_t *dir = user_data;
char abs_path[PATH_MAX];
struct stat statbuf;
- int status;
if (dir == NULL)
return -1;
snprintf(abs_path, sizeof(abs_path), "%s/%s", dirname, filename);
- status = lstat(abs_path, &statbuf);
+ int status = lstat(abs_path, &statbuf);
if (status != 0) {
ERROR("filecount plugin: stat (%s) failed.", abs_path);
return -1;
} /* int fc_read_dir_callback */
static int fc_read_dir(fc_directory_conf_t *dir) {
- int status;
-
dir->files_num = 0;
dir->files_size = 0;
if (dir->mtime != 0)
dir->now = time(NULL);
- status =
+ int status =
walk_directory(dir->path, fc_read_dir_callback, dir,
/* include hidden */ (dir->options & FC_HIDDEN) ? 1 : 0);
if (status != 0) {
* Copyright (C) 2009 Doug MacEachern
* Copyright (C) 2009 Franck Lombardi
* Copyright (C) 2012 Nicolas Szalay
+ * Copyright (C) 2017 Pavel Rochnyak
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Doug MacEachern <dougm at hyperic.com>
* Franck Lombardi
* Nicolas Szalay
+ * Pavel Rochnyak <pavel2000 ngs.ru>
**/
#include "collectd.h"
#include <netinet/tcp.h>
#include <sys/un.h>
+#include <poll.h>
+
#define MEMCACHED_DEF_HOST "127.0.0.1"
#define MEMCACHED_DEF_PORT "11211"
+#define MEMCACHED_CONNECT_TIMEOUT 10000
+#define MEMCACHED_IO_TIMEOUT 5000
struct memcached_s {
char *name;
char *socket;
char *connhost;
char *connport;
+ int fd;
};
typedef struct memcached_s memcached_t;
if (st == NULL)
return;
+ if (st->fd >= 0) {
+ shutdown(st->fd, SHUT_RDWR);
+ close(st->fd);
+ st->fd = -1;
+ }
+
sfree(st->name);
sfree(st->host);
sfree(st->socket);
if (status != 0) {
shutdown(fd, SHUT_RDWR);
close(fd);
- fd = -1;
+ return -1;
+ }
+
+ /* switch to non-blocking mode */
+ int flags = fcntl(fd, F_GETFL);
+ status = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+ if (status != 0) {
+ close(fd);
+ return -1;
}
return fd;
continue;
}
+ /* switch socket to non-blocking mode */
+ int flags = fcntl(fd, F_GETFL);
+ status = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
+ if (status != 0) {
+ close(fd);
+ fd = -1;
+ continue;
+ }
+
/* connect to the memcached daemon */
status = (int)connect(fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
- if (status != 0) {
+ if (status != 0 && errno != EINPROGRESS) {
shutdown(fd, SHUT_RDWR);
close(fd);
fd = -1;
continue;
}
- /* A socket could be opened and connecting succeeded. We're done. */
+ /* Wait until connection establishes */
+ struct pollfd pollfd = {
+ .fd = fd, .events = POLLOUT,
+ };
+ do
+ status = poll(&pollfd, 1, MEMCACHED_CONNECT_TIMEOUT);
+ while (status < 0 && errno == EINTR);
+ if (status <= 0) {
+ close(fd);
+ fd = -1;
+ continue;
+ }
+
+ /* Check if all is good */
+ int socket_error;
+ status = getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&socket_error,
+ &(socklen_t){sizeof(socket_error)});
+ if (status != 0 || socket_error != 0) {
+ close(fd);
+ fd = -1;
+ continue;
+ }
+ /* A socket is opened and connection succeeded. We're done. */
break;
}
return fd;
} /* int memcached_connect_inet */
-static int memcached_connect(memcached_t *st) {
+static void memcached_connect(memcached_t *st) {
+ if (st->fd >= 0)
+ return;
+
if (st->socket != NULL)
- return memcached_connect_unix(st);
+ st->fd = memcached_connect_unix(st);
else
- return memcached_connect_inet(st);
+ st->fd = memcached_connect_inet(st);
+
+ if (st->fd >= 0)
+ INFO("memcached plugin: Instance \"%s\": connection established.",
+ st->name);
}
static int memcached_query_daemon(char *buffer, size_t buffer_size,
memcached_t *st) {
- int fd, status;
+ int status;
size_t buffer_fill;
- fd = memcached_connect(st);
- if (fd < 0) {
+ memcached_connect(st);
+ if (st->fd < 0) {
ERROR("memcached plugin: Instance \"%s\" could not connect to daemon.",
st->name);
return -1;
}
- status = (int)swrite(fd, "stats\r\n", strlen("stats\r\n"));
+ struct pollfd pollfd = {
+ .fd = st->fd, .events = POLLOUT,
+ };
+
+ do
+ status = poll(&pollfd, 1, MEMCACHED_IO_TIMEOUT);
+ while (status < 0 && errno == EINTR);
+
+ if (status <= 0) {
+ ERROR("memcached plugin: poll() failed for write() call.");
+ close(st->fd);
+ st->fd = -1;
+ return -1;
+ }
+
+ status = (int)swrite(st->fd, "stats\r\n", strlen("stats\r\n"));
if (status != 0) {
char errbuf[1024];
- ERROR("memcached plugin: write(2) failed: %s",
+ ERROR("memcached plugin: Instance \"%s\": write(2) failed: %s", st->name,
sstrerror(errno, errbuf, sizeof(errbuf)));
- shutdown(fd, SHUT_RDWR);
- close(fd);
+ shutdown(st->fd, SHUT_RDWR);
+ close(st->fd);
+ st->fd = -1;
return -1;
}
memset(buffer, 0, buffer_size);
buffer_fill = 0;
- while ((status = (int)recv(fd, buffer + buffer_fill,
- buffer_size - buffer_fill, /* flags = */ 0)) !=
- 0) {
+ pollfd.events = POLLIN;
+ while (1) {
+ do
+ status = poll(&pollfd, 1, MEMCACHED_IO_TIMEOUT);
+ while (status < 0 && errno == EINTR);
+
+ if (status <= 0) {
+ ERROR("memcached plugin: Instance \"%s\": Timeout reading from socket",
+ st->name);
+ close(st->fd);
+ st->fd = -1;
+ return -1;
+ }
+
+ do
+ status = (int)recv(st->fd, buffer + buffer_fill,
+ buffer_size - buffer_fill, /* flags = */ 0);
+ while (status < 0 && errno == EINTR);
+
char const end_token[5] = {'E', 'N', 'D', '\r', '\n'};
if (status < 0) {
char errbuf[1024];
- if ((errno == EAGAIN) || (errno == EINTR))
+ if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
continue;
- ERROR("memcached: Error reading from socket: %s",
- sstrerror(errno, errbuf, sizeof(errbuf)));
- shutdown(fd, SHUT_RDWR);
- close(fd);
+ ERROR("memcached plugin: Instance \"%s\": Error reading from socket: %s",
+ st->name, sstrerror(errno, errbuf, sizeof(errbuf)));
+ shutdown(st->fd, SHUT_RDWR);
+ close(st->fd);
+ st->fd = -1;
return -1;
}
buffer_fill += (size_t)status;
if (buffer_fill > buffer_size) {
buffer_fill = buffer_size;
- WARNING("memcached plugin: Message was truncated.");
+ WARNING("memcached plugin: Instance \"%s\": Message was truncated.",
+ st->name);
+ shutdown(st->fd, SHUT_RDWR);
+ close(st->fd);
+ st->fd = -1;
break;
}
status = 0;
if (buffer_fill == 0) {
- WARNING("memcached plugin: No data returned by memcached.");
+ WARNING("memcached plugin: Instance \"%s\": No data returned by memcached.",
+ st->name);
status = -1;
}
- shutdown(fd, SHUT_RDWR);
- close(fd);
return status;
} /* int memcached_query_daemon */
} else if (FIELD_IS("listen_disabled_num")) {
submit_derive("connections", "listen_disabled", atof(fields[2]), st);
}
+ /*
+ * Total number of connections opened since the server started running
+ * Report this as connection rate.
+ */
+ else if (FIELD_IS("total_connections")) {
+ submit_derive("connections", "opened", atof(fields[2]), st);
+ }
/*
* Commands
st->connhost = NULL;
st->connport = NULL;
+ st->fd = -1;
+
if (strcasecmp(ci->key, "Instance") == 0)
status = cf_util_get_string(ci, &st->name);
st->connhost = NULL;
st->connport = NULL;
+ st->fd = -1;
+
status = memcached_add_read_callback(st);
if (status == 0)
memcached_have_instances = 1;
--- /dev/null
+/*
+ * Partial header file imported from the linux kernel
+ * (arch/x86/include/asm/msr-index.h)
+ * as it is not provided by the kernel sources anymore
+ *
+ * Only the minimal blocks of macro have been included
+ * ----
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * ----
+ */
+
+#ifndef _ASM_X86_MSR_INDEX_H
+#define _ASM_X86_MSR_INDEX_H
+
+/*
+ * CPU model specific register (MSR) numbers.
+ *
+ * Do not add new entries to this file unless the definitions are shared
+ * between multiple compilation units.
+ */
+
+/* Intel MSRs. Some also available on other CPUs */
+
+/* C-state Residency Counters */
+#define MSR_PKG_C3_RESIDENCY 0x000003f8
+#define MSR_PKG_C6_RESIDENCY 0x000003f9
+#define MSR_ATOM_PKG_C6_RESIDENCY 0x000003fa
+#define MSR_PKG_C7_RESIDENCY 0x000003fa
+#define MSR_CORE_C3_RESIDENCY 0x000003fc
+#define MSR_CORE_C6_RESIDENCY 0x000003fd
+#define MSR_CORE_C7_RESIDENCY 0x000003fe
+#define MSR_KNL_CORE_C6_RESIDENCY 0x000003ff
+#define MSR_PKG_C2_RESIDENCY 0x0000060d
+#define MSR_PKG_C8_RESIDENCY 0x00000630
+#define MSR_PKG_C9_RESIDENCY 0x00000631
+#define MSR_PKG_C10_RESIDENCY 0x00000632
+
+/* Run Time Average Power Limiting (RAPL) Interface */
+
+#define MSR_RAPL_POWER_UNIT 0x00000606
+
+#define MSR_PKG_POWER_LIMIT 0x00000610
+#define MSR_PKG_ENERGY_STATUS 0x00000611
+#define MSR_PKG_PERF_STATUS 0x00000613
+#define MSR_PKG_POWER_INFO 0x00000614
+
+#define MSR_DRAM_POWER_LIMIT 0x00000618
+#define MSR_DRAM_ENERGY_STATUS 0x00000619
+#define MSR_DRAM_PERF_STATUS 0x0000061b
+#define MSR_DRAM_POWER_INFO 0x0000061c
+
+#define MSR_PP0_POWER_LIMIT 0x00000638
+#define MSR_PP0_ENERGY_STATUS 0x00000639
+#define MSR_PP0_POLICY 0x0000063a
+#define MSR_PP0_PERF_STATUS 0x0000063b
+
+#define MSR_PP1_POWER_LIMIT 0x00000640
+#define MSR_PP1_ENERGY_STATUS 0x00000641
+#define MSR_PP1_POLICY 0x00000642
+
+
+
+/* Intel defined MSRs. */
+#define MSR_IA32_TSC 0x00000010
+#define MSR_SMI_COUNT 0x00000034
+
+#define MSR_IA32_MPERF 0x000000e7
+#define MSR_IA32_APERF 0x000000e8
+
+#define MSR_IA32_THERM_STATUS 0x0000019c
+
+#define MSR_IA32_TEMPERATURE_TARGET 0x000001a2
+
+#define MSR_IA32_PACKAGE_THERM_STATUS 0x000001b1
+
+
+#endif /* _ASM_X86_MSR_INDEX_H */
#include "plugin.h"
#include "utils_time.h"
-#include <asm/msr-index.h>
+#include "msr-index.h"
#include <cpuid.h>
#ifdef HAVE_SYS_CAPABILITY_H
#include <sys/capability.h>
/* If not using logical core numbering, set core id */
if (!config_lcn) {
- snprintf(name, sizeof(name), "core%02d", c->core_id);
+ if (topology.num_packages > 1)
+ snprintf(name, sizeof(name), "pkg%02d-core%02d", p->package_id, c->core_id);
+ else
+ snprintf(name, sizeof(name), "core%02d", c->core_id);
}
if (do_core_cstate & (1 << 3))
char *prefix;
int database;
int max_set_size;
+ int max_set_duration;
_Bool store_rates;
redisContext *conn;
freeReplyObject(rr);
}
+ if (node->max_set_duration > 0) {
+ /*
+ * remove element, scored less than 'current-max_set_duration'
+ * '(%d' indicates 'less than' in redis CLI.
+ */
+ rr = redisCommand(node->conn, "ZREMRANGEBYSCORE %s -1 (%d", key,
+ (time - node->max_set_duration) + 1);
+ if (rr == NULL)
+ WARNING("ZREMRANGEBYSCORE command error. key:%s message:%s", key,
+ node->conn->errstr);
+ else
+ freeReplyObject(rr);
+ }
+
/* TODO(octo): This is more overhead than necessary. Use the cache and
* metadata to determine if it is a new metric and call SADD only once for
* each metric. */
node->prefix = NULL;
node->database = 0;
node->max_set_size = -1;
+ node->max_set_duration = -1;
node->store_rates = 1;
pthread_mutex_init(&node->lock, /* attr = */ NULL);
status = cf_util_get_int(child, &node->database);
} else if (strcasecmp("MaxSetSize", child->key) == 0) {
status = cf_util_get_int(child, &node->max_set_size);
+ } else if (strcasecmp("MaxSetDuration", child->key) == 0) {
+ status = cf_util_get_int(child, &node->max_set_duration);
} else if (strcasecmp("StoreRates", child->key) == 0) {
status = cf_util_get_boolean(child, &node->store_rates);
} else