static void stat_add(char *name, TSMgmtInt amount, TSStatPersistence persist_type, TSMutex create_mutex) { int stat_id = -1; ENTRY search, *result = NULL; static __thread struct hsearch_data stat_cache; static __thread bool hash_init = false; if (unlikely(!hash_init)) { hcreate_r(TS_MAX_API_STATS << 1, &stat_cache); hash_init = true; TSDebug(DEBUG_TAG, "stat cache hash init"); } search.key = name; search.data = 0; hsearch_r(search, FIND, &result, &stat_cache); if (unlikely(result == NULL)) { // This is an unlikely path because we most likely have the stat cached // so this mutex won't be much overhead and it fixes a race condition // in the RecCore. Hopefully this can be removed in the future. TSMutexLock(create_mutex); if (TS_ERROR == TSStatFindName((const char *)name, &stat_id)) { stat_id = TSStatCreate((const char *)name, TS_RECORDDATATYPE_INT, persist_type, TS_STAT_SYNC_SUM); if (stat_id == TS_ERROR) { TSDebug(DEBUG_TAG, "Error creating stat_name: %s", name); } else { TSDebug(DEBUG_TAG, "Created stat_name: %s stat_id: %d", name, stat_id); } } TSMutexUnlock(create_mutex); if (stat_id >= 0) { search.key = TSstrdup(name); search.data = (void *)((intptr_t)stat_id); hsearch_r(search, ENTER, &result, &stat_cache); TSDebug(DEBUG_TAG, "Cached stat_name: %s stat_id: %d", name, stat_id); } } else { stat_id = (int)((intptr_t)result->data); } if (likely(stat_id >= 0)) { TSStatIntIncrement(stat_id, amount); } else { TSDebug(DEBUG_TAG, "stat error! stat_name: %s stat_id: %d", name, stat_id); } }
void init_stats(void) { /* noncoupled: */ redirect_count_connect = TSStatCreate(STAT_PREFIX "count.connect", TS_RECORDDATATYPE_INT, TS_STAT_NON_PERSISTENT, TS_STAT_SYNC_SUM); redirect_count_delete = TSStatCreate(STAT_PREFIX "count.delete", TS_RECORDDATATYPE_INT, TS_STAT_NON_PERSISTENT, TS_STAT_SYNC_SUM); redirect_count_get = TSStatCreate(STAT_PREFIX "count.get", TS_RECORDDATATYPE_INT, TS_STAT_NON_PERSISTENT, TS_STAT_SYNC_SUM); redirect_count_head = TSStatCreate(STAT_PREFIX "count.head", TS_RECORDDATATYPE_INT, TS_STAT_NON_PERSISTENT, TS_STAT_SYNC_SUM); redirect_count_options = TSStatCreate(STAT_PREFIX "count.options", TS_RECORDDATATYPE_INT, TS_STAT_NON_PERSISTENT, TS_STAT_SYNC_SUM); redirect_count_post = TSStatCreate(STAT_PREFIX "count.post", TS_RECORDDATATYPE_INT, TS_STAT_NON_PERSISTENT, TS_STAT_SYNC_SUM); redirect_count_purge = TSStatCreate(STAT_PREFIX "count.purge", TS_RECORDDATATYPE_INT, TS_STAT_NON_PERSISTENT, TS_STAT_SYNC_SUM); redirect_count_put = TSStatCreate(STAT_PREFIX "count.put", TS_RECORDDATATYPE_INT, TS_STAT_NON_PERSISTENT, TS_STAT_SYNC_SUM); redirect_count_trace = TSStatCreate(STAT_PREFIX "count.trace", TS_RECORDDATATYPE_INT, TS_STAT_NON_PERSISTENT, TS_STAT_SYNC_SUM); redirect_count_unknown = TSStatCreate(STAT_PREFIX "count.unknown", TS_RECORDDATATYPE_INT, TS_STAT_NON_PERSISTENT, TS_STAT_SYNC_SUM); requests_redirects = TSStatCreate(STAT_PREFIX "total.redirects", TS_RECORDDATATYPE_INT, TS_STAT_NON_PERSISTENT, TS_STAT_SYNC_SUM); requests_unchanged = TSStatCreate(STAT_PREFIX "total.unchanged", TS_RECORDDATATYPE_INT, TS_STAT_NON_PERSISTENT, TS_STAT_SYNC_SUM); }