Skip to content

Commit 58cd6be

Browse files
committed
FEATURE: Add stats_tcp_retrans()
1 parent 9a95d2e commit 58cd6be

File tree

7 files changed

+174
-1
lines changed

7 files changed

+174
-1
lines changed

Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ memcached_SOURCES = \
8181
sasl_defs.h \
8282
stats_prefix.c \
8383
stats_prefix.h \
84+
stats.c \
85+
stats.h \
8486
thread.c \
8587
thread.h \
8688
mc_util.c \

include/memcached/types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ struct iovec {
4040
#define SUPPORT_BOP_SMGET
4141
#define JHPARK_OLD_SMGET_INTERFACE
4242
#define MULTI_NOTIFY_IO_COMPLETE
43+
#define STATS_TCP_RETRANS
4344

4445
#ifdef __cplusplus
4546
extern "C" {

memcached.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8092,6 +8092,11 @@ static void server_stats(ADD_STAT add_stats, conn *c, bool aggregate)
80928092
APPEND_STAT("limit_maxconns", "%d", settings.maxconns);
80938093
APPEND_STAT("threads", "%d", settings.num_threads);
80948094
APPEND_STAT("conn_yields", "%"PRIu64, thread_stats.conn_yields);
8095+
#ifdef STATS_TCP_RETRANS
8096+
if (IS_TCP(c->transport)) {
8097+
APPEND_STAT("tcp_retrans", "%ld", stats_tcp_retrans());
8098+
}
8099+
#endif
80958100
UNLOCK_STATS();
80968101
}
80978102

memcached.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ enum network_transport {
190190
udp_transport
191191
};
192192

193+
#define IS_TCP(x) (x == tcp_transport)
194+
193195
#define IS_UDP(x) (x == udp_transport)
194196

195197
/**
@@ -575,6 +577,7 @@ extern int daemonize(int nochdir, int noclose);
575577
#endif
576578

577579
#include "stats_prefix.h"
580+
#include "stats.h"
578581
#include "trace.h"
579582
#include "hash.h"
580583
#include <memcached/util.h>

stats.c

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2+
/*
3+
* arcus-memcached - Arcus memory cache server
4+
* Copyright 2010-2014 NAVER Corp.
5+
* Copyright 2015 JaM2in Co., Ltd.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
/*
20+
* Detailed statistics management. For simple stats like total number of
21+
* "get" requests, we use inline code in memcached.c and friends, but when
22+
* stats detail mode is activated, the code here records more information.
23+
*
24+
* Author:
25+
* Steven Grimm <[email protected]>
26+
*/
27+
#include "config.h"
28+
#include "memcached.h"
29+
30+
#ifdef STATS_TCP_RETRANS
31+
#include <ctype.h>
32+
#include <stdlib.h>
33+
#include <string.h>
34+
35+
static void rtrim(char **src) {
36+
if (src == NULL || *src == NULL || strlen(*src) == 0) {
37+
return;
38+
}
39+
40+
char *str = *src;
41+
for (int i = strlen(str) - 1; i >= 0; i--) {
42+
if (!isspace(str[i])) {
43+
break;
44+
}
45+
46+
str[i] = '\0';
47+
}
48+
49+
*src = str;
50+
}
51+
52+
int64_t stats_tcp_retrans(void) {
53+
char *key_line = NULL;
54+
char *value_line = NULL;
55+
int64_t tcp_retrans = -1;
56+
57+
FILE *fp = fopen("/proc/net/snmp", "r");
58+
if (fp == NULL) {
59+
goto done;
60+
}
61+
62+
size_t key_len = 0;
63+
size_t value_len = 0;
64+
ssize_t key_read = -1;
65+
ssize_t value_read = -1;
66+
67+
char *prefix = "Tcp:";
68+
size_t prefix_len = strlen(prefix);
69+
70+
while ((key_read = getline(&key_line, &key_len, fp)) != -1) {
71+
if (strncmp(prefix, key_line, prefix_len) != 0) {
72+
continue;
73+
}
74+
75+
if ((value_read = getline(&value_line, &value_len, fp)) != -1) {
76+
break;
77+
}
78+
}
79+
80+
if (key_read < 0 || value_read < 0) {
81+
goto done;
82+
}
83+
84+
/*
85+
* below lines are examples of key_line and value_line.
86+
* for examples below, tcp_retrans = 9814784
87+
*
88+
* Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs InErrs OutRsts InCsumErrors
89+
* Tcp: 1 200 120000 -1 231273424 45758374 43975115 12045288 360 9853401239 10104984649 9814784 12765 17318799 883
90+
*/
91+
92+
char *delimiter = " ";
93+
char *retrans_segs = "RetransSegs";
94+
95+
char *key_next = NULL;
96+
char *value_next = NULL;
97+
98+
char *key_token = strtok_r(key_line, delimiter, &key_next);
99+
char *value_token = strtok_r(value_line, delimiter, &value_next);
100+
101+
// first token is always "Tcp:"
102+
key_token = strtok_r(NULL, delimiter, &key_next);
103+
value_token = strtok_r(NULL, delimiter, &value_next);
104+
105+
while (key_token && value_token) {
106+
// last token always ends with "\n"
107+
rtrim(&key_token);
108+
rtrim(&value_token);
109+
110+
if (strcmp(key_token, retrans_segs) == 0) {
111+
char *end = NULL;
112+
errno = 0;
113+
tcp_retrans = strtoll(value_token, &end, 10);
114+
115+
if (errno > 0 || *end != '\0') {
116+
tcp_retrans = -1;
117+
}
118+
goto done;
119+
}
120+
121+
key_token = strtok_r(NULL, delimiter, &key_next);
122+
value_token = strtok_r(NULL, delimiter, &value_next);
123+
}
124+
125+
done:
126+
if (fp != NULL) {
127+
fclose(fp);
128+
}
129+
130+
if (key_line != NULL) {
131+
free(key_line);
132+
}
133+
134+
if (value_line != NULL) {
135+
free(value_line);
136+
}
137+
138+
return tcp_retrans;
139+
}
140+
#endif

stats.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* arcus-memcached - Arcus memory cache server
3+
* Copyright 2010-2014 NAVER Corp.
4+
* Copyright 2015 JaM2in Co., Ltd.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
/* stats */
19+
20+
#ifdef STATS_TCP_RETRANS
21+
int64_t stats_tcp_retrans(void);
22+
#endif

stats_prefix.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* See the License for the specific language governing permissions and
1616
* limitations under the License.
1717
*/
18-
/* stats */
18+
/* stats_prefix */
1919
void stats_prefix_init(char delimiter, void (*cb_when_prefix_overflow)(void));
2020
void stats_prefix_clear(void);
2121
int stats_prefix_count(void);

0 commit comments

Comments
 (0)