Add listeners info string for 'INFO' command

Suggested by Oran, add necessary listeners information in 'INFO'
command. It would be helpful for debug.

Example of this:
127.0.0.1:6379> INFO SERVER
redis_version:255.255.255
...
listener0:name=tcp,bind=127.0.0.1,port=6380
listener1:name=unix,bind=/run/redis.sock
listener2:name=tls,bind=127.0.0.1,port=6379
...

Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
This commit is contained in:
zhenwei pi 2022-08-22 10:53:30 +08:00
parent 0b27cfe37d
commit 0c4d2fcc8e
3 changed files with 32 additions and 7 deletions

View File

@ -183,3 +183,22 @@ int connTypeProcessPendingData(void) {
return ret; return ret;
} }
sds getListensInfoString(sds info) {
for (int j = 0; j < CONN_TYPE_MAX; j++) {
connListener *listener = &server.listeners[j];
if (listener->ct == NULL)
continue;
info = sdscatfmt(info, "listener%i:name=%s", j, listener->ct->get_type(NULL));
for (int i = 0; i < listener->count; i++) {
info = sdscatfmt(info, ",bind=%s", listener->bindaddr[i]);
}
if (listener->port)
info = sdscatfmt(info, ",port=%i", listener->port);
info = sdscatfmt(info, "\r\n");
}
return info;
}

View File

@ -275,7 +275,7 @@ static inline int connLastErrorRetryable(connection *conn) {
} }
/* Get address information of a connection. /* Get address information of a connection.
* @remote works as boolean type to get local/remote address */ * remote works as boolean type to get local/remote address */
static inline int connAddr(connection *conn, char *ip, size_t ip_len, int *port, int remote) { static inline int connAddr(connection *conn, char *ip, size_t ip_len, int *port, int remote) {
if (conn && conn->type->addr) { if (conn && conn->type->addr) {
return conn->type->addr(conn, ip, ip_len, port, remote); return conn->type->addr(conn, ip, ip_len, port, remote);
@ -287,8 +287,8 @@ static inline int connAddr(connection *conn, char *ip, size_t ip_len, int *port,
/* Format an IP,port pair into something easy to parse. If IP is IPv6 /* Format an IP,port pair into something easy to parse. If IP is IPv6
* (matches for ":"), the ip is surrounded by []. IP and port are just * (matches for ":"), the ip is surrounded by []. IP and port are just
* separated by colons. This the standard to display addresses within Redis. */ * separated by colons. This the standard to display addresses within Redis. */
static inline int formatAddr(char *buf, size_t buf_len, char *ip, int port) { static inline int formatAddr(char *buf, size_t buf_len, char *ip, int port) {
return snprintf(buf,buf_len, strchr(ip,':') ? return snprintf(buf, buf_len, strchr(ip,':') ?
"[%s]:%d" : "%s:%d", ip, port); "[%s]:%d" : "%s:%d", ip, port);
} }
@ -400,19 +400,19 @@ static inline connection *connCreate(ConnectionType *ct) {
} }
/* Create a accepted connection of specified type. /* Create a accepted connection of specified type.
* @priv is connection type specified argument */ * priv is connection type specified argument */
static inline connection *connCreateAccepted(ConnectionType *ct, int fd, void *priv) { static inline connection *connCreateAccepted(ConnectionType *ct, int fd, void *priv) {
return ct->conn_create_accepted(fd, priv); return ct->conn_create_accepted(fd, priv);
} }
/* Configure a connection type. A typical case is to configure TLS. /* Configure a connection type. A typical case is to configure TLS.
* @priv is connection type specified, * priv is connection type specified,
* @reconfigure is boolean type to specify if overwrite the original config */ * reconfigure is boolean type to specify if overwrite the original config */
static inline int connTypeConfigure(ConnectionType *ct, void *priv, int reconfigure) { static inline int connTypeConfigure(ConnectionType *ct, void *priv, int reconfigure) {
return ct->configure(priv, reconfigure); return ct->configure(priv, reconfigure);
} }
/* Walk all the connection type, and cleanup them all if possible */ /* Walk all the connection types and cleanup them all if possible */
void connTypeCleanupAll(); void connTypeCleanupAll();
/* Test all the connection type has pending data or not. */ /* Test all the connection type has pending data or not. */
@ -433,6 +433,9 @@ static inline aeFileProc *connAcceptHandler(ConnectionType *ct) {
return NULL; return NULL;
} }
/* Get Listeners information, note that caller should free the non-empty string */
sds getListensInfoString(sds info);
int RedisRegisterConnectionTypeSocket(); int RedisRegisterConnectionTypeSocket();
int RedisRegisterConnectionTypeUnix(); int RedisRegisterConnectionTypeUnix();
int RedisRegisterConnectionTypeTLS(); int RedisRegisterConnectionTypeTLS();

View File

@ -5426,6 +5426,9 @@ sds genRedisInfoString(dict *section_dict, int all_sections, int everything) {
"shutdown_in_milliseconds:%I\r\n", "shutdown_in_milliseconds:%I\r\n",
(int64_t)(server.shutdown_mstime - server.mstime)); (int64_t)(server.shutdown_mstime - server.mstime));
} }
/* get all the listeners information */
info = getListensInfoString(info);
} }
/* Clients */ /* Clients */