Fix prometheus exception

Fix prometheus exception (#10221)
This commit is contained in:
Theo Arends 2020-12-24 12:37:59 +01:00
parent 9747dd4b5c
commit f3feb3ea6a
1 changed files with 50 additions and 81 deletions

View File

@ -26,68 +26,47 @@
const char *UnitfromType(const char *type) // find unit for measurment type const char *UnitfromType(const char *type) // find unit for measurment type
{ {
if (strcmp(type, "time") == 0) if (strcmp(type, "time") == 0) {
{ return "seconds";
return "_seconds";
} }
if (strcmp(type, "temperature") == 0 || strcmp(type, "dewpoint") == 0) if (strcmp(type, "temperature") == 0 || strcmp(type, "dewpoint") == 0) {
{ return "celsius";
return "_celsius";
} }
if (strcmp(type, "pressure") == 0) if (strcmp(type, "pressure") == 0) {
{ return "hpa";
return "_hpa";
} }
if (strcmp(type, "voltage") == 0) if (strcmp(type, "voltage") == 0) {
{ return "volts";
return "_volts";
} }
if (strcmp(type, "current") == 0) if (strcmp(type, "current") == 0) {
{ return "amperes";
return "_amperes";
} }
if (strcmp(type, "mass") == 0) if (strcmp(type, "mass") == 0) {
{ return "grams";
return "_grams";
} }
if (strcmp(type, "carbondioxide") == 0) if (strcmp(type, "carbondioxide") == 0) {
{ return "ppm";
return "_ppm";
} }
if (strcmp(type, "humidity") == 0) if (strcmp(type, "humidity") == 0) {
{ return "percentage";
return "_percentage";
} }
return ""; return "";
} }
const char *FormatMetricName(const char *metric) // cleanup spaces and uppercases for Prmetheus metrics conventions String FormatMetricName(const char *metric) { // cleanup spaces and uppercases for Prmetheus metrics conventions
{ String formatted = metric;
char *formated = (char *)malloc(strlen(metric)+1); formatted.toLowerCase();
uint32_t cnt = 0; formatted.replace(" ", "_");
for (cnt; cnt < strlen(metric)+1; cnt++) return formatted;
{
if (metric[cnt] == ' ')
{
formated[cnt] = '_';
}
else
{
formated[cnt] = tolower(metric[cnt]);
}
}
return formated;
} }
void HandleMetrics(void) void HandleMetrics(void) {
{
if (!HttpCheckPriviledgedAccess()) { return; } if (!HttpCheckPriviledgedAccess()) { return; }
AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP "Prometheus")); AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP "Prometheus"));
WSContentBegin(200, CT_PLAIN); WSContentBegin(200, CT_PLAIN);
char parameter[FLOATSZ]; char parameter[FLOATSZ];
// Pseudo-metric providing metadata about the running firmware version. // Pseudo-metric providing metadata about the running firmware version.
@ -142,52 +121,43 @@ void HandleMetrics(void)
String jsonStr = json; String jsonStr = json;
JsonParser parser((char *)jsonStr.c_str()); JsonParser parser((char *)jsonStr.c_str());
JsonParserObject root = parser.getRootObject(); JsonParserObject root = parser.getRootObject();
if (root) if (root) { // did JSON parsing went ok?
{ // did JSON parsing went ok? for (auto key1 : root) {
for (auto key1 : root)
{
JsonParserToken value1 = key1.getValue(); JsonParserToken value1 = key1.getValue();
if (value1.isObject()) if (value1.isObject()) {
{
JsonParserObject Object2 = value1.getObject(); JsonParserObject Object2 = value1.getObject();
for (auto key2 : Object2) for (auto key2 : Object2) {
{
JsonParserToken value2 = key2.getValue(); JsonParserToken value2 = key2.getValue();
if (value2.isObject()) if (value2.isObject()) {
{
JsonParserObject Object3 = value2.getObject(); JsonParserObject Object3 = value2.getObject();
for (auto key3 : Object3) for (auto key3 : Object3) {
{
const char *value = key3.getValue().getStr(nullptr); const char *value = key3.getValue().getStr(nullptr);
if (value != nullptr && isdigit(value[0])) if (value != nullptr && isdigit(value[0])) {
{ String sensor = FormatMetricName(key2.getStr());
const char *sensor = FormatMetricName(key2.getStr()); //cleanup sensor name String type = FormatMetricName(key3.getStr());
const char *type = FormatMetricName(key3.getStr()); //cleanup sensor type const char *unit = UnitfromType(type.c_str()); //grab base unit corresponding to type
const char *unit = UnitfromType(type); //grab base unit corresponding to type WSContentSend_P(PSTR("# TYPE tasmota_sensors_%s_%s gauge\ntasmota_sensors_%s_%s{sensor=\"%s\"} %s\n"),
WSContentSend_P(PSTR("# TYPE tasmota_sensors_%s%s gauge\ntasmota_sensors_%s%s{sensor=\"%s\"} %s\n"), type, unit, type, unit, sensor, value); //build metric as "# TYPE tasmota_sensors_%type%_%unit% gauge\ntasmotasensors_%type%_%unit%{sensor=%sensor%"} %value%"" type.c_str(), unit, type.c_str(), unit, sensor.c_str(), value); //build metric as "# TYPE tasmota_sensors_%type%_%unit% gauge\ntasmotasensors_%type%_%unit%{sensor=%sensor%"} %value%""
} }
} }
} } else {
else
{
const char *value = value2.getStr(nullptr); const char *value = value2.getStr(nullptr);
if (value != nullptr && isdigit(value[0])) if (value != nullptr && isdigit(value[0])) {
{ String sensor = FormatMetricName(key1.getStr());
const char *sensor = FormatMetricName(key1.getStr()); String type = FormatMetricName(key2.getStr());
const char *type = FormatMetricName(key2.getStr()); const char *unit = UnitfromType(type.c_str());
const char *unit = UnitfromType(type); if (strcmp(type.c_str(), "totalstarttime") != 0) { // this metric causes prometheus of fail
WSContentSend_P(PSTR("# TYPE tasmota_sensors_%s%s gauge\ntasmota_sensors_%s%s{sensor=\"%s\"} %s\n"), type, unit, type, unit, sensor, value); WSContentSend_P(PSTR("# TYPE tasmota_sensors_%s_%s gauge\ntasmota_sensors_%s_%s{sensor=\"%s\"} %s\n"),
type.c_str(), unit, type.c_str(), unit, sensor.c_str(), value);
} }
} }
} }
} }
else } else {
{
const char *value = value1.getStr(nullptr); const char *value = value1.getStr(nullptr);
if (value != nullptr && isdigit(value[0] && strcmp(key1.getStr(), "Time") != 0)) //remove false 'time' metric String sensor = FormatMetricName(key1.getStr());
{ if (value != nullptr && isdigit(value[0] && strcmp(sensor.c_str(), "time") != 0)) { //remove false 'time' metric
const char *sensor = FormatMetricName(key1.getStr()); WSContentSend_P(PSTR("# TYPE tasmota_sensors_%s gauge\ntasmota_sensors{sensor=\"%s\"} %s\n"), sensor.c_str(), sensor.c_str(), value);
WSContentSend_P(PSTR("# TYPE tasmota_sensors_%s gauge\ntasmota_sensors{sensor=\"%s\"} %s\n"), sensor, sensor, value);
} }
} }
} }
@ -200,8 +170,7 @@ void HandleMetrics(void)
* Interface * Interface
\*********************************************************************************************/ \*********************************************************************************************/
bool Xsns75(uint8_t function) bool Xsns75(uint8_t function) {
{
bool result = false; bool result = false;
switch (function) { switch (function) {