static void nc_show_version() { log_stderr("This is nutcracker-%s sha=%s:%d" CRLF, NC_VERSION_STRING, NC_GIT_SHA1, strtol(NC_GIT_DIRTY, NULL, 10) > 0); }
static rstatus_t nc_get_options(int argc, char **argv, struct instance *nci) { int c, value; opterr = 0; for (;;) { c = getopt_long(argc, argv, short_options, long_options, NULL); if (c == -1) { /* no more options */ break; } switch (c) { case 'h': show_help = 1; break; case 'V': show_version = 1; break; case 't': test_conf = 1; break; case 'd': daemonize = 1; break; case 'D': describe_stats = 1; break; case 'v': value = nc_atoi(optarg, strlen(optarg)); if (value < 0) { log_stderr("nutcracker: option -v requires a number"); return NC_ERROR; } nci->log_level = value; break; case 'o': nci->log_filename = optarg; break; case 'c': nci->conf_filename = optarg; break; case 's': value = nc_atoi(optarg, strlen(optarg)); if (value < 0) { log_stderr("nutcracker: option -s requires a number"); return NC_ERROR; } if (!nc_valid_port(value)) { log_stderr("nutcracker: option -s value %d is not a valid " "port", value); return NC_ERROR; } nci->stats_port = (uint16_t)value; break; case 'i': value = nc_atoi(optarg, strlen(optarg)); if (value < 0) { log_stderr("nutcracker: option -i requires a number"); return NC_ERROR; } nci->stats_interval = value; break; case 'a': nci->stats_addr = optarg; break; case 'p': nci->pid_filename = optarg; break; case 'm': value = nc_atoi(optarg, strlen(optarg)); if (value <= 0) { log_stderr("nutcracker: option -m requires a non-zero number"); return NC_ERROR; } if (value < NC_MBUF_MIN_SIZE || value > NC_MBUF_MAX_SIZE) { log_stderr("nutcracker: mbuf chunk size must be between %zu and" " %zu bytes", NC_MBUF_MIN_SIZE, NC_MBUF_MAX_SIZE); return NC_ERROR; } nci->mbuf_chunk_size = (size_t)value; break; case '?': switch (optopt) { case 'o': case 'c': case 'p': log_stderr("nutcracker: option -%c requires a file name", optopt); break; case 'm': case 'v': case 's': case 'i': log_stderr("nutcracker: option -%c requires a number", optopt); break; case 'a': log_stderr("nutcracker: option -%c requires a string", optopt); break; default: log_stderr("nutcracker: invalid option -- '%c'", optopt); break; } return NC_ERROR; default: log_stderr("nutcracker: invalid option -- '%c'", optopt); return NC_ERROR; } } return NC_OK; }
int _log_rotating(ssize_t write_bytes, struct logger *l) { r_status status = 0; if(LOG_RORATE == 0) { return status; } //struct logger *l = &logger; if(write_bytes <= 0) { return -1; } l->current_log_size += write_bytes; if(l->current_log_size >= LOG_FIEL_MAX_SIZE_FOR_ROTATING) { if (l->fd < 0 || l->fd == STDERR_FILENO) { return -1; } close(l->fd); size_t len = 0; char str_time[30]; struct timeval tv; gettimeofday(&tv, NULL); len += rct_strftime(str_time, 30 - len, "_%Y-%m-%d_%H.%M.%S.", localtime(&tv.tv_sec)); len += rct_scnprintf(str_time + len, 30 - len, "%03ld", tv.tv_usec/1000); size_t i; size_t log_filename_len = strlen(l->name); size_t filename_bak_len = log_filename_len + len + 1; char filename_bak[filename_bak_len]; for(i = 0; i < log_filename_len; i ++) { filename_bak[i] = (l->name)[i]; } for(i = log_filename_len; i < filename_bak_len - 1; i ++) { filename_bak[i] = str_time[i - log_filename_len]; } filename_bak[filename_bak_len - 1] = '\0'; //log_debug(LOG_DEBUG, "filename_bak is %s", filename_bak); if(rename(l->name, filename_bak) < 0) { log_stderr("rename log file '%s' to '%s' failed: %s", l->name, filename_bak, strerror(errno)); status |= -1; } l->fd = open(l->name, O_WRONLY | O_APPEND | O_CREAT, 0644); if (l->fd < 0) { log_stderr("opening log file '%s' failed: %s", l->name, strerror(errno)); return -1; } l->current_log_size = 0; status |= _log_files_circular_maintain(filename_bak, l); } return status; }
static rstatus_t dn_get_options(int argc, char **argv, struct instance *nci) { int c, value; opterr = 0; for (;;) { c = getopt_long(argc, argv, short_options, long_options, NULL); if (c == -1) { /* no more options */ break; } switch (c) { case 'h': show_version = 1; show_help = 1; break; case 'V': show_version = 1; break; case 't': test_conf = 1; nci->log_level = 11; break; case 'd': daemonize = 1; break; case 'D': describe_stats = 1; show_version = 1; break; case 'g': enable_gossip = 1; break; case 'v': value = dn_atoi(optarg, strlen(optarg)); if (value < 0) { log_stderr("dynomite: option -v requires a number"); return DN_ERROR; } nci->log_level = value; break; case 'o': nci->log_filename = optarg; break; case 'c': nci->conf_filename = optarg; break; case 's': value = dn_atoi(optarg, strlen(optarg)); if (value < 0) { log_stderr("dynomite: option -s requires a number"); return DN_ERROR; } if (!dn_valid_port(value)) { log_stderr("dynomite: option -s value %d is not a valid " "port", value); return DN_ERROR; } nci->stats_port = (uint16_t)value; break; case 'i': value = dn_atoi(optarg, strlen(optarg)); if (value < 0) { log_stderr("dynomite: option -i requires a number"); return DN_ERROR; } nci->stats_interval = value; break; case 'a': nci->stats_addr = optarg; break; case 'p': nci->pid_filename = optarg; break; case 'm': value = dn_atoi(optarg, strlen(optarg)); if (value <= 0) { log_stderr("dynomite: option -m requires a non-zero number"); return DN_ERROR; } if (value < DN_MBUF_MIN_SIZE || value > DN_MBUF_MAX_SIZE) { log_stderr("dynomite: mbuf chunk size must be between %zu and" " %zu bytes", DN_MBUF_MIN_SIZE, DN_MBUF_MAX_SIZE); return DN_ERROR; } if ((value / 16) * 16 != value) { log_stderr("dynomite: mbuf chunk size must be a multiple of 16"); return DN_ERROR; } nci->mbuf_chunk_size = (size_t)value; break; case 'M': value = dn_atoi(optarg, strlen(optarg)); if (value <= 0) { log_stderr("dynomite: option -M requires a non-zero number"); return DN_ERROR; } if (value < DN_MIN_ALLOC_MSGS || value > DN_MAX_ALLOC_MSGS) { log_stderr("dynomite: max allocated messages buffer must be between %zu and" " %zu messages", DN_MIN_ALLOC_MSGS, DN_MAX_ALLOC_MSGS); return DN_ERROR; } nci->alloc_msgs_max = (size_t)value; break; case 'x': value = dn_atoi(optarg, strlen(optarg)); if (value <= 0) { log_stderr("dynomite: option -x requires a non-zero number"); return DN_ERROR; } admin_opt = value; break; case '?': switch (optopt) { case 'o': case 'c': case 'p': log_stderr("dynomite: option -%c requires a file name", optopt); break; case 'm': case 'M': case 'v': case 's': case 'i': log_stderr("dynomite: option -%c requires a number", optopt); break; case 'a': log_stderr("dynomite: option -%c requires a string", optopt); break; default: log_stderr("dynomite: invalid option -- '%c'", optopt); break; } return DN_ERROR; default: log_stderr("dynomite: invalid option -- '%c'", optopt); return DN_ERROR; } } return DN_OK; }
static rstatus_t mcp_get_options(struct context *ctx, int argc, char **argv) { rstatus_t status; struct opt *opt; int c, value; size_t size; double real; char *pos; opt = &ctx->opt; opterr = 0; for (;;) { c = getopt_long(argc, argv, short_options, long_options, NULL); if (c == -1) { /* no more options */ break; } switch(c) { case 'h': show_version = 1; show_help = 1; break; case 'V': show_version = 1; break; case 'v': value = mcp_atoi(optarg); if (value < 0) { log_stderr("mcperf: option -v requires a number"); return MCP_ERROR; } opt->log_level = value; break; case 'o': opt->log_filename = optarg; break; case 's': opt->server = optarg; break; case 'p': value = mcp_atoi(optarg); if (value < 0) { log_stderr("mcperf: option -p requires a number"); return MCP_ERROR; } if (!mcp_valid_port(value)) { log_stderr("mcperf: option -p value %d is not a valid port", value); return MCP_ERROR; } opt->port = (uint16_t)value; break; case 'H': opt->print_histogram = 1; break; case 't': real = mcp_atod(optarg); if (real < 0.0) { log_stderr("mcperf: option -T requires a real number"); return MCP_ERROR; } opt->timeout = real; break; case 'l': value = mcp_atoi(optarg); if (value < 0) { log_stderr("mcperf: option -l requires a number"); return MCP_ERROR; } opt->linger = 1; opt->linger_timeout = value; break; case 'b': value = mcp_atoi(optarg); if (value < 0) { log_stderr("mcperf: option -b requires a number"); return MCP_ERROR; } opt->send_buf_size = value; break; case 'B': value = mcp_atoi(optarg); if (value < 0) { log_stderr("mcperf: option -B requires a number"); return MCP_ERROR; } opt->recv_buf_size = value; break; case 'm': status = mcp_get_method(ctx, optarg); if (status != MCP_OK) { return status; } break; case 'e': value = mcp_atoi(optarg); if (value < 0) { log_stderr("mcperf: option -e requires a number"); return MCP_ERROR; } opt->expiry = (uint32_t)value; break; case 'q': opt->use_noreply = 1; break; case 'P': size = strlen(optarg); if (size > MCP_PREFIX_LEN) { log_stderr("mcperf: key prefix cannot exceed %d in length", MCP_PREFIX_LEN); return MCP_ERROR; } opt->prefix.data = optarg; opt->prefix.len = size; break; case 'c': pos = strchr(optarg, '/'); if (pos == NULL) { log_stderr("mcperf: invalid client id format '%s'", optarg); return MCP_ERROR; } *pos = '\0'; value = mcp_atoi(optarg); if (value < 0) { log_stderr("mcperf: client id is not a number '%s'", optarg); return MCP_ERROR; } opt->client.id = (uint32_t)value; optarg = pos + 1; value = mcp_atoi(optarg); if (value < 0) { log_stderr("mcperf: number of clients is not a number '%s'", optarg); return MCP_ERROR; } opt->client.n = (uint32_t)value; break; case 'n': value = mcp_atoi(optarg); if (value < 0) { log_stderr("mcperf: option -n requires a number"); return MCP_ERROR; } opt->num_conns = (uint32_t)value; break; case 'N': value = mcp_atoi(optarg); if (value < 0) { log_stderr("mcperf: option -N requires a number"); return MCP_ERROR; } opt->num_calls = (uint32_t)value; break; case 'r': status = mcp_get_dist_opt(&opt->conn_dopt, optarg); if (status != MCP_OK) { return status; } break; case 'R': status = mcp_get_dist_opt(&opt->call_dopt, optarg); if (status != MCP_OK) { return status; } break; case 'D': opt->disable_nodelay = 1; break; case 'z': status = mcp_get_dist_opt(&opt->size_dopt, optarg); if (status != MCP_OK) { return status; } if (opt->size_dopt.type == DIST_NONE) { log_stderr("mcperf: invalid distribution type %d for item " "sizes", opt->size_dopt.type); return MCP_ERROR; } break; case '?': switch (optopt) { case 'o': log_stderr("mcperf: option -%c requires a file name", optopt); break; case 's': case 'm': case 'P': case 'c': log_stderr("mcperf: option -%c requires a string", optopt); break; case 'v': case 'p': case 'l': case 'b': case 'B': case 'e': case 'n': case 'N': log_stderr("mcperf: option -%c requires a number", optopt); break; case 't': log_stderr("mcperf: option -%c requires a real number", optopt); break; case 'r': case 'R': case 'z': log_stderr("mcperf: option -%c requires a distribution", optopt); break; default: log_stderr("mcperf: invalid option -- '%c'", optopt); break; } return MCP_ERROR; default: log_stderr("mcperf: invalid option -- '%c'", optopt); return MCP_ERROR; } } return MCP_OK; }
static rstatus_t mcp_get_dist_opt(struct dist_opt *dopt, char *line) { char *pos; /* * Parse any distribution value specified as: * --distribution [d|u|e]T1[,T2] */ switch (*line) { case 'd': dopt->type = DIST_DETERMINISTIC; line++; break; case 'u': dopt->type = DIST_UNIFORM; line++; break; case 'e': dopt->type = DIST_EXPONENTIAL; line++; break; case 's': dopt->type = DIST_SEQUENTIAL; line++; break; default: dopt->type = DIST_NONE; break; } dopt->min = 0.0; dopt->max = 0.0; switch (dopt->type) { case DIST_NONE: dopt->min = mcp_atod(line); if (dopt->min < 0.0) { log_stderr("mcperf: invalid distribution value '%s'", line); return MCP_ERROR; } if (dopt->min != 0.0) { dopt->type = DIST_DETERMINISTIC; dopt->min = 1.0 / dopt->min; dopt->max = dopt->min; } break; case DIST_DETERMINISTIC: case DIST_EXPONENTIAL: case DIST_SEQUENTIAL: dopt->min = mcp_atod(line); if (dopt->min <= 0.0) { log_stderr("mcperf: invalid mean value '%s'", line); return MCP_ERROR; } dopt->max = dopt->min; break; case DIST_UNIFORM: pos = strchr(line, ','); if (pos == NULL) { log_stderr("mcperf: invalid uniform distribution value '%s'", line); return MCP_ERROR; } *pos = '\0'; dopt->min = mcp_atod(line); if (dopt->min <= 0.0) { log_stderr("mcperf: invalid minimum value '%s'", line); return MCP_ERROR; } line = pos + 1; dopt->max = mcp_atod(line); if (dopt->max <= 0.0) { log_stderr("mcperf: invalid maximum value '%s'", line); return MCP_ERROR; } if (dopt->max < dopt->min) { log_stderr("mcperf: maximum value '%g' should be greater than or " "equal to minium value '%g'", dopt->max, dopt->min); return MCP_ERROR; } break; default: NOT_REACHED(); } return MCP_OK; }
static void mcp_show_usage(void) { log_stderr( "Usage: mcperf [-?hV] [-v verbosity level] [-o output file]" CRLF " [-s server] [-p port] [-H] [-t timeout] [-l linger]" CRLF " [-b send-buffer] [-B recv-buffer] [-D]" CRLF " [-m method] [-e expiry] [-q] [-P prefix]" CRLF " [-c client] [-n num-conns] [-N num-calls]" CRLF " [-r conn-rate] [-R call-rate] [-z sizes]" CRLF "" CRLF "Options:" CRLF " -h, --help : this help" CRLF " -V, --version : show version and exit" CRLF " -v, --verbosity=N : set logging level (default: %d, min: %d, max: %d)" CRLF " -o, --output=S : set logging file (default: %s)" CRLF " -s, --server=S : set the hostname of the server (default: %s)" CRLF " -p, --port=N : set the port number of the server (default: %d)" CRLF " -H, --print-histogram : print response time histogram" CRLF " ...", MCP_LOG_DEFAULT, MCP_LOG_MIN, MCP_LOG_MAX, MCP_LOG_PATH, MCP_SERVER, MCP_PORT); log_stderr( " -t, --timeout=X : set the connection and response timeout in sec (default: %s sec)" CRLF " -l, --linger=N : set the linger timeout in sec, when closing TCP connections (default: %s)" CRLF " -b, --send-buffer=N : set socket send buffer size (default: %d bytes)" CRLF " -B, --recv-buffer=N : set socket recv buffer size (default: %d bytes)" CRLF " -D, --disable-nodelay : disable tcp nodelay" CRLF " ...", MCP_TIMEOUT_STR, MCP_LINGER_STR, MCP_SEND_BUFSIZE, MCP_RECV_BUFSIZE ); log_stderr( " -m, --method=M : set the method to use when issuing memcached request (default: %s)" CRLF " -e, --expiry=N : set the expiry value in sec for generated requests (default: %s sec)" CRLF " -q, --use-noreply : set noreply for generated requests" CRLF " -P, --prefix=S : set the prefix of generated keys (default: %s)" CRLF " ...", MCP_METHOD_STR, MCP_EXPIRY_STR, MCP_PREFIX ); log_stderr( " -c, --client=I/N : set mcperf instance to be I out of total N instances (default: %d/%d)" CRLF " -n, --num-conns=N : set the number of connections to create (default: %d)" CRLF " -N, --num-calls=N : set the number of calls to create on each connection (default: %d)" CRLF " -r, --conn-rate=R : set the connection creation rate (default: %s conns/sec) "CRLF " -R, --call-rate=R : set the call creation rate (default: %s calls/sec)" CRLF " -z, --sizes=R : set the distribution for item sizes (default: %s bytes)" CRLF " ...", MCP_CLIENT_ID, MCP_CLIENT_N, MCP_NUM_CONNS, MCP_NUM_CALLS, MCP_CONN_DIST_STR, MCP_CALL_DIST_STR, MCP_SIZE_DIST_STR ); log_stderr( "Where:" CRLF " N is an integer" CRLF " X is a real" CRLF " S is a string" CRLF " M is a method string and is either a 'get', 'gets', 'delete', 'cas', 'set', 'add', 'replace'" CRLF " 'append', 'prepend', 'incr', 'decr'" CRLF " R is the rate written as [D]R1[,R2] where:" CRLF " D is the distribution type and is either deterministic 'd', uniform 'u', or exponential 'e' and if:" CRLF " D is ommited or set to 'd', a deterministic interval specified by parameter R1 is used" CRLF " D is set to 'e', an exponential distibution with mean interval of R1 is used" CRLF " D is set to 'u', a uniform distribution over interval [R1, R2) is used" CRLF " R is 0, the next request or connection is created after the previous one completes" CRLF " " ); }