mirror of
https://github.com/Telecominfraproject/OpenNetworkLinux.git
synced 2025-12-25 17:27:01 +00:00
Merge pull request #146 from kenchiang/onlp-snmp
Add CpuAllPercentUtilization and CpuAllPercentIdle.
This commit is contained in:
@@ -34,7 +34,7 @@ CpuAllPercentUtilization OBJECT-TYPE
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"The average CPU utilization (in percent). Provided by mpstat."
|
||||
"The average CPU utilization in percent, multiplied by 100 and rounded to the nearest integer. Provided by mpstat."
|
||||
::= { Basic 1 }
|
||||
|
||||
CpuAllPercentIdle OBJECT-TYPE
|
||||
@@ -42,7 +42,7 @@ CpuAllPercentIdle OBJECT-TYPE
|
||||
MAX-ACCESS read-only
|
||||
STATUS current
|
||||
DESCRIPTION
|
||||
"The average CPU idle time (in percent). Provided by mpstat."
|
||||
"The average CPU idle time in percent, multiplied by 100 and rounded to the nearest integer. Provided by mpstat."
|
||||
::= { Basic 2 }
|
||||
|
||||
END
|
||||
|
||||
@@ -16,6 +16,7 @@ packages:
|
||||
files:
|
||||
builds/$BUILD_DIR/${TOOLCHAIN}/bin/onlp-snmpd: /usr/bin/onlp-snmpd
|
||||
${ONL}/packages/base/any/onlp-snmpd/bin/onl-snmpwalk : /usr/bin/onl-snmpwalk
|
||||
${ONL}/packages/base/any/onlp-snmpd/bin/onl-snmp-mpstat : /usr/bin/onl-snmp-mpstat
|
||||
|
||||
init: ${ONL}/packages/base/any/onlp-snmpd/onlp-snmpd.init
|
||||
|
||||
|
||||
33
packages/base/any/onlp-snmpd/bin/onl-snmp-mpstat
Executable file
33
packages/base/any/onlp-snmpd/bin/onl-snmp-mpstat
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# call mpstat and generate json output containing stats for all cpus
|
||||
|
||||
"""
|
||||
sample output from "mpstat 1 1":
|
||||
# mpstat 1 1
|
||||
Linux 3.8.13-OpenNetworkLinux-e500mc-1.5 (as6700-3) 2016-12-15 _ppc_(4 CPU)
|
||||
|
||||
04:59:31 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
|
||||
04:59:32 PM all 5.17 0.00 2.07 0.00 0.00 0.00 0.00 0.00 92.76
|
||||
Average: all 5.17 0.00 2.07 0.00 0.00 0.00 0.00 0.00 92.76
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import json
|
||||
|
||||
stats = {}
|
||||
|
||||
# 1 second interval, 1 count
|
||||
out = subprocess.check_output(['mpstat','1','1'])
|
||||
|
||||
for line in out.split('\n'):
|
||||
if "%idle" in line:
|
||||
# extract keys from header line, skipping over time and AM/PM
|
||||
keys = line.split()[2:]
|
||||
|
||||
if "Average" in line:
|
||||
vals = line.split()[1:]
|
||||
stats[vals[0]] = { k:int(round(100*float(v))) \
|
||||
for (k,v) in zip(keys[1:],vals[1:]) }
|
||||
|
||||
print json.dumps(stats)
|
||||
@@ -3,7 +3,7 @@ include $(ONL)/make/any.mk
|
||||
MODULE := onlp-snmpd
|
||||
include $(BUILDER)/standardinit.mk
|
||||
|
||||
DEPENDMODULES := onlp_snmp AIM OS snmp_subagent IOF onlplib
|
||||
DEPENDMODULES := onlp_snmp AIM OS snmp_subagent IOF onlplib cjson cjson_util
|
||||
DEPENDMODULE_HEADERS := onlp
|
||||
|
||||
include $(BUILDER)/dependmodules.mk
|
||||
|
||||
@@ -56,6 +56,9 @@ cdefs: &cdefs
|
||||
- ONLP_SNMP_CONFIG_AS_SUBAGENT:
|
||||
doc: "Configure as an snmp_subagent client."
|
||||
default: 0
|
||||
- ONLP_SNMP_CONFIG_RESOURCE_UPDATE_SECONDS:
|
||||
doc: "Resource object update period in seconds."
|
||||
default: 5
|
||||
|
||||
definitions:
|
||||
cdefs:
|
||||
|
||||
@@ -191,6 +191,16 @@
|
||||
#define ONLP_SNMP_CONFIG_AS_SUBAGENT 0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* ONLP_SNMP_CONFIG_RESOURCE_UPDATE_SECONDS
|
||||
*
|
||||
* Resource object update period in seconds. */
|
||||
|
||||
|
||||
#ifndef ONLP_SNMP_CONFIG_RESOURCE_UPDATE_SECONDS
|
||||
#define ONLP_SNMP_CONFIG_RESOURCE_UPDATE_SECONDS 5
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -94,6 +94,11 @@ onlp_snmp_config_settings_t onlp_snmp_config_settings[] =
|
||||
{ __onlp_snmp_config_STRINGIFY_NAME(ONLP_SNMP_CONFIG_AS_SUBAGENT), __onlp_snmp_config_STRINGIFY_VALUE(ONLP_SNMP_CONFIG_AS_SUBAGENT) },
|
||||
#else
|
||||
{ ONLP_SNMP_CONFIG_AS_SUBAGENT(__onlp_snmp_config_STRINGIFY_NAME), "__undefined__" },
|
||||
#endif
|
||||
#ifdef ONLP_SNMP_CONFIG_RESOURCE_UPDATE_SECONDS
|
||||
{ __onlp_snmp_config_STRINGIFY_NAME(ONLP_SNMP_CONFIG_RESOURCE_UPDATE_SECONDS), __onlp_snmp_config_STRINGIFY_VALUE(ONLP_SNMP_CONFIG_RESOURCE_UPDATE_SECONDS) },
|
||||
#else
|
||||
{ ONLP_SNMP_CONFIG_RESOURCE_UPDATE_SECONDS(__onlp_snmp_config_STRINGIFY_NAME), "__undefined__" },
|
||||
#endif
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
#include <onlp_snmp/onlp_snmp_config.h>
|
||||
#include "onlp_snmp_log.h"
|
||||
|
||||
#include <AIM/aim_time.h>
|
||||
#include <cjson/cJSON.h>
|
||||
#include <cjson_util/cjson_util.h>
|
||||
#include <net-snmp/net-snmp-config.h>
|
||||
#include <net-snmp/net-snmp-includes.h>
|
||||
#include <net-snmp/agent/net-snmp-agent-includes.h>
|
||||
@@ -54,7 +57,7 @@ platform_string_register(int index, const char* desc, char* value)
|
||||
netsnmp_register_watched_scalar( reg, winfo );
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
platform_int_register(int index, char* desc, int value)
|
||||
{
|
||||
oid tree[] = { 1, 3, 6, 1, 4, 1, 42623, 1, 1, 1, 1, 1};
|
||||
@@ -69,6 +72,106 @@ platform_int_register(int index, char* desc, int value)
|
||||
v, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
resource_int_register(int index, const char* desc,
|
||||
Netsnmp_Node_Handler *handler)
|
||||
{
|
||||
oid tree[] = { 1, 3, 6, 1, 4, 1, 42623, 1, 3, 1, 1 };
|
||||
tree[10] = index;
|
||||
|
||||
netsnmp_handler_registration *reg =
|
||||
netsnmp_create_handler_registration(desc, handler,
|
||||
tree, OID_LENGTH(tree),
|
||||
HANDLER_CAN_RONLY);
|
||||
if (netsnmp_register_scalar(reg) != MIB_REGISTERED_OK) {
|
||||
AIM_LOG_ERROR("registering handler for %s failed", desc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* resource objects */
|
||||
typedef struct {
|
||||
uint32_t utilization_percent;
|
||||
uint32_t idle_percent;
|
||||
} resources_t;
|
||||
|
||||
static resources_t resources;
|
||||
static uint64_t resource_update_time;
|
||||
|
||||
void resource_update(void)
|
||||
{
|
||||
uint64_t now = aim_time_monotonic();
|
||||
if (now - resource_update_time >
|
||||
(ONLP_SNMP_CONFIG_RESOURCE_UPDATE_SECONDS * 1000 * 1000)) {
|
||||
resource_update_time = now;
|
||||
AIM_LOG_INFO("update resource objects");
|
||||
|
||||
/* invoke mpstat collection script for json output */
|
||||
FILE *fp = popen("/usr/bin/onl-snmp-mpstat", "r");
|
||||
if (fp == NULL) {
|
||||
AIM_LOG_ERROR("failed invoking onl-snmp-mpstat");
|
||||
return;
|
||||
}
|
||||
|
||||
/* parse json output */
|
||||
char line[1024];
|
||||
while (fgets(line, sizeof(line), fp) != NULL) {
|
||||
cJSON *root = cJSON_Parse(line);
|
||||
int result;
|
||||
int rv = cjson_util_lookup_int(root, &result, "all.%%idle");
|
||||
if (rv == 0) {
|
||||
/* save it */
|
||||
resources.idle_percent = result;
|
||||
resources.utilization_percent = 100*100 - result;
|
||||
}
|
||||
cJSON_Delete(root);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
utilization_handler(netsnmp_mib_handler *handler,
|
||||
netsnmp_handler_registration *reginfo,
|
||||
netsnmp_agent_request_info *reqinfo,
|
||||
netsnmp_request_info *requests)
|
||||
{
|
||||
if (MODE_GET == reqinfo->mode) {
|
||||
resource_update();
|
||||
snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE,
|
||||
(u_char *) &resources.utilization_percent,
|
||||
sizeof(resources.utilization_percent));
|
||||
} else {
|
||||
netsnmp_assert("bad mode in RO handler");
|
||||
}
|
||||
|
||||
if (handler->next && handler->next->access_method) {
|
||||
return netsnmp_call_next_handler(handler, reginfo, reqinfo, requests);
|
||||
}
|
||||
|
||||
return SNMP_ERR_NOERROR;
|
||||
}
|
||||
|
||||
static int
|
||||
idle_handler(netsnmp_mib_handler *handler,
|
||||
netsnmp_handler_registration *reginfo,
|
||||
netsnmp_agent_request_info *reqinfo,
|
||||
netsnmp_request_info *requests)
|
||||
{
|
||||
if (MODE_GET == reqinfo->mode) {
|
||||
resource_update();
|
||||
snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE,
|
||||
(u_char *) &resources.idle_percent,
|
||||
sizeof(resources.idle_percent));
|
||||
} else {
|
||||
netsnmp_assert("bad mode in RO handler");
|
||||
}
|
||||
|
||||
if (handler->next && handler->next->access_method) {
|
||||
return netsnmp_call_next_handler(handler, reginfo, reqinfo, requests);
|
||||
}
|
||||
|
||||
return SNMP_ERR_NOERROR;
|
||||
}
|
||||
|
||||
void
|
||||
onlp_snmp_platform_init(void)
|
||||
@@ -110,5 +213,8 @@ onlp_snmp_platform_init(void)
|
||||
REGISTER_STR(14, service_tag);
|
||||
REGISTER_STR(15, onie_version);
|
||||
}
|
||||
|
||||
resource_int_register(1, "CpuAllPercentUtilization", utilization_handler);
|
||||
resource_int_register(2, "CpuAllPercentIdle", idle_handler);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user