mirror of
https://codeberg.org/redict/redict.git
synced 2025-01-23 16:48:27 -05:00
94 lines
3.9 KiB
C
94 lines
3.9 KiB
C
|
/* The latency monitor allows to easily observe the sources of latency
|
||
|
* in a Redis instance using the LATENCY command. Different latency
|
||
|
* sources are monitored, like disk I/O, execution of commands, fork
|
||
|
* system call, and so forth.
|
||
|
*
|
||
|
* ----------------------------------------------------------------------------
|
||
|
*
|
||
|
* Copyright (c) 2014, Salvatore Sanfilippo <antirez at gmail dot com>
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms, with or without
|
||
|
* modification, are permitted provided that the following conditions are met:
|
||
|
*
|
||
|
* * Redistributions of source code must retain the above copyright notice,
|
||
|
* this list of conditions and the following disclaimer.
|
||
|
* * Redistributions in binary form must reproduce the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer in the
|
||
|
* documentation and/or other materials provided with the distribution.
|
||
|
* * Neither the name of Redis nor the names of its contributors may be used
|
||
|
* to endorse or promote products derived from this software without
|
||
|
* specific prior written permission.
|
||
|
*
|
||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||
|
*/
|
||
|
|
||
|
#include "redis.h"
|
||
|
|
||
|
/* Dictionary type for latency events. Key/Val destructors are set to NULL
|
||
|
* since we never delete latency time series at runtime. */
|
||
|
int dictStringKeyCompare(void *privdata, const void *key1, const void *key2) {
|
||
|
return strcmp(key1,key2) == 0;
|
||
|
}
|
||
|
|
||
|
unsigned int dictStringHash(const void *key) {
|
||
|
return dictGenHashFunction(key, strlen(key));
|
||
|
}
|
||
|
|
||
|
dictType latencyTimeSeriesDictType = {
|
||
|
dictStringHash, /* hash function */
|
||
|
NULL, /* key dup */
|
||
|
NULL, /* val dup */
|
||
|
dictStringKeyCompare, /* key compare */
|
||
|
NULL, /* key destructor */
|
||
|
NULL /* val destructor */
|
||
|
};
|
||
|
|
||
|
/* ---------------------------- Latency API --------------------------------- */
|
||
|
|
||
|
/* Latency monitor initialization. We just need to create the dictionary
|
||
|
* of time series, each time serie is craeted on demand in order to avoid
|
||
|
* having a fixed list to maintain. */
|
||
|
void latencyMonitorInit(void) {
|
||
|
server.latency_events = dictCreate(&latencyTimeSeriesDictType,NULL);
|
||
|
}
|
||
|
|
||
|
/* Add the specified sample to the specified time series "event".
|
||
|
* This function is usually called via latencyAddSampleIfNeeded(), that
|
||
|
* is a macro that only adds the sample if the latency is higher than
|
||
|
* server.latency_monitor_threshold. */
|
||
|
void latencyAddSample(char *event, mstime_t latency) {
|
||
|
struct latencyTimeSeries *ts = dictFetchValue(server.latency_events,event);
|
||
|
|
||
|
/* Create the time series if it does not exist. */
|
||
|
if (ts == NULL) {
|
||
|
ts = zmalloc(sizeof(*ts));
|
||
|
ts->idx = 0;
|
||
|
ts->max = 0;
|
||
|
memset(ts->samples,0,sizeof(ts->samples));
|
||
|
dictAdd(server.latency_events,zstrdup(event),ts);
|
||
|
}
|
||
|
|
||
|
ts->samples[ts->idx].time = time(NULL);
|
||
|
ts->samples[ts->idx].latency = latency;
|
||
|
if (latency > ts->max) ts->max = latency;
|
||
|
|
||
|
ts->idx++;
|
||
|
if (ts->idx == LATENCY_TS_LEN) ts->idx = 0;
|
||
|
}
|
||
|
|
||
|
/* ---------------------- Latency command implementation -------------------- */
|
||
|
|
||
|
void latencyCommand(redisClient *c) {
|
||
|
}
|