Skip to content

Added drizzle_return_error_code and drizzle_no_log_error_codes directives #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
16 changes: 16 additions & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,22 @@ Directives
servers: 1
peers: 1

drizzle_return_error_code on|off
Returns the drizzle / mysql error code when an error occurs, rather
than 500 (internal server error).

This can be useful for example if you are using ngx_lua to process the
returned data, and wish to handle specific error situations, such as
when there is a duplicate entry on INSERT queries (see example below).

drizzle_no_log_error_codes <num> [<num> ...]
Do not log error information for the error codes listed

e.g.

drizzle_return_error_code on;
drizzle_no_log_error_codes 1062; # doesn't log duplicate entries

Output
This module generates binary query results in a format
that will be shared among the various nginx database
Expand Down
80 changes: 78 additions & 2 deletions src/ngx_http_drizzle_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ static ngx_int_t ngx_http_drizzle_tid_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static char * ngx_http_drizzle_enable_status(ngx_conf_t *cf,
ngx_command_t *cmd, void *conf);

static char * ngx_http_drizzle_error_codes(ngx_conf_t *cf,
ngx_command_t *cmd, void *conf);


static ngx_http_variable_t ngx_http_drizzle_variables[] = {

Expand Down Expand Up @@ -136,6 +138,22 @@ static ngx_command_t ngx_http_drizzle_cmds[] = {
0,
NULL },

{ ngx_string("drizzle_return_error_code"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
|NGX_HTTP_LIF_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_drizzle_loc_conf_t, return_error_code),
NULL },

{ ngx_string("drizzle_no_log_error_codes"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
|NGX_HTTP_LIF_CONF|NGX_CONF_1MORE,
ngx_http_drizzle_error_codes,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_drizzle_loc_conf_t, no_log_error_codes),
NULL },

ngx_null_command
};

Expand Down Expand Up @@ -229,13 +247,15 @@ ngx_http_drizzle_create_loc_conf(ngx_conf_t *cf)
/* set by ngx_pcalloc:
* conf->dbname = NULL
* conf->query = NULL
* conf->no_log_error_codes = NULL
*/

conf->return_error_code = NGX_CONF_UNSET;
conf->complex_target = NGX_CONF_UNSET_PTR;

conf->buf_size = NGX_CONF_UNSET_SIZE;
conf->tid_var_index = NGX_CONF_UNSET;

return conf;
}

Expand Down Expand Up @@ -271,6 +291,11 @@ ngx_http_drizzle_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
conf->queries = prev->queries;
}

ngx_conf_merge_value(conf->return_error_code, prev->return_error_code, 0);

if (conf->no_log_error_codes == NULL)
conf->no_log_error_codes = prev->no_log_error_codes;

ngx_conf_merge_size_value(conf->buf_size, prev->buf_size,
(size_t) ngx_pagesize);

Expand Down Expand Up @@ -560,3 +585,54 @@ ngx_http_drizzle_enable_status(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_OK;
}


static char *
ngx_http_drizzle_error_codes(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
char *p = conf;

ngx_array_t **ap;
ngx_str_t *value, *e;
ngx_int_t i, *c;

ap = (ngx_array_t **) (p + cmd->offset);
if (*ap) {
return "is duplicate";
}

*ap = ngx_array_create (cf->pool, cf->args->nelts - 1, sizeof (ngx_int_t));
if (*ap == NULL)
return NGX_CONF_ERROR;

value = cf->args->elts;
value++;

e = value + cf->args->nelts - 1;

for ( ;value<e; value++) {

c = ngx_array_push (*ap);
if (c == NULL)
return NGX_CONF_ERROR;

*c = ngx_atoi (value->data, value->len);
if (*c == NGX_ERROR) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"%V\" is not a valid drizzle error code (it must be an integer between 1 and 65536)", value);

return NGX_CONF_ERROR;
}

if (*c <= 0 || *c > 0xffff) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"%V\" is not a valid drizzle error code (it must be an integer between 1 and 65536)", value);

return NGX_CONF_ERROR;
}

/* TODO: further check that numbers are valid error codes? */
}

return NGX_CONF_OK;
}

3 changes: 3 additions & 0 deletions src/ngx_http_drizzle_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ typedef struct {
ngx_array_t *user_types;
/* of ngx_http_drizzle_var_type_t */

ngx_flag_t return_error_code;
ngx_array_t *no_log_error_codes;

ngx_http_complex_value_t *complex_target;

size_t buf_size;
Expand Down
56 changes: 43 additions & 13 deletions src/ngx_http_drizzle_processor.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,17 @@ ngx_http_upstream_drizzle_send_query(ngx_http_request_t *r,
ngx_connection_t *c, ngx_http_upstream_drizzle_peer_data_t *dp,
drizzle_con_st *dc)
{
ngx_http_drizzle_loc_conf_t *dlcf;
ngx_http_upstream_t *u = r->upstream;
drizzle_return_t ret;
ngx_int_t rc;
u_char *query_data;
size_t query_len;
ngx_flag_t has_set_names = 0;
ngx_flag_t enable_charset = 0;

ngx_flag_t log_error;
ngx_int_t error_code, *codep, *codepe;

dd("enable charset: %d", (int) dp->enable_charset);

if (dp->enable_charset && ! dp->has_set_names) {
Expand Down Expand Up @@ -202,16 +205,37 @@ ngx_http_upstream_drizzle_send_query(ngx_http_request_t *r,
}

if (ret != DRIZZLE_RETURN_OK) {

error_code = drizzle_error_code(dc->drizzle);

dlcf = ngx_http_get_module_loc_conf (r, ngx_http_drizzle_module);

log_error = 1;

if (dlcf->no_log_error_codes) {
codep = dlcf->no_log_error_codes->elts;
codepe = codep + dlcf->no_log_error_codes->nelts;

for ( ; codep < codepe; codep++) {
if (*codep == error_code) {
log_error = 0;
break;
}
}
}
#if 1
if (ret == DRIZZLE_RETURN_ERROR_CODE) {
if (drizzle_error_code(dc->drizzle) == MYSQL_ER_NO_SUCH_TABLE) {
dd("XXX no such talbe");

ngx_log_error(NGX_LOG_NOTICE, c->log, 0,
"failed to send query: %d (%d): %s",
(int) ret, drizzle_error_code(dc->drizzle),
drizzle_error(dc->drizzle));

if (error_code == MYSQL_ER_NO_SUCH_TABLE) {
dd("XXX no such table");

if (log_error) {

ngx_log_error(NGX_LOG_NOTICE, c->log, 0,
"failed to send query: %d (%ui): %s",
(int) ret, error_code,
drizzle_error(dc->drizzle));
}

if (dp->enable_charset && ! dp->has_set_names) {
c->log->action = "sending query to drizzle upstream";
dp->has_set_names = 1;
Expand All @@ -226,11 +250,17 @@ ngx_http_upstream_drizzle_send_query(ngx_http_request_t *r,
}
#endif

ngx_log_error(NGX_LOG_ERR, c->log, 0,
"failed to send query: %d (%d): %s",
(int) ret, drizzle_error_code(dc->drizzle),
drizzle_error(dc->drizzle));
if (log_error) {

ngx_log_error(NGX_LOG_ERR, c->log, 0,
"failed to send query: %d (%ui): %s",
(int) ret, error_code,
drizzle_error(dc->drizzle));
}

if (dlcf->return_error_code)
return error_code;

return NGX_HTTP_INTERNAL_SERVER_ERROR;
}

Expand Down