mirror of
https://github.com/nginx/nginx.git
synced 2026-09-03 20:53:04 -05:00
Control API.
A new nginx option -l specifies control socket listen address.
The socket is providing an HTTP/1 REST API for retrieving information
about running nginx instance.
Example:
$ nginx -l 127.0.0.1:1234
$ curl 127.0.0.1:1234/1/control/processes | jq
[
{
"pid": 41536,
"name": "worker process",
"exiting": false
}
]
Co-authored-by: Roman Arutyunyan <arut@nginx.com>
Co-authored-by: Pavel Pautov <p.pautov@f5.com>
Co-authored-by: Dmitry Plotnikov <d.plotnikov@f5.com>
Co-authored-by: Sergey Kandaurov <pluknet@nginx.com>
Co-authored-by: Ivan Ovchinnikov <i.ovchinnikov@f5.com>
This commit is contained in:
committed by
Ava Hahn
co-authored by
Roman Arutyunyan
Pavel Pautov
Dmitry Plotnikov
Sergey Kandaurov
Ivan Ovchinnikov
parent
032e181dad
commit
4bc459a15c
@@ -56,6 +56,23 @@ if [ $NGX_TEST_BUILD_SOLARIS_SENDFILEV = YES ]; then
|
||||
fi
|
||||
|
||||
|
||||
if [ $CONTROL_API = YES ]; then
|
||||
|
||||
if [ "$NGX_PLATFORM" = win32 ]; then
|
||||
cat << END
|
||||
|
||||
$0: --with-control-api is not supported on Windows
|
||||
|
||||
END
|
||||
exit 1
|
||||
fi
|
||||
|
||||
have=NGX_CONTROL_API . auto/have
|
||||
CORE_DEPS="$CORE_DEPS $UNIX_CONTROL_API_DEPS"
|
||||
CORE_SRCS="$CORE_SRCS $UNIX_CONTROL_API_SRCS"
|
||||
fi
|
||||
|
||||
|
||||
if [ $HTTP = YES ]; then
|
||||
HTTP_MODULES=
|
||||
HTTP_DEPS=
|
||||
|
||||
@@ -41,6 +41,8 @@ EVENT_FOUND=NO
|
||||
EVENT_SELECT=NO
|
||||
EVENT_POLL=NO
|
||||
|
||||
CONTROL_API=NO
|
||||
|
||||
USE_THREADS=NO
|
||||
|
||||
NGX_FILE_AIO=NO
|
||||
@@ -225,6 +227,8 @@ do
|
||||
|
||||
--without-quic_bpf_module) QUIC_BPF=NONE ;;
|
||||
|
||||
--with-control-api) CONTROL_API=YES ;;
|
||||
|
||||
--with-ipv6)
|
||||
NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG
|
||||
$0: warning: the \"--with-ipv6\" option is deprecated"
|
||||
@@ -468,6 +472,8 @@ cat << END
|
||||
--with-poll_module enable poll module
|
||||
--without-poll_module disable poll module
|
||||
|
||||
--with-control-api enable control API
|
||||
|
||||
--with-threads enable thread pool support
|
||||
|
||||
--with-file-aio enable file AIO support
|
||||
|
||||
@@ -192,6 +192,9 @@ UNIX_SRCS="$CORE_SRCS $EVENT_SRCS \
|
||||
src/os/unix/ngx_dlopen.c \
|
||||
src/os/unix/ngx_process_cycle.c"
|
||||
|
||||
UNIX_CONTROL_API_DEPS=src/os/unix/ngx_control.h
|
||||
UNIX_CONTROL_API_SRCS=src/os/unix/ngx_control.c
|
||||
|
||||
POSIX_DEPS=src/os/unix/ngx_posix_config.h
|
||||
|
||||
THREAD_POOL_MODULE=ngx_thread_pool_module
|
||||
|
||||
+43
-1
@@ -187,6 +187,9 @@ static u_char *ngx_prefix;
|
||||
static u_char *ngx_error_log;
|
||||
static u_char *ngx_conf_file;
|
||||
static u_char *ngx_conf_params;
|
||||
#if (NGX_CONTROL_API)
|
||||
static u_char *ngx_control_addr;
|
||||
#endif
|
||||
static char *ngx_signal;
|
||||
|
||||
|
||||
@@ -360,6 +363,18 @@ main(int argc, char *const *argv)
|
||||
|
||||
#endif
|
||||
|
||||
#if (NGX_CONTROL_API)
|
||||
if (ngx_process == NGX_PROCESS_SINGLE) {
|
||||
ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
|
||||
"control API unavailable in single process mode");
|
||||
|
||||
} else {
|
||||
if (ngx_control_init(ngx_control_addr) != NGX_OK) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
|
||||
return 1;
|
||||
}
|
||||
@@ -410,6 +425,9 @@ ngx_show_version_info(void)
|
||||
"during configuration testing" NGX_LINEFEED
|
||||
" -s signal : send signal to a master process: "
|
||||
"stop, quit, reopen, reload" NGX_LINEFEED
|
||||
#if (NGX_CONTROL_API)
|
||||
" -l addr : open control socket on address" NGX_LINEFEED
|
||||
#endif
|
||||
#ifdef NGX_PREFIX
|
||||
" -p prefix : set prefix path (default: " NGX_PREFIX ")"
|
||||
NGX_LINEFEED
|
||||
@@ -711,7 +729,7 @@ ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv)
|
||||
ctx.name = "new binary process";
|
||||
ctx.argv = argv;
|
||||
|
||||
n = 2;
|
||||
n = 3;
|
||||
env = ngx_set_environment(cycle, &n);
|
||||
if (env == NULL) {
|
||||
return NGX_INVALID_PID;
|
||||
@@ -751,6 +769,14 @@ ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv)
|
||||
|
||||
#endif
|
||||
|
||||
#if (NGX_CONTROL_API)
|
||||
env[n] = ngx_control_handoff();
|
||||
|
||||
if (env[n] != NULL) {
|
||||
n++;
|
||||
}
|
||||
#endif
|
||||
|
||||
env[n] = NULL;
|
||||
|
||||
#if (NGX_DEBUG)
|
||||
@@ -929,6 +955,22 @@ ngx_get_options(int argc, char *const *argv)
|
||||
ngx_log_stderr(0, "invalid option: \"-s %s\"", ngx_signal);
|
||||
return NGX_ERROR;
|
||||
|
||||
#if (NGX_CONTROL_API)
|
||||
case 'l':
|
||||
if (*p) {
|
||||
ngx_control_addr = p;
|
||||
goto next;
|
||||
}
|
||||
|
||||
if (argv[++i]) {
|
||||
ngx_control_addr = (u_char *) argv[i];
|
||||
goto next;
|
||||
}
|
||||
|
||||
ngx_log_stderr(0, "option \"-l\" requires listen address");
|
||||
return NGX_ERROR;
|
||||
#endif
|
||||
|
||||
default:
|
||||
ngx_log_stderr(0, "invalid option: \"%c\"", *(p - 1));
|
||||
return NGX_ERROR;
|
||||
|
||||
@@ -92,6 +92,9 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c);
|
||||
#endif
|
||||
#endif
|
||||
#include <ngx_process_cycle.h>
|
||||
#if (NGX_CONTROL_API)
|
||||
#include <ngx_control.h>
|
||||
#endif
|
||||
#include <ngx_conf_file.h>
|
||||
#include <ngx_module.h>
|
||||
#include <ngx_open_file_cache.h>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,26 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) Nginx, Inc.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _NGX_CONTROL_H_INCLUDED_
|
||||
#define _NGX_CONTROL_H_INCLUDED_
|
||||
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
|
||||
|
||||
ngx_int_t ngx_control_init(u_char *addr);
|
||||
void ngx_control_uninit(void);
|
||||
void ngx_control_close_sockets(void);
|
||||
char *ngx_control_handoff(void);
|
||||
void ngx_control_reown(void);
|
||||
ngx_int_t ngx_control_handle_events(void);
|
||||
|
||||
|
||||
extern ngx_uint_t ngx_control_api_enabled;
|
||||
|
||||
|
||||
#endif /* _NGX_CONTROL_H_INCLUDED_ */
|
||||
@@ -174,6 +174,14 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
|
||||
live = ngx_reap_children(cycle);
|
||||
}
|
||||
|
||||
#if (NGX_CONTROL_API)
|
||||
if (ngx_sigio) {
|
||||
ngx_sigio = 0;
|
||||
|
||||
ngx_control_handle_events();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!live && (ngx_terminate || ngx_quit)) {
|
||||
ngx_master_process_exit(cycle);
|
||||
}
|
||||
@@ -629,6 +637,10 @@ ngx_reap_children(ngx_cycle_t *cycle)
|
||||
ccf->oldpid.data, ccf->pid.data, ngx_argv[0]);
|
||||
}
|
||||
|
||||
#if (NGX_CONTROL_API)
|
||||
ngx_control_reown();
|
||||
#endif
|
||||
|
||||
ngx_new_binary = 0;
|
||||
if (ngx_noaccepting) {
|
||||
ngx_restart = 1;
|
||||
@@ -669,6 +681,10 @@ ngx_master_process_exit(ngx_cycle_t *cycle)
|
||||
|
||||
ngx_close_listening_sockets(cycle);
|
||||
|
||||
#if (NGX_CONTROL_API)
|
||||
ngx_control_uninit();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copy ngx_cycle->log related data to the special static exit cycle,
|
||||
* log, and log file structures enough to allow a signal handler to log.
|
||||
@@ -760,6 +776,10 @@ ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker)
|
||||
struct rlimit rlmt;
|
||||
ngx_core_conf_t *ccf;
|
||||
|
||||
#if (NGX_CONTROL_API)
|
||||
ngx_control_close_sockets();
|
||||
#endif
|
||||
|
||||
if (ngx_set_environment(cycle, NULL) == NULL) {
|
||||
/* fatal */
|
||||
exit(2);
|
||||
|
||||
Reference in New Issue
Block a user