You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by jp...@apache.org on 2014/08/02 04:59:32 UTC
[6/9] TS-2977: move the stats processor to traffic_manager
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e6d233f/mgmt/stats/StatType.cc
----------------------------------------------------------------------
diff --git a/mgmt/stats/StatType.cc b/mgmt/stats/StatType.cc
deleted file mode 100644
index 1c51b95..0000000
--- a/mgmt/stats/StatType.cc
+++ /dev/null
@@ -1,1199 +0,0 @@
-/** @file
-
- A brief file description
-
- @section license License
-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
-/***************************************/
-/****************************************************************************
- *
- * StatType.cc - Functions for computing node and cluster stat
- * aggregation
- *
- *
- ****************************************************************************/
-
-#include "ink_config.h"
-#include "StatType.h"
-#include "MgmtUtils.h"
-#include "ink_hrtime.h"
-#include "WebOverview.h"
-
-bool StatError = false; // global error flag
-bool StatDebug = false; // global debug flag
-
-/**
- * StatExprToken()
- * ---------------
- */
-StatExprToken::StatExprToken()
- : m_arith_symbol('\0'),
- m_token_name(NULL),
- m_token_type(RECD_NULL),
- m_sum_var(false), m_node_var(true)
-{
- RecDataClear(RECD_NULL, &m_token_value);
- RecDataClear(RECD_NULL, &m_token_value_max);
- RecDataClear(RECD_NULL, &m_token_value_min);
- memset(&m_token_value_delta, 0, sizeof(m_token_value_delta));
-}
-
-
-/**
- * StatExprToken::copy()
- * ---------------------
- */
-void
-StatExprToken::copy(const StatExprToken & source)
-{
- m_arith_symbol = source.m_arith_symbol;
-
- if (source.m_token_name != NULL) {
- m_token_name = ats_strdup(source.m_token_name);
- }
-
- m_token_type = source.m_token_type;
- m_token_value = source.m_token_value;
- m_token_value_min = source.m_token_value_min;
- m_token_value_max = source.m_token_value_max;
-
- if (source.m_token_value_delta) {
- m_token_value_delta = new StatDataSamples();
- m_token_value_delta->previous_time = source.m_token_value_delta->previous_time;
- m_token_value_delta->current_time = source.m_token_value_delta->current_time;
- m_token_value_delta->previous_value = source.m_token_value_delta->previous_value;
- m_token_value_delta->current_value = source.m_token_value_delta->current_value;
- }
-
- m_node_var = source.m_node_var;
- m_sum_var = source.m_sum_var;
-}
-
-
-/**
- * StatExprToken::assignTokenName()
- * --------------------------------
- * Assign the token name. If the token is a predefined constant,
- * assign the value as well. Also, assign the token type as well.
- */
-void
-StatExprToken::assignTokenName(const char *name)
-{
-
- if (isdigit(name[0])) {
- // numerical constant
- m_token_name = ats_strdup("CONSTANT");
- m_token_type = RECD_CONST;
- } else {
- m_token_name = ats_strdup(name);
- assignTokenType();
- }
-
- switch (m_token_type) {
- case RECD_INT:
- case RECD_COUNTER:
- case RECD_FLOAT:
- break;
- case RECD_CONST:
- // assign pre-defined constant in here
- // constant will be stored as RecFloat type.
- if (!strcmp(m_token_name, "CONSTANT")) {
- m_token_value.rec_float = (RecFloat) atof(name);
- } else if (!strcmp(m_token_name, "$BYTES_TO_MB_SCALE")) {
- m_token_value.rec_float = (RecFloat) BYTES_TO_MB_SCALE;
- } else if (!strcmp(m_token_name, "$MBIT_TO_KBIT_SCALE")) {
- m_token_value.rec_float = (RecFloat) MBIT_TO_KBIT_SCALE;
- } else if (!strcmp(m_token_name, "$SECOND_TO_MILLISECOND_SCALE")) {
- m_token_value.rec_float = (RecFloat) SECOND_TO_MILLISECOND_SCALE;
- } else if (!strcmp(m_token_name, "$PCT_TO_INTPCT_SCALE")) {
- m_token_value.rec_float = (RecFloat) PCT_TO_INTPCT_SCALE;
- } else if (!strcmp(m_token_name, "$HRTIME_SECOND")) {
- m_token_value.rec_float = (RecFloat) HRTIME_SECOND;
- } else if (!strcmp(m_token_name, "$BYTES_TO_MBIT_SCALE")) {
- m_token_value.rec_float = (RecFloat) BYTES_TO_MBIT_SCALE;
- } else {
- mgmt_log(stderr, "[StatPro] ERROR: Undefined constant: %s\n", m_token_name);
- StatError = true;
- }
- case RECD_FX:
- default:
- break;
- }
-}
-
-
-/**
- * assignTokenType()
- * -----------------
- * Assign the proper token type based on the token name.
- * Do some token type conversion if necessary. Return true
- * if the token type is recognizable; false otherwise.
- */
-bool StatExprToken::assignTokenType()
-{
- ink_assert(m_token_name != NULL);
- m_token_type = varType(m_token_name);
-
- if (m_token_name[0] == '$') {
- m_token_type = RECD_CONST;
- } else if (m_token_name[0] == '_') {
- m_token_type = RECD_FX;
- }
-
- if (m_token_value_delta) {
- m_token_value_delta->data_type = m_token_type;
- }
-
- // I'm guessing here that we want to check if we're still RECD_NULL,
- // it used to be INVALID, which is not in the m_token_type's enum. /leif
- return (m_token_type != RECD_NULL);
-}
-
-
-void
-StatExprToken::clean()
-{
- ats_free(m_token_name);
- delete m_token_value_delta;
-}
-
-
-/**
- * FOR DEBUGGING ONLY
- * Print the token according to its type in a human-readable format. :)
- */
-void
-StatExprToken::print(const char *prefix)
-{
- if (m_token_name != NULL) {
- printf("%s\t%s\n", prefix, m_token_name);
- } else {
- printf("%s\t%c\n", prefix, m_arith_symbol);
- }
-}
-
-
-/**
- * StatExprToken::precedence()
- * ---------------------------
- * Return the binary operator precedence. The higher returning value,
- * the higher the precedence value.
- */
-short
-StatExprToken::precedence()
-{
- switch (m_arith_symbol) {
- case '(':
- return 4;
- case '^': // fall through
- case '!':
- return 3;
- case '*': // fall through
- case '/':
- return 2;
- case '+': // fall through
- case '-':
- return 1;
- default:
- return -1;
- }
-}
-
-
-/**
- * StatExprToken::statVarSet()
- * ---------------------------
- * This method is responsible for ensuring the assigning value
- * fall within the min. and max. bound. If it's smaller than min.
- * or larger than max, then the error value is assigned. If no
- * error value is assigned, either min. or max. is assigned.
- */
-bool StatExprToken::statVarSet(RecDataT type, RecData value)
-{
- RecData converted_value;
-
- if (StatError) {
- /* fix this after librecords is done
- mgmt_log(stderr,
- "[StatPro] ERROR in a statistics aggregation operations\n");
- */
- RecData err_value;
- RecDataClear(m_token_type, &err_value);
- return varSetData(m_token_type, m_token_name, err_value);
- }
-
- /*
- * do conversion if necessary.
- */
- if (m_token_type != type) {
- switch (m_token_type) {
- case RECD_INT:
- case RECD_COUNTER:
- if (type == RECD_NULL)
- converted_value = value;
- else if (type == RECD_INT || type == RECD_COUNTER || type == RECD_FX)
- converted_value.rec_int = value.rec_int;
- else if (type == RECD_FLOAT || type == RECD_CONST)
- converted_value.rec_int = (RecInt)value.rec_float;
- else
- Fatal("%s, invalid value type:%d\n", m_token_name, type);
- break;
- case RECD_FLOAT:
- if (type == RECD_NULL)
- converted_value = value;
- else if (type == RECD_INT || type == RECD_COUNTER || type == RECD_FX)
- converted_value.rec_float = (RecFloat)value.rec_int;
- else if (type == RECD_FLOAT || type == RECD_CONST)
- converted_value.rec_float = value.rec_float;
- else
- Fatal("%s, invalid value type:%d\n", m_token_name, type);
- break;
- default:
- Fatal("%s, unsupported token type:%d\n", m_token_name, m_token_type);
- }
- } else {
- converted_value = value;
- }
-
- if (RecDataCmp(m_token_type, converted_value, m_token_value_min) < 0) {
- value = m_token_value_min;
- }
- else if (RecDataCmp(m_token_type, converted_value, m_token_value_max) > 0) {
- value = m_token_value_max;
- }
-
- return varSetData(m_token_type, m_token_name, converted_value);
-}
-
-
-/***********************************************************************
- StatExprList
- **********************************************************************/
-
-/**
- * StatExprList::StatExprList()
- * ----------------------------
- */
-StatExprList::StatExprList()
- : m_size(0)
-{
-}
-
-
-/**
- * StatExprList::clean()
- * ---------------------
- */
-void
-StatExprList::clean()
-{
- StatExprToken *temp = NULL;
-
- while ((temp = m_tokenList.dequeue())) {
- delete(temp);
- m_size -= 1;
- }
- ink_assert(m_size == 0);
-}
-
-
-void
-StatExprList::enqueue(StatExprToken * entry)
-{
- ink_assert(entry);
- m_tokenList.enqueue(entry);
- m_size += 1;
-}
-
-
-void
-StatExprList::push(StatExprToken * entry)
-{
- ink_assert(entry);
- m_tokenList.push(entry);
- m_size += 1;
-}
-
-
-StatExprToken *
-StatExprList::dequeue()
-{
- if (m_size == 0) {
- return NULL;
- }
- m_size -= 1;
- return (StatExprToken *) m_tokenList.dequeue();
-}
-
-
-StatExprToken *
-StatExprList::pop()
-{
- if (m_size == 0) {
- return NULL;
- }
- m_size -= 1;
- return m_tokenList.pop();
-}
-
-
-StatExprToken *
-StatExprList::top()
-{
- if (m_size == 0) {
- return NULL;
- }
- return m_tokenList.head;
-}
-
-
-StatExprToken *
-StatExprList::first()
-{
- if (m_size == 0) {
- return NULL;
- }
- return m_tokenList.head;
-}
-
-
-StatExprToken *
-StatExprList::next(StatExprToken * current)
-{
- if (!current) {
- return NULL;
- }
- return (current->link).next;
-}
-
-
-/**
- * StatExprList::print()
- * ---------------------
- * Print the token in the expression in a human-readable format. :)
- */
-void
-StatExprList::print(const char *prefix)
-{
- for (StatExprToken * token = first(); token; token = next(token)) {
- token->print(prefix);
- }
-}
-
-
-/**
- * StatExprToken::count()
- * ----------------------
- * Counts the number of token in the expression list and return it.
- */
-unsigned
-StatExprList::count()
-{
- return m_size;
-}
-
-
-/***********************************************************************
- StatObject
- **********************************************************************/
-
-
-/**
- * StatObject::StatObject()
- * ------------------------
- */
-
-StatObject::StatObject()
- : m_id(1),
- m_debug(false),
- m_expr_string(NULL),
- m_node_dest(NULL),
- m_cluster_dest(NULL),
- m_expression(NULL),
- m_postfix(NULL),
- m_last_update(-1),
- m_current_time(-1), m_update_interval(-1),
- m_stats_max(FLT_MAX), m_stats_min(FLT_MIN),
- m_has_max(false), m_has_min(false), m_has_delta(false)
-{
-}
-
-
-StatObject::StatObject(unsigned identifier)
- : m_id(identifier),
- m_debug(false),
- m_expr_string(NULL),
- m_node_dest(NULL),
- m_cluster_dest(NULL),
- m_expression(NULL),
- m_postfix(NULL),
- m_last_update(-1),
- m_current_time(-1), m_update_interval(-1),
- m_stats_max(FLT_MAX), m_stats_min(FLT_MIN),
- m_has_max(false), m_has_min(false), m_has_delta(false)
-{
-}
-
-
-/**
- * StatObject::clean()
- * -------------------
- */
-void
-StatObject::clean()
-{
- ats_free(m_expr_string);
- delete m_node_dest;
- delete m_cluster_dest;
- delete m_postfix;
-}
-
-
-/**
- * StatObject::assignDst()
- * -----------------------
- */
-void
-StatObject::assignDst(const char *str, bool m_node_var, bool m_sum_var)
-{
- if (StatDebug) {
- Debug(MODULE_INIT, "DESTINTATION: %s\n", str);
- }
-
- StatExprToken *statToken = new StatExprToken();
-
- statToken->assignTokenName(str);
- statToken->m_node_var = m_node_var;
- statToken->m_sum_var = m_sum_var;
-
- // The type of dst token should be always not NULL
- if (statToken->m_token_type == RECD_NULL) {
- Fatal("token:%s, invalid token type!", statToken->m_token_name);
- }
-
- // Set max/min value
- if (m_has_max)
- RecDataSetFromFloat(statToken->m_token_type, &statToken->m_token_value_max,
- m_stats_max);
- else
- RecDataSetMax(statToken->m_token_type, &statToken->m_token_value_max);
-
- if (m_has_min)
- RecDataSetFromFloat(statToken->m_token_type, &statToken->m_token_value_min,
- m_stats_min);
- else
- RecDataSetMin(statToken->m_token_type, &statToken->m_token_value_min);
-
- if (m_node_var) {
- ink_assert(m_node_dest == NULL);
- m_node_dest = statToken;
- } else {
- ink_assert(m_cluster_dest == NULL);
- m_cluster_dest = statToken;
- }
-}
-
-
-/**
- * StatObject::assignExpr()
- * ------------------------
- */
-void
-StatObject::assignExpr(char *str)
-{
- StatExprToken *statToken = NULL;
-
- if (StatDebug) {
- Debug(MODULE_INIT, "EXPRESSION: %s\n", str);
- }
- ink_assert(m_expr_string == NULL);
- // We take ownership here
- m_expr_string = str;
-
- Tokenizer exprTok(" ");
- exprTok.Initialize(str);
- tok_iter_state exprTok_state;
- const char *token = exprTok.iterFirst(&exprTok_state);
-
- ink_assert(m_expression == NULL);
- m_expression = new StatExprList();
-
- while (token) {
-
- statToken = new StatExprToken();
-
- if (isOperator(token[0])) {
-
- statToken->m_arith_symbol = token[0];
- ink_assert(statToken->m_token_name == NULL);
-
- if (StatDebug) {
- Debug(MODULE_INIT, "\toperator: ->%c<-\n", statToken->m_arith_symbol);
- }
-
- } else {
-
- ink_assert(statToken->m_arith_symbol == '\0');
-
- // delta
- if (token[0] == '#') {
-
- token += 1; // skip '#'
- statToken->m_token_value_delta = new StatDataSamples();
- statToken->m_token_value_delta->previous_time = (ink_hrtime) 0;
- statToken->m_token_value_delta->current_time = (ink_hrtime) 0;
- statToken->m_token_value_delta->data_type = RECD_NULL;
- RecDataClear(RECD_NULL, &statToken->m_token_value_delta->previous_value);
- RecDataClear(RECD_NULL, &statToken->m_token_value_delta->current_value);
-
- }
-
- statToken->assignTokenName(token);
-
- if (StatDebug) {
- Debug(MODULE_INIT, "\toperand: ->%s<-\n", token);
- }
-
- }
-
- token = exprTok.iterNext(&exprTok_state);
- m_expression->enqueue(statToken);
-
- }
-
- infix2postfix();
-
-}
-
-
-/**
- * StatObject::infix2postfix()
- * ---------------------------
- * Takes the infix "expression" and convert it to a postfix for future
- * evaluation.
- *
- * SIDE EFFECT: consume all token in "expression"
- */
-void
-StatObject::infix2postfix()
-{
- StatExprList stack;
- StatExprToken *tempToken = NULL;
- StatExprToken *curToken = NULL;
- m_postfix = new StatExprList();
-
- while (m_expression->top()) {
- curToken = m_expression->dequeue();
-
- if (!isOperator(curToken->m_arith_symbol)) {
- //printf("I2P~: enqueue %s\n", curToken->m_token_name);
- m_postfix->enqueue(curToken);
-
- } else {
- ink_assert(curToken->m_arith_symbol != '\0');
-
- if (curToken->m_arith_symbol == '(') {
- stack.push(curToken);
- } else if (curToken->m_arith_symbol == ')') {
- tempToken = (StatExprToken *) stack.pop();
-
- while (tempToken->m_arith_symbol != '(') {
- //printf("I2P@: enqueue %c\n", tempToken->m_arith_symbol);
- m_postfix->enqueue(tempToken);
- tempToken = (StatExprToken *) stack.pop();
- }
-
- // Free up memory for ')'
- delete(curToken);
- delete(tempToken);
-
- } else {
- if (stack.count() == 0) {
- stack.push(curToken);
- } else {
- tempToken = (StatExprToken *) stack.top();
-
- while ((tempToken->m_arith_symbol != '(') && (tempToken->precedence() >= curToken->precedence())) {
- tempToken = (StatExprToken *) stack.pop(); // skip the (
- //printf("I2P$: enqueue %c\n", tempToken->m_arith_symbol);
- m_postfix->enqueue(tempToken);
- if (stack.count() == 0) {
- break;
- }
- tempToken = (StatExprToken *) stack.top();
- } // while
-
- stack.push(curToken);
- }
- }
- }
- }
-
- while (stack.count() > 0) {
- tempToken = (StatExprToken *) stack.pop();
- //printf("I2P?: enqueue %c\n", tempToken->m_arith_symbol);
- m_postfix->enqueue(tempToken);
- }
-
- // dump infix expression
- delete(m_expression);
- m_expression = NULL;
-}
-
-
-/**
- * StatObject::NodeStatEval()
- * --------------------------
- *
- *
- */
-RecData StatObject::NodeStatEval(RecDataT *result_type, bool cluster)
-{
- StatExprList stack;
- StatExprToken *left = NULL;
- StatExprToken *right = NULL;
- StatExprToken *result = NULL;
- StatExprToken *curToken = NULL;
- RecData tempValue;
- RecDataClear(RECD_NULL, &tempValue);
-
- *result_type = RECD_NULL;
-
- /* Express checkout lane -- Stat. object with on 1 source variable */
- if (m_postfix->count() == 1) {
- StatExprToken * src = m_postfix->top();
-
- // in librecords, not all statistics are register at initialization
- // must assign proper type if it is undefined.
- if (src->m_token_type == RECD_NULL) {
- src->assignTokenType();
- }
-
- *result_type = src->m_token_type;
- if (src->m_token_type == RECD_CONST) {
- tempValue = src->m_token_value;
- } else if (src->m_token_value_delta) {
- tempValue = src->m_token_value_delta->diff_value(src->m_token_name);
- } else if (!cluster) {
- if (!varDataFromName(src->m_token_type, src->m_token_name, &tempValue)) {
- RecDataClear(src->m_token_type, &tempValue);
- }
- } else {
- if (!overviewGenerator->varClusterDataFromName(src->m_token_type,
- src->m_token_name,
- &tempValue)) {
- RecDataClear(src->m_token_type, &tempValue);
- }
- }
- } else {
-
- /* standard postfix evaluation */
- for (StatExprToken * token = m_postfix->first(); token; token = m_postfix->next(token)) {
- /* carbon-copy the token. */
- curToken = new StatExprToken();
- curToken->copy(*token);
-
- if (!isOperator(curToken->m_arith_symbol)) {
- stack.push(curToken);
- } else {
- ink_assert(isOperator(curToken->m_arith_symbol));
- right = stack.pop();
- left = stack.pop();
-
- if (left->m_token_type == RECD_NULL) {
- left->assignTokenType();
- }
- if (right->m_token_type == RECD_NULL) {
- right->assignTokenType();
- }
-
- result = StatBinaryEval(left, curToken->m_arith_symbol, right, cluster);
-
- stack.push(result);
- delete(curToken);
- delete(left);
- delete(right);
- }
- }
-
- /* should only be 1 value left on stack -- the resulting value */
- if (stack.count() > 1) {
- stack.print("\t");
- ink_assert(false);
- }
-
- *result_type = stack.top()->m_token_type;
- tempValue = stack.top()->m_token_value;
- }
-
- return tempValue;
-
-}
-
-
-/**
- * StatObject::ClusterStatEval()
- * -----------------------------
- *
- *
- */
-RecData StatObject::ClusterStatEval(RecDataT *result_type)
-{
- /* Sanity check */
- ink_assert(m_cluster_dest && !m_cluster_dest->m_node_var);
-
- // what is this?
- if ((m_node_dest == NULL) || (m_cluster_dest->m_sum_var == false)) {
- return NodeStatEval(result_type, true);
- } else {
- RecData tempValue;
-
- if (!overviewGenerator->varClusterDataFromName(m_node_dest->m_token_type,
- m_node_dest->m_token_name,
- &tempValue)) {
- *result_type = RECD_NULL;
- RecDataClear(*result_type, &tempValue);
- }
-
- return (tempValue);
- }
-}
-
-
-/**
- * StatObject::setTokenValue()
- * ---------------------------
- * The logic of the following code segment is the following.
- * The objective is to extract the appropriate right->m_token_value.
- * If 'right' is an intermediate value, nothing to do.
- * If m_token_type is RECD_CONST, nothing to do.
- * If m_token_type is RECD_FX, right->m_token_value is the diff. in time.
- * If m_token_type is either RECD_INT or RECD_FLOAT, it can either
- * by a cluster variable or a node variable.
- * If it is a cluster variable, just use varClusterFloatFromName
- * to set right->m_token_value.
- * If it is a node variable, then it can either be a variable
- * with delta. To determine whether it has a delta, simply search
- * the m_token_name in the delta list. If found then it has delta.
- * If it has delta then use the delta's diff. in value,
- * otherwise simply set right->m_token_value with varFloatFromName.
- */
-void
-StatObject::setTokenValue(StatExprToken * token, bool cluster)
-{
- if (token->m_token_name) {
- // it is NOT an intermediate value
-
- switch (token->m_token_type) {
- case RECD_CONST:
- break;
-
- case RECD_FX:
- // only support time function
- // use rec_int to store time value
- token->m_token_value.rec_int = (m_current_time - m_last_update);
- break;
-
- case RECD_INT: // fallthought
- case RECD_COUNTER:
- case RECD_FLOAT:
- if (cluster) {
- if (!overviewGenerator->varClusterDataFromName(token->m_token_type,
- token->m_token_name,
- &(token->m_token_value)))
- {
- RecDataClear(token->m_token_type, &token->m_token_value);
- }
- } else {
- if (token->m_token_value_delta) {
- token->m_token_value =
- token->m_token_value_delta->diff_value(token->m_token_name);
- } else {
- if (!varDataFromName(token->m_token_type, token->m_token_name,
- &(token->m_token_value))) {
- RecDataClear(token->m_token_type, &token->m_token_value);
- }
- } // delta?
- } // cluster?
- break;
-
- default:
- if (StatDebug) {
- Debug(MODULE, "Unrecognized token \"%s\" of type %d.\n",
- token->m_token_name, token->m_token_type);
- }
- } // switch
- } // m_token_name?
-}
-
-
-/**
- * StatObject::StatBinaryEval()
- * ------------------------
- * Take the left token, the right token, an binary operation and perform an
- * arithmatic operations on them. This function is responsible for getting the
- * correct value from:
- * - (1) node variable
- * - (2) node variable with a delta structure
- * - (3) cluster variable
- * - (4) an immediate value
- */
-StatExprToken *StatObject::StatBinaryEval(StatExprToken * left, char op,
- StatExprToken * right, bool cluster)
-{
- RecData l, r;
- StatExprToken *result = new StatExprToken();
- result->m_token_type = RECD_INT;
-
- if (left->m_token_type == RECD_NULL
- && right->m_token_type == RECD_NULL) {
- return result;
- }
-
- if (left->m_token_type != RECD_NULL) {
- setTokenValue(left, cluster);
- result->m_token_type = left->m_token_type;
- }
-
- if (right->m_token_type != RECD_NULL) {
- setTokenValue(right, cluster);
- switch (result->m_token_type) {
- case RECD_NULL:
- result->m_token_type = right->m_token_type;
- break;
- case RECD_FX:
- case RECD_INT:
- case RECD_COUNTER:
- /*
- * When types of left and right are different, select RECD_FLOAT
- * as result type. It's may lead to loss of precision when do
- * conversion, be careful!
- */
- if (right->m_token_type == RECD_FLOAT
- || right->m_token_type == RECD_CONST) {
- result->m_token_type = right->m_token_type;
- }
- break;
- case RECD_CONST:
- case RECD_FLOAT:
- break;
- default:
- Fatal("Unexpected RecData Type:%d", result->m_token_type);
- break;
- }
- }
-
- /*
- * We should make the operands with the same type before calculating.
- */
- RecDataClear(RECD_NULL, &l);
- RecDataClear(RECD_NULL, &r);
-
- if (left->m_token_type == right->m_token_type ) {
- l = left->m_token_value;
- r = right->m_token_value;
- } else if (result->m_token_type != left->m_token_type) {
- if (left->m_token_type != RECD_NULL) {
- ink_assert(result->m_token_type == RECD_FLOAT
- || result->m_token_type == RECD_CONST);
-
- l.rec_float = (RecFloat)left->m_token_value.rec_int;
- }
- r = right->m_token_value;
- ink_assert(result->m_token_type == right->m_token_type);
- } else {
- l = left->m_token_value;
- if (right->m_token_type != RECD_NULL) {
- ink_assert(result->m_token_type == RECD_FLOAT
- || result->m_token_type == RECD_CONST);
-
- r.rec_float = (RecFloat)right->m_token_value.rec_int;
- }
- ink_assert(result->m_token_type == left->m_token_type);
- }
-
- /*
- * Start to calculate
- */
- switch (op) {
- case '+':
- result->m_token_value = RecDataAdd(result->m_token_type, l, r);
- break;
-
- case '-':
- result->m_token_value = RecDataSub(result->m_token_type, l, r);
- break;
-
- case '*':
- result->m_token_value = RecDataMul(result->m_token_type, l, r);
- break;
-
- case '/':
- RecData recTmp;
- RecDataClear(RECD_NULL, &recTmp);
-
- /*
- * Force the type of result to be RecFloat on div operation
- */
- if (result->m_token_type != RECD_FLOAT && result->m_token_type != RECD_CONST) {
- RecFloat t;
-
- result->m_token_type = RECD_FLOAT;
-
- t = (RecFloat)l.rec_int;
- l.rec_float = t;
-
- t = (RecFloat)r.rec_int;
- r.rec_float = t;
- }
-
- if (RecDataCmp(result->m_token_type, r, recTmp)) {
- result->m_token_value = RecDataDiv(result->m_token_type, l, r);
- }
- break;
-
- default:
- // should never reach here
- StatError = true;
- }
-
- return (result);
-}
-
-
-/***********************************************************************
- StatObjectList
- **********************************************************************/
-
-StatObjectList::StatObjectList()
- : m_size(0)
-{
-}
-
-
-void
-StatObjectList::clean()
-{
- StatObject *temp = NULL;
-
- while ((temp = m_statList.dequeue())) {
- m_size -= 1;
- delete(temp);
- }
-
- ink_assert(m_size == 0);
-}
-
-
-void
-StatObjectList::enqueue(StatObject * object)
-{
- for (StatExprToken * token = object->m_postfix->first(); token; token = object->m_postfix->next(token)) {
- if (token->m_token_value_delta) {
- object->m_has_delta = true;
- break;
- }
- }
-
- m_statList.enqueue(object);
- m_size += 1;
-}
-
-
-StatObject *
-StatObjectList::first()
-{
- return m_statList.head;
-}
-
-
-StatObject *
-StatObjectList::next(StatObject * current)
-{
- return (current->link).next;
-}
-
-
-/**
- * StatObjectList::Eval()
- * ----------------------
- * The statisitic processor entry point to perform the calculation.
- */
-short
-StatObjectList::Eval()
-{
- RecData tempValue;
- RecData result;
- RecDataT result_type;
- ink_hrtime threshold = 0;
- ink_hrtime delta = 0;
- short count = 0;
-
- RecDataClear(RECD_NULL, &tempValue);
- RecDataClear(RECD_NULL, &result);
-
- for (StatObject * object = first(); object; object = next(object)) {
- StatError = false;
- StatDebug = object->m_debug;
-
- if (StatDebug) {
- Debug(MODULE, "\n##### %d #####\n", object->m_id);
- }
-
- if (object->m_update_interval <= 0) {
- // non-time statistics
- object->m_current_time = ink_get_hrtime_internal();
-
- if (object->m_node_dest) {
- result = object->NodeStatEval(&result_type, false);
- object->m_node_dest->statVarSet(result_type, result);
- }
-
- if (object->m_cluster_dest) {
- result = object->ClusterStatEval(&result_type);
- object->m_cluster_dest->statVarSet(result_type, result);
- }
-
- object->m_last_update = object->m_current_time;
- } else {
- // timed statisitics
- object->m_current_time = ink_get_hrtime_internal();
-
- threshold = object->m_update_interval * HRTIME_SECOND;
- delta = object->m_current_time - object->m_last_update;
-
- if (StatDebug) {
- Debug(MODULE, "\tUPDATE:%" PRId64 " THRESHOLD:%" PRId64 ", DELTA:%" PRId64 "\n", object->m_update_interval, threshold, delta);
- }
-
- /* Should we do the calculation? */
- if ((delta > threshold) || /* sufficient elapsed time? */
- (object->m_last_update == -1) || /* first time? */
- (object->m_last_update > object->m_current_time)) { /*wrapped */
-
- if (StatDebug) {
- if (delta > threshold) {
- Debug(MODULE, "\t\tdelta > threshold IS TRUE!\n");
- }
- if (object->m_last_update == -1) {
- Debug(MODULE, "\t\tm_last_update = -1 IS TRUE!\n");
- }
- if (object->m_last_update > object->m_current_time) {
- Debug(MODULE, "\t\tm_last_update > m_current_time IS TRUE\n");
- }
- }
-
- if (!object->m_has_delta) {
-
- if (StatDebug) {
- Debug(MODULE, "\tEVAL: Simple time-condition.\n");
- }
-
- if (object->m_node_dest) {
- result = object->NodeStatEval(&result_type, false);
- object->m_node_dest->statVarSet(result_type, result);
- }
-
- if (object->m_cluster_dest) {
- result = object->ClusterStatEval(&result_type);
- object->m_cluster_dest->statVarSet(result_type, result);
- }
-
- object->m_last_update = object->m_current_time;
- } else {
- /* has delta */
- if (StatDebug) {
- Debug(MODULE, "\tEVAL: Complicated time-condition.\n");
- }
- // scroll old values
- for (StatExprToken * token = object->m_postfix->first(); token; token = object->m_expression->next(token)) {
-
- // in librecords, not all statistics are register at initialization
- // must assign proper type if it is undefined.
- if (!isOperator(token->m_arith_symbol) && token->m_token_type == RECD_NULL) {
- token->assignTokenType();
- }
-
- if (token->m_token_value_delta) {
- if (!varDataFromName(token->m_token_type, token->m_token_name,
- &tempValue)) {
- RecDataClear(RECD_NULL, &tempValue);
- }
-
- token->m_token_value_delta->previous_time = token->m_token_value_delta->current_time;
- token->m_token_value_delta->previous_value = token->m_token_value_delta->current_value;
- token->m_token_value_delta->current_time = object->m_current_time;
- token->m_token_value_delta->current_value = tempValue;
- }
- }
-
- if (delta > threshold) {
- if (object->m_node_dest) {
- result = object->NodeStatEval(&result_type, false);
- object->m_node_dest->statVarSet(result_type, result);
- }
-
- if (object->m_cluster_dest) {
- result = object->ClusterStatEval(&result_type);
- object->m_cluster_dest->statVarSet(result_type, result);
- }
-
- object->m_last_update = object->m_current_time;
- } else {
- if (StatDebug) {
- Debug(MODULE, "\tEVAL: Timer not expired, do nothing\n");
- }
- }
- } /* delta? */
- } else {
- if (StatDebug) {
- Debug(MODULE, "\tEVAL: Timer not expired, nor 1st time, nor wrapped, SORRY!\n");
- }
- } /* timed event */
- }
- count += 1;
- } /* for */
-
- return count;
-} /* Eval() */
-
-
-/**
- * StatObjectList::print()
- * --------------------------
- * Print the list of of statistics object in a human-readable format. :)
- */
-void
-StatObjectList::print(const char *prefix)
-{
- for (StatObject * object = first(); object; object = next(object)) {
- if (StatDebug) {
- Debug(MODULE, "\n%sSTAT OBJECT#: %d\n", prefix, object->m_id);
- }
-
- if (object->m_expression) {
- object->m_expression->print("\t");
- }
-
- if (object->m_postfix) {
- object->m_postfix->print("\t");
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e6d233f/mgmt/stats/StatType.h
----------------------------------------------------------------------
diff --git a/mgmt/stats/StatType.h b/mgmt/stats/StatType.h
deleted file mode 100644
index 673e1e7..0000000
--- a/mgmt/stats/StatType.h
+++ /dev/null
@@ -1,231 +0,0 @@
-/** @file
-
- A brief file description
-
- @section license License
-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
-/***************************************/
-/****************************************************************************
- *
- * StatType.h - Functions for computing node and cluster stat
- * aggregation
- *
- *
- ****************************************************************************/
-
-#ifndef _STATTYPE_H_
-#define _STATTYPE_H_
-
-#include "StatXML.h"
-#include "Main.h" // Debug()
-#include "WebMgmtUtils.h"
-
-#define BYTES_TO_MBIT_SCALE (8/1000000.0)
-
-/* Structs used in Average Statistics calculations */
-struct StatDataSamples
-{
- ink_hrtime previous_time;
- ink_hrtime current_time;
- RecDataT data_type;
- RecData previous_value;
- RecData current_value;
-
- RecData diff_value(const char *name)
- {
- RecData tmp;
-
- if (data_type == RECD_NULL) {
- data_type = varType(name);
- }
-
- if (data_type != RECD_NULL)
- return RecDataSub(data_type, current_value, previous_value);
- else {
- RecDataClear(RECD_NULL, &tmp);
- return tmp;
- }
- }
- ink_hrtime diff_time()
- {
- return (current_time - previous_time);
- }
-};
-
-// Urgly workaround -- no optimization in HPUX
-#if defined(hpux)
-#define inline
-#endif
-
-#define MODULE "StatPro" // Statistics processor debug tag
-#define MODULE_INIT "StatProInit" // Statistics processor debug tag
-
-/***************************************************************
- * StatExprToken
- * a statistics expression token can either be a binary operator,
- * name '+', '-', '*', '/', or parenthesis '(', ')' or a TS variable.
- * In the former case, the arithSymbol stores the operator or
- * paranthesis; otherwise arithSymbol is '/0';
- ***************************************************************/
-class StatExprToken
-{
-
-public:
-
- char m_arith_symbol;
- char *m_token_name;
- RecDataT m_token_type;
- RecData m_token_value;
- RecData m_token_value_max;
- RecData m_token_value_min;
- StatDataSamples *m_token_value_delta;
- bool m_sum_var;
- bool m_node_var;
-
- // Member Functions
- void assignTokenName(const char *);
- bool assignTokenType();
- void print(const char *);
- short precedence();
- void copy(const StatExprToken &);
-
- LINK(StatExprToken, link);
- StatExprToken();
- inline ~ StatExprToken()
- {
- clean();
- };
- void clean();
-
- bool statVarSet(RecDataT, RecData);
-};
-
-
-/**
- * StatExprList
- * simply a list of StatExprToken.
- **/
-class StatExprList
-{
-
-public:
-
- StatExprList();
- inline ~ StatExprList()
- {
- clean();
- };
- void clean();
-
- void enqueue(StatExprToken *);
- void push(StatExprToken *);
- StatExprToken *dequeue();
- StatExprToken *pop();
- StatExprToken *top();
- StatExprToken *first();
- StatExprToken *next(StatExprToken *);
- unsigned count();
- void print(const char *);
-
-private:
-
- size_t m_size;
- Queue<StatExprToken> m_tokenList;
-};
-
-/***************************************************************
- * StatObject
- * Each entry in the statistics XML file is represented by a
- * StatObject.
- ***************************************************************/
-class StatObject
-{
-
-public:
-
- unsigned m_id;
- bool m_debug;
- char *m_expr_string; /* for debugging using only */
- StatExprToken *m_node_dest;
- StatExprToken *m_cluster_dest;
- StatExprList *m_expression;
- StatExprList *m_postfix;
- ink_hrtime m_last_update;
- ink_hrtime m_current_time;
- ink_hrtime m_update_interval;
- RecFloat m_stats_max;
- RecFloat m_stats_min;
- bool m_has_max;
- bool m_has_min;
- bool m_has_delta;
- LINK(StatObject, link);
-
- // Member functions
- StatObject();
- StatObject(unsigned);
- inline ~ StatObject()
- {
- clean();
- };
- void clean();
- void assignDst(const char *, bool, bool);
- void assignExpr(char *);
-
- StatExprToken *StatBinaryEval(StatExprToken *, char, StatExprToken *, bool cluster = false);
- RecData NodeStatEval(RecDataT *result_type, bool cluster);
- RecData ClusterStatEval(RecDataT *result_type);
- void setTokenValue(StatExprToken *, bool cluster = false);
-
-private:
-
- void infix2postfix();
-};
-
-
-/**
- * StatObjectList
- * simply a list of StatObject.
- **/
-class StatObjectList
-{
-
-public:
-
- // Member functions
- StatObjectList();
- inline ~ StatObjectList()
- {
- clean();
- };
- void clean();
- void enqueue(StatObject * object);
- StatObject *first();
- StatObject *next(StatObject * current);
- void print(const char *prefix = "");
- short Eval(); // return the number of statistics object processed
-
- size_t m_size;
-
-private:
-
- Queue<StatObject> m_statList;
-};
-
-#endif
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e6d233f/mgmt/stats/StatXML.cc
----------------------------------------------------------------------
diff --git a/mgmt/stats/StatXML.cc b/mgmt/stats/StatXML.cc
deleted file mode 100644
index 277b84a..0000000
--- a/mgmt/stats/StatXML.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-/** @file
-
- A brief file description
-
- @section license License
-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
-#include "ink_config.h"
-#include "StatXML.h"
-#include <stdlib.h>
-#include <ctype.h>
-
-//
-// Extract the text between a pair of XML tag and returns the length
-// of the extracted text.
-//
-unsigned short
-XML_extractContent(const char *name, char *content, size_t result_len)
-{
-
- char c;
- int contentIndex = 0;
-
- memset(content, 0, result_len);
- for (unsigned short nameIndex = 0; name[nameIndex] != '<'; nameIndex += 1) {
- c = name[nameIndex];
-
- if (isspace(c)) {
- continue;
- }
-
- if (isOperator(c)) {
- content[contentIndex++] = ' ';
- content[contentIndex++] = c;
- content[contentIndex++] = ' ';
- } else {
- content[contentIndex++] = c;
- }
- }
-
- return (strlen(content));
-
-}
-
-
-//
-// Returns true if 'c'is an operator (in our definition),
-// false otherwise
-//
-bool
-isOperator(char c)
-{
-
- switch (c) {
- case '+':
- case '-':
- case '*':
- case '/':
- case '(':
- case ')':
- return true;
- default:
- return false;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e6d233f/mgmt/stats/StatXML.h
----------------------------------------------------------------------
diff --git a/mgmt/stats/StatXML.h b/mgmt/stats/StatXML.h
deleted file mode 100644
index b31063b..0000000
--- a/mgmt/stats/StatXML.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/** @file
-
- A brief file description
-
- @section license License
-
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
-
-
-#ifndef _STATXML_H_
-#define _STATXML_H_
-
-#include "WebMgmtUtils.h"
-#include "List.h"
-
-typedef enum
-{
- INVALID_TAG = -1,
- ROOT_TAG,
- STAT_TAG,
- DST_TAG,
- EXPR_TAG
-} StatXMLTag;
-
-/***************************************************************
- * General Methods
- ***************************************************************/
-bool isOperator(char);
-int XML_getContent(const char *, int, char *, StatXMLTag);
-unsigned short XML_extractContent(const char *, char *, size_t);
-
-#endif
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9e6d233f/mgmt/stats/spec
----------------------------------------------------------------------
diff --git a/mgmt/stats/spec b/mgmt/stats/spec
deleted file mode 100644
index 97bdb90..0000000
--- a/mgmt/stats/spec
+++ /dev/null
@@ -1,236 +0,0 @@
-//-----------------------------------------------------------------------------
-//
-// Statistics Processor
-//
-// Last Update: 04/11/2001
-//
-//-----------------------------------------------------------------------------
-// -*- coding: utf-8 -*-
-//
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-//-----------------------------------------------------------------------------
-// Design
-//-----------------------------------------------------------------------------
-
-This statistics processor is a Cougar II (Tsunami) feature.
-It is designed to replace the StatAggregate.cc and portion of WebOverview.cc
-for scalability, maintainability, and ability to customize reasons.
-
-The statistics processor aggregate/calculate traffic server statistics based
-on a XML-based configuration file. At the processor's initialization, the
-configuration file is read and parsed. Each set of calculation is then stored
-as a C++ object, called StatObject; and each StatObject is linked into a list,
-called StatObjectList.
-
-The mgmt/traffic_manager threads will invoke the StatObjectList->Eval() to
-perform the statistics aggregation and calculation within its event loop. As
-Eval() is call, each StatObject in StatObjectList is evaluated.
-
-Recall: StatAggregate.cc aggregates/calculates/copies proxy.process.* TS
-variables to proxy.node.* variables. Similarly, WebOverview.cc aggregate
-proxy.node.* variables to their corresponding proxy.cluster.* variable.
-
-So there are two types of calculations in the statistics processor: NodeEval
-and ClusterEval. As their names imply, they aggregate node-based statistics
-and clsuter-based statistics, respectively. We call the different basis of
-statistics aggregation as "scope". (See "Destination Attributes")
-
-In the cluster-based statistics, the aggregation is further divided into two
-types: sum and re-calculate. Sum refers calculating the proxy.cluster.*
-variable by simply summing all required proxy.node.* variables from nodes in
-the cluster. Re-calculate refers to summing all proxy.nodes.* variables that
-are used in the process of calculation before performing the calculation.
-An analogy would be, summing all open connection in the cluster vs. the
-average hit rate in the cluster.
-
-//-----------------------------------------------------------------------------
-// Destination Attributes
-//-----------------------------------------------------------------------------
-
- "scope"
- - "node"
- - "cluster"
-
- "operation"
- - "sum"
- summing the corresponding node variable across all nodes in the cluster.
- - "re-calculate"
-
-
- "define"
- - "custom"
- - "built-in"
-
-//-----------------------------------------------------------------------------
-// Predefined Constants and Functions
-//-----------------------------------------------------------------------------
-
- Predefined Constants
-
- . BYTES_TO_MB_SCALE (1/(1024*1024.0))
- - convert bytes to mega-bytes
-
- . MBIT_TO_KBIT_SCALE (1000.0)
- - convert mega-bits to kilo-bits
-
- . SECOND_TO_MILLISECOND_SCALE (1000.0)
- - convert seconds to milliseconds
-
- . PCT_TO_INTPCT_SCALE (100.0)
- - convert ratios to percentage
-
- . HRTIME_SECOND
- - converting milli-seconds to seconds
-
- . BYTES_TO_MBIT_SCALE (8/1000000.0)
- - convert bytes to mega-bits
-
- Predefined Functions
- . DIFFTIME
- - the number of milliseconds since last update. Usually used in
- combination of HRTIME_SECOND which computes the number of seconds
- since last update.
-
-//-----------------------------------------------------------------------------
-// Unit test plan
-//-----------------------------------------------------------------------------
-
-The statistics processor is designed to replace StatAggregate.cc and part of
-the WebOverview. The first thing to test StatProcessor is to comment the
-aggregateNodeRecords() and doClusterAg() calls from mgmt/Main.cc.
-
-The next step is to replace the above function calls with StatProcessor::
-processStat().
-
-This statistics processor is a rather complicated module in traffic manager.
-Hence it can't be easily tested. We divided the test into multiple sections.
-
-1) Node-based Simple Aggregation
- - simply performs those aggregation that are node-based and the aggregation
- is performed every time statProcess() is invoked.
- E.g.: hit rate = doc. hit / doc. served.
-
-2) Node-based Time-Delta Aggregation
- - performs those aggregation that are node-based but the operation is only
- perform in a regular interval AND one of more variables in the
- calculation is obtained by calculating the difference between the last
- updated value and the current value. E.g. average connections per second
- is calculated by subtracting the 10 seconds ago connection count from the
- current connection count and divide the quotient by 10.
-
-Repeat the about 2 testes with cluster-based variables. So, we have, at least,
-4 test cases.
-
-Developing a PASS/FAIL unit test that will test the statistics processor is not
-cost-efficient. The approach we are going to use is to display the input value
-and the output value before and after the calculation is done.
-
-Let's subdivide the testes in two stages:
-
-Stage 1 : Synthetic Data
-------------------------
-We control the testing environment by setting the input values. This will test
-the correctness of the statistics processor in a controlled environment. PASS/
-FAIL is determined by matching the input/output values.
-
-Stage 2 : Load Data
--------------------
-Submitting network traffic through traffic server with load tools like jtest and
-ftest, dumps the statistics to a text file, periodically and examines the
-resulting values
-
-//-----------------------------------------------------------------------------
-// For QA Engineer
-//-----------------------------------------------------------------------------
-The most concerning question for QA engineers is "how can I tell if the
-Statistics Processor is working correctly?"
-
-Recall, the new Statistics Processor is meant to replace the StatAggregate.cc
-and part of the WebOverview.cc. In essence, you should not see any apparent
-change.
-
-If you ever see a value of -9999.0 (or -9999), then there is an error in
-computing that value.
-
-
-<expr>
- - %d
- - %f
- - %k
-
-<dst>
- - specifies the variable that stores that result value.
- - ATTRIBUTE: type
- built-in: variables that are built-in/defined in traffic server
- custom: variables that are introducted to be temporary storage or
- variables that are introdcuted by the client.
- - default attributes:
- type = built-in
-
-<src>
- - variable need to computer the <dst>
- - ATTRIBUTE: type
- node: this is a proxy.node.* variables
- cluster: the is a proxy.node.* variables but summing over all
- nodes in the cluster.
- - default attributes:
- type = node
-
-<min>
- - specifics what is the smallest possible value for <dst>. For values
- smaller than <min>, the <defualt> is used.
-
-<max>
- - specifics what is the largest possible value for <dst>. For values
- larger than <max>, the <defualt> is used.
-
-<default>
- - specifics what value to be assigned to <dst> is the result <dst>
- value is smaller then <min> or larger then <max>
-
-RULES: (some of these are enfored by the DTD anyways)
-- all operator and operand in <expr> MUST BE separated by a single space.
-- the order of the tags matters
-- the order of each entry matters
-- each statistics entry has have at most 1 <dst>
-
-
-DEFINED CONSTANT (in alphabetical order)
-* _BYTES_TO_MB_SCALE
- * Origin: utils/WebMgmtUtils.h
- * Value: (1/(1024*1024.0))
-
-* _HRTIME_SECOND
- * Origin:
- * Value:
-
-* _MBIT_TO_KBIT_SCALE
- * Origin: utils/WebMgmtUtils.h
- * Value: (1000.0);
-
-* _PCT_TO_INTPCT_SCALE
- * Origin: utils/WebMgmtUtils.h
- * Value: (100.0);
-
-* _SECOND_TO_MILLISECOND_SCALE
- * Origin: utils/WebMgmtUtils.h
- * Value: (1000.0);
-
-
- __DIFFTIME