From 80bee73e488408faa0aa5801c9dc71f2c154b1a5 Mon Sep 17 00:00:00 2001 From: Roman Chukov Date: Thu, 9 Apr 2026 17:36:26 +0300 Subject: [PATCH] Allow using full hostname with eligible subdomain delimiter as a partof metric prefix --- README.md | 32 +++++++++++++++------------- src/ngx_http_graphite_module.c | 39 +++++++++++++++++++++++++++++++--- src/ngx_http_graphite_module.h | 2 ++ 3 files changed, 55 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 6f2780c..5ec8aec 100644 --- a/README.md +++ b/README.md @@ -56,21 +56,23 @@ Directives Specify global settings for a whole server instance. -Param | Required | Default | Description ---------- | -------- | ------------- | ----------- -prefix | | | path prefix for all graphs -host | | gethostname() | host name for all graphs -server | Yes | | carbon-cache server IP address -protocol | | udp | carbon-cache server protocol (udp or tcp) -port | | 2003 | carbon-cache server port -frequency | | 60 | how often send values to Graphite (seconds) -intervals | | 1m | aggregation intervals, time interval list, vertical bar separator (`m` - minutes) -params | | * | limit metrics list to track, vertical bar separator -shared | | 2m | shared memory size, increase in case of `too small shared memory` error -buffer | | 64k | network buffer size, increase in case of `too small buffer size` error -package | | 1400 | maximum UDP packet size -template | | | template for graph name (default is $prefix.$host.$split.$param_$interval) -error\_log| | | path suffix for error logs graphs (\*) +Param | Required | Default | Description +------------------------------ | -------- | ------------- | ----------- +prefix | | | path prefix for all graphs +host | | gethostname() | host name for all graphs +server | Yes | | carbon-cache server IP address +use\_full\_hostname | | no | whether to use a full server's hostname in a metric prefix, using hostname\_subdomain\_delimiter value as a subdomain separator +hostname\_subdomain\_delimiter | | _ | a subdomain delimiter to use. Applies only if use\_full\_hostname variable is set to "yes" +protocol | | udp | carbon-cache server protocol (udp or tcp) +port | | 2003 | carbon-cache server port +frequency | | 60 | how often send values to Graphite (seconds) +intervals | | 1m | aggregation intervals, time interval list, vertical bar separator (`m` - minutes) +params | | * | limit metrics list to track, vertical bar separator +shared | | 2m | shared memory size, increase in case of `too small shared memory` error +buffer | | 64k | network buffer size, increase in case of `too small buffer size` error +package | | 1400 | maximum UDP packet size +template | | | template for graph name (default is $prefix.$host.$split.$param_$interval) +error\_log | | | path suffix for error logs graphs (\*) (\*): works only when nginx_error\_log\_limiting\*.patch is applied to the nginx source code diff --git a/src/ngx_http_graphite_module.c b/src/ngx_http_graphite_module.c index 5c6c769..d3f9eb6 100644 --- a/src/ngx_http_graphite_module.c +++ b/src/ngx_http_graphite_module.c @@ -61,6 +61,8 @@ typedef struct ngx_http_graphite_context_s { static char *ngx_http_graphite_config_arg_prefix(ngx_http_graphite_context_t *context, void *data, ngx_str_t *value); static char *ngx_http_graphite_config_arg_host(ngx_http_graphite_context_t *context, void *data, ngx_str_t *value); +static char *ngx_http_graphite_config_arg_use_full_hostname(ngx_http_graphite_context_t *context, void *data, ngx_str_t *value); +static char *ngx_http_graphite_config_arg_hostname_subdomain_delimiter(ngx_http_graphite_context_t *context, void *data, ngx_str_t *value); static char *ngx_http_graphite_config_arg_server(ngx_http_graphite_context_t *context, void *data, ngx_str_t *value); static char *ngx_http_graphite_config_arg_port(ngx_http_graphite_context_t *context, void *data, ngx_str_t *value); static char *ngx_http_graphite_config_arg_frequency(ngx_http_graphite_context_t *context, void *data, ngx_str_t *value); @@ -178,6 +180,8 @@ typedef struct ngx_http_graphite_arg_s { static const ngx_http_graphite_arg_t ngx_http_graphite_config_args[] = { { ngx_string("prefix"), ngx_http_graphite_config_arg_prefix, ngx_null_string }, { ngx_string("host"), ngx_http_graphite_config_arg_host, ngx_null_string }, + { ngx_string("use_full_hostname"), ngx_http_graphite_config_arg_use_full_hostname, ngx_string("no") }, + { ngx_string("hostname_subdomain_delimiter"), ngx_http_graphite_config_arg_hostname_subdomain_delimiter, ngx_string("_") }, { ngx_string("server"), ngx_http_graphite_config_arg_server, ngx_null_string }, { ngx_string("port"), ngx_http_graphite_config_arg_port, ngx_string("2003") }, { ngx_string("frequency"), ngx_http_graphite_config_arg_frequency, ngx_string("60") }, @@ -1199,9 +1203,24 @@ ngx_http_graphite_config(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) char host[HOST_LEN]; gethostname(host, HOST_LEN); host[HOST_LEN - 1] = '\0'; - char *dot = strchr(host, '.'); - if (dot) - *dot = '\0'; + + if( ngx_strncmp(gmcf->use_full_hostname.data, "yes", 3) == 0 ) { + if (gmcf->hostname_subdomain_delimiter.len != 1) { + ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "hostname_subdomain_delimiter must contain only 1 ASCII symbol"); + return NGX_CONF_ERROR; + } + + int i; + for ( i = 0; i < HOST_LEN ; i++ ) { + if ( host[i] == '.' ) + host[i] = gmcf->hostname_subdomain_delimiter.data[0]; + } + } + else { + char *dot = strchr(host, '.'); + if (dot) + *dot = '\0'; + } size_t host_size = strlen(host); @@ -1655,6 +1674,20 @@ ngx_http_graphite_config_arg_host(ngx_http_graphite_context_t *context, void *da return ngx_http_graphite_parse_string(context, value, &gmcf->host); } +static char * +ngx_http_graphite_config_arg_use_full_hostname(ngx_http_graphite_context_t *context, void *data, ngx_str_t *value) { + + ngx_http_graphite_main_conf_t *gmcf = data; + return ngx_http_graphite_parse_string(context, value, &gmcf->use_full_hostname); +} + +static char * +ngx_http_graphite_config_arg_hostname_subdomain_delimiter(ngx_http_graphite_context_t *context, void *data, ngx_str_t *value) { + + ngx_http_graphite_main_conf_t *gmcf = data; + return ngx_http_graphite_parse_string(context, value, &gmcf->hostname_subdomain_delimiter); +} + static char * ngx_http_graphite_config_arg_protocol(ngx_http_graphite_context_t *context, void *data, ngx_str_t *value) { diff --git a/src/ngx_http_graphite_module.h b/src/ngx_http_graphite_module.h index 72ee7f8..f672296 100644 --- a/src/ngx_http_graphite_module.h +++ b/src/ngx_http_graphite_module.h @@ -40,6 +40,8 @@ typedef struct { ngx_uint_t enable; ngx_str_t host; + ngx_str_t use_full_hostname; + ngx_str_t hostname_subdomain_delimiter; ngx_str_t protocol; #ifdef NGX_LOG_LIMIT_ENABLED ngx_str_t error_log;