3
A brief file description
5
@section license License
7
Licensed to the Apache Software Foundation (ASF) under one
8
or more contributor license agreements. See the NOTICE file
9
distributed with this work for additional information
10
regarding copyright ownership. The ASF licenses this file
11
to you under the Apache License, Version 2.0 (the
12
"License"); you may not use this file except in compliance
13
with the License. You may obtain a copy of the License at
15
http://www.apache.org/licenses/LICENSE-2.0
17
Unless required by applicable law or agreed to in writing, software
18
distributed under the License is distributed on an "AS IS" BASIS,
19
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
See the License for the specific language governing permissions and
21
limitations under the License.
24
/***************************************/
25
/****************************************************************************
27
* StatProcessor.cc - Functions for computing node and cluster stat
31
****************************************************************************/
33
#include "ink_config.h"
34
#include "StatProcessor.h"
35
#include "ink_unused.h"
37
#define STAT_CONFIG_FILE "stats.config.xml"
39
StatObjectList statObjectList;
40
StatXMLTag currentTag = INVALID_TAG;
41
StatObject *statObject = NULL;
42
char *exprContent = NULL;
43
static unsigned statCount = 0; // global statistics object counter
49
startElement(void *userData, const char *name, const char **atts)
51
NOWARN_UNUSED(userData);
55
if (!strcmp(name, "ink:statistics"))
56
currentTag = ROOT_TAG;
57
else if (!strcmp(name, "statistics"))
58
currentTag = STAT_TAG;
59
else if (!strcmp(name, "destination"))
61
else if (!strcmp(name, "expression"))
62
currentTag = EXPR_TAG;
64
currentTag = INVALID_TAG;
68
statObject = NEW(new StatObject(++statCount));
69
Debug(MODULE_INIT, "\nStat #: ----------------------- %d -----------------------\n", statCount);
71
for (i = 0; atts[i]; i += 2) {
72
ink_debug_assert(atts[i + 1]); // Attribute comes in pairs, hopefully.
74
if (!strcmp(atts[i], "minimum")) {
75
statObject->m_stats_min = (MgmtFloat) atof(atts[i + 1]);
76
} else if (!strcmp(atts[i], "maximum")) {
77
statObject->m_stats_max = (MgmtFloat) atof(atts[i + 1]);
78
} else if (!strcmp(atts[i], "interval")) {
79
statObject->m_update_interval = (ink_hrtime) atoi(atts[i + 1]);
80
} else if (!strcmp(atts[i], "debug")) {
81
statObject->m_debug = (atts[i + 1] && atts[i + 1][0] == '1');
84
Debug(MODULE_INIT, "\tDESTINTATION w/ attribute: %s -> %s\n", atts[i], atts[i + 1]);
89
exprContent = NEW(new char[BUFSIZ * 10]); // Will free up at endElement
90
memset(exprContent, 0, BUFSIZ * 10);
95
sumClusterVar = true; // Should only be used with cluster variable
97
for (i = 0; atts[i]; i += 2) {
98
ink_debug_assert(atts[i + 1]); // Attribute comes in pairs, hopefully.
99
if (!strcmp(atts[i], "scope")) {
100
nodeVar = (!strcmp(atts[i + 1], "node") ? true : false);
101
} else if (!strcmp(atts[i], "operation")) {
102
sumClusterVar = (!strcmp(atts[i + 1], "sum") ? true : false);
105
Debug(MODULE_INIT, "\tDESTINTATION w/ attribute: %s -> %s\n", atts[i], atts[i + 1]);
111
Debug(MODULE_INIT, "==========================================>%s<=\n", name);
121
endElement(void *userData, const char *name)
123
NOWARN_UNUSED(userData);
125
switch (currentTag) {
127
statObjectList.enqueue(statObject);
128
currentTag = ROOT_TAG;
132
statObject->assignExpr(exprContent);
137
currentTag = STAT_TAG;
144
charDataHandler(void *userData, const XML_Char * name, int len)
146
NOWARN_UNUSED(userData);
148
if (currentTag != EXPR_TAG && currentTag != DST_TAG) {
152
char content[BUFSIZ * 10];
153
if (XML_extractContent(name, content, BUFSIZ * 10) == 0) {
157
if (currentTag == EXPR_TAG) {
159
strncat(exprContent, content, ((BUFSIZ * 10) - strlen(exprContent) - 1));
163
statObject->assignDst(content, nodeVar, sumClusterVar);
170
StatProcessor::StatProcessor():m_lmgmt(NULL), m_overviewGenerator(NULL)
177
StatProcessor::rereadConfig()
179
textBuffer *fileContent = NULL;
180
Rollback *fileRB = NULL;
181
char *fileBuffer = NULL;
182
version_t fileVersion;
185
statObjectList.clean();
186
statCount = 0; // reset statistics counter
188
int ret = configFiles->getRollbackObj(STAT_CONFIG_FILE, &fileRB);
190
Debug(MODULE_INIT, " Can't get Rollback for file: %s\n", STAT_CONFIG_FILE);
192
fileVersion = fileRB->getCurrentVersion();
193
fileRB->getVersion(fileVersion, &fileContent);
194
fileBuffer = fileContent->bufPtr();
195
fileLen = strlen(fileBuffer);
198
* Start the XML Praser -- the package used is EXPAT
200
XML_Parser parser = XML_ParserCreate(NULL);
201
XML_SetUserData(parser, NULL);
202
XML_SetElementHandler(parser, startElement, endElement);
203
XML_SetCharacterDataHandler(parser, charDataHandler);
206
* Substiture every newline with a space to get around
207
* the SetCharacterDataHandler problem.
210
while ((newlinePtr = strchr(fileBuffer, '\n')) != NULL || (newlinePtr = strchr(fileBuffer, '\r')) != NULL) {
215
* Parse the input file according to XML standard.
216
* Print error if we encounter any
218
int status = XML_Parse(parser, fileBuffer, fileLen, true);
220
mgmt_log(stderr, "%s at line %d\n", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
226
XML_ParserFree(parser);
229
Debug(MODULE_INIT, "\n\n---------- END OF PARSING & INITIALIZING ---------\n\n");
233
StatProcessor::~StatProcessor()
236
Debug(MODULE_INIT, "[StatProcessor] Destructing Statistics Processor\n");
246
for (int i = 1; i <= 5; i++) {
247
memset(var_name, 0, 64);
248
snprintf(var_name, sizeof(var_name), "proxy.node.stats.test%d", i);
251
varFloatFromName("proxy.node.stats.test4", &tmp);
252
varSetFloat(var_name, tmp + 1, true);
254
varSetFloat(var_name, i, true);
263
MgmtFloat tmp1, tmp2;
266
varFloatFromName("proxy.node.stats.test1", &tmp1);
267
varFloatFromName("proxy.node.stats.test2", &tmp2);
269
Debug(MODULE_INIT, "PASS -- simple copy");
271
Debug(MODULE_INIT, "FAIL -- simple copy");
274
// 2. simple interval
275
varFloatFromName("proxy.node.stats.test3", &tmp2);
277
Debug(MODULE_INIT, "PASS -- simple interval & constant");
279
Debug(MODULE_INIT, "FAIL -- simple interval & constant %f", tmp2);
283
varFloatFromName("proxy.node.stats.test4", &tmp2);
284
if ((tmp2 > 150) && (tmp2 < 250)) {
285
Debug(MODULE_INIT, "PASS -- delta");
287
Debug(MODULE_INIT, "FAIL -- delta %f", tmp2);
293
* Updating the statistics NOW.
296
StatProcessor::processStat()
298
unsigned short result = 0;
300
Debug(MODULE_INIT, "[StatProcessor] Processing Statistics....\n");
303
statObjectList.Eval();
316
ExpressionEval(char *exprString)
318
StatObject statObject;
320
char content[BUFSIZ * 10];
321
XML_extractContent(exprString, content, BUFSIZ * 10);
323
statObject.assignExpr(content);
324
return statObject.NodeStatEval(false);