Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 8 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ Nginx module developed for logging and displaying statistic of websocket proxy c

## Installation

1. Configure nginx adding this module with:
1. Configure nginx adding this module with or build this module as a dynamic module:
```sh
./configure (...) --add-module=./ngx_http_websocket_stat_module
# or
./configure (...) --add-dynamic-module=./ngx_http_websocket_stat_module && make modules
```
2. Build nginx with make -j<n> command where n is number of cpu cores on your build machine

Expand All @@ -22,9 +24,10 @@ Nginx module developed for logging and displaying statistic of websocket proxy c

## Usage

To enable websocket logging specify log file in server section of nginx config file with ws_log directibe.
To enable websocket frames logging specify `log_enabled on` and `ws_log_format` in server section of nginx config file. Additionally, specify `ws_log` to override the log file, which is used to log ws frames.

You can specify your own websocket log format using ws_log_format directive in server section. To customize connection open and close log messages use "open" and "close" parameter for ws_log_format directive.
To customize connection open and close log messages use "open" and "close" parameter for ws_log_format directive.
To log only when the full message is received/sent use "message" parameter for ws_log_format directive.

Maximum number of concurrent websocket connections could be specified with ws_max_connections on server section. This value applies to whole connections that are on nginx. Argument should be integer representing maximum connections. When client tries to open more connections it recevies close framee with 1013 error code and connection is closed on nginx side. If zero number of connections is given there would be no limit on websocket connections.

Expand All @@ -34,7 +37,8 @@ To set maximum single connection lifetime use ws_conn_age parameter. Argument is
Here is a list of variables you can use in log format string:

* $ws_opcode - websocket packet opcode. Look into https://tools.ietf.org/html/rfc6455 Section 5.2, Base Framing Protocol.
* $ws_payload_size - Websocket packet size without protocol specific data. Only data that been sent or received by the client
* $ws_payload_size - Size of the WS frame without protocol specific data. Only data that been sent or received by the client
* $ws_message_size - Size of the WS message without protocol specific data. Only data that been sent or received by the client
* $ws_packet_source - Could be "client" if packet has been sent by the user or "upstream" if it has been received from the server
* $ws_conn_age - Number of seconds connection is alive
* $time_local - Nginx local time, date and timezone
Expand All @@ -48,8 +52,6 @@ Here is a list of variables you can use in log format string:
* $server_port - Server's port
* $upstream_addr - websocket backend address

To read websocket statistic there is GET request should be set up at "location" location of nginx config file with ws_stat command in it. Look into example section for details.

## Example of configuration

```
Expand All @@ -62,10 +64,6 @@ server
ws_log_format close "$time_local: Connection closed";
ws_max_connections 200;
ws_conn_age 12h;
# set up location for statistic
location /websocket_status {
ws_stat;
}
...
}

Expand Down
21 changes: 15 additions & 6 deletions config
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
ngx_addon_name=ngx_http_websocket_stat_module

ngx_module_type=HTTP
ngx_module_name=ngx_http_websocket_stat_module
ngx_module_srcs="$ngx_addon_dir/ngx_http_websocket_stat_module.c \
$ngx_addon_dir/ngx_http_websocket_stat_format.c \
$ngx_addon_dir/ngx_http_websocket_stat_frame_counter.c"
. auto/module
if test -n "$ngx_module_link"; then
ngx_module_type=HTTP
ngx_module_name=ngx_http_websocket_stat_module
ngx_module_srcs="$ngx_addon_dir/ngx_http_websocket_stat_module.c \
$ngx_addon_dir/ngx_http_websocket_stat_format.c \
$ngx_addon_dir/ngx_http_websocket_stat_frame_counter.c"
. auto/module
else
HTTP_MODULES="$HTTP_MODULES ngx_http_websocket_stat_module"
HTTP_AUX_FILTER_MODULES="$HTTP_AUX_FILTER_MODULES ngx_http_websocket_stat_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS \
$ngx_addon_dir/ngx_http_websocket_stat_module.c \
$ngx_addon_dir/ngx_http_websocket_stat_format.c \
$ngx_addon_dir/ngx_http_websocket_stat_frame_counter.c"
fi
7 changes: 7 additions & 0 deletions ngx_http_websocket_stat_frame_counter.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ frame_counter_process_message(u_char **buffer, ssize_t *size,
switch (frame_counter->stage) {
case HEADER:
frame_counter->current_frame_type = **buffer & 0x0f;
frame_counter->fragment_final = **buffer >> 7;

if (frame_counter->current_frame_type != CONTINUATION) {
frame_counter->current_message_size = 0;
}

move_buffer(buffer, size, 1);
frame_counter->stage = PAYLOAD_LEN;
frame_counter->bytes_consumed =
Expand Down Expand Up @@ -102,6 +108,7 @@ frame_counter_process_message(u_char **buffer, ssize_t *size,
}
break;
case PAYLOAD:
frame_counter->current_message_size += *size;
if (*size >= (u_int)(frame_counter->current_payload_size -
frame_counter->bytes_consumed)) {
move_buffer(buffer, size,
Expand Down
5 changes: 3 additions & 2 deletions ngx_http_websocket_stat_frame_counter.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@ typedef enum { CONTINUATION, TEXT, BINARY, CLOSE = 8, PING, PONG } frame_type;

// Structure representing frame statistic and parsing stage
typedef struct {
ngx_int_t total_payload_size;
ngx_int_t current_message_size;

// private fields representing current parcing stage
// private fields representing current parsing stage
ngx_int_t bytes_consumed;
packet_reading_stage stage;
char payload_masked : 1;
char fragment_final : 1;
frame_type current_frame_type;
ngx_int_t current_payload_size;
} ngx_frame_counter_t;
Expand Down
Loading