Index: configs/queues.conf.sample =================================================================== --- configs/queues.conf.sample (revision 241226) +++ configs/queues.conf.sample (working copy) @@ -42,6 +42,14 @@ ; monitor-type = MixMonitor ; +; Keep Statistics on Reloads +; Normally a reload clears the queue statistics. Set keepstats=yes +; to preserve the queue counters across reloads. There's always the option +; of using the 'queue reset stats' CLI command, or the AMI command +; QueueReset to reset the counters. +; +keepstats = no +; ; UpdateCDR behavior. ; This option is implemented to mimic chan_agents behavior of populating ; CDR dstchannel field of a call with an agent name, which you can set Index: apps/app_queue.c =================================================================== --- apps/app_queue.c (revision 241226) +++ apps/app_queue.c (working copy) @@ -724,6 +724,9 @@ /* The maximum length of each persistent member queue database entry */ #define PM_MAX_LEN 8192 +/*! \brief queues.conf keep statistics on reoads option */ +static int queue_keep_stats = 0; + /*! \brief queues.conf [general] option */ static int queue_persistent_members = 0; @@ -1366,13 +1369,11 @@ } /*! \brief allocate space for new queue member and set fields based on parameters passed */ -static struct member *create_queue_member(const char *interface, const char *membername, int penalty, int paused, const char *state_interface) +static struct member *create_queue_member(const char *interface, const char *membername, const char *state_interface) { struct member *cur; if ((cur = ao2_alloc(sizeof(*cur), NULL))) { - cur->penalty = penalty; - cur->paused = paused; ast_copy_string(cur->interface, interface, sizeof(cur->interface)); if (!ast_strlen_zero(state_interface)) ast_copy_string(cur->state_interface, state_interface, sizeof(cur->state_interface)); @@ -1890,9 +1891,11 @@ /* Create a new member */ if (!found) { - if ((m = create_queue_member(interface, membername, penalty, paused, state_interface))) { + if ((m = create_queue_member(interface, membername, state_interface))) { m->dead = 0; m->realtime = 1; + m->penalty = penalty; + m->paused = paused; ast_copy_string(m->rt_uniqueid, rt_uniqueid, sizeof(m->rt_uniqueid)); ast_queue_log(q->name, "REALTIME", m->interface, "ADDMEMBER", "%s", ""); ao2_link(q->members, m); @@ -4893,7 +4896,9 @@ ao2_lock(q); if ((old_member = interface_exists(q, interface)) == NULL) { - if ((new_member = create_queue_member(interface, membername, penalty, paused, state_interface))) { + if ((new_member = create_queue_member(interface, membername, state_interface))) { + new_member->penalty = penalty; + new_member->paused = paused; new_member->dynamic = 1; ao2_link(q->members, new_member); q->membercount++; @@ -6151,6 +6156,9 @@ static void queue_set_global_params(struct ast_config *cfg) { const char *general_val = NULL; + queue_keep_stats = 0; + if ((general_val = ast_variable_retrieve(cfg, "general", "keepstats"))) + queue_keep_stats = ast_true(general_val); queue_persistent_members = 0; if ((general_val = ast_variable_retrieve(cfg, "general", "persistentmembers"))) queue_persistent_members = ast_true(general_val); @@ -6231,7 +6239,16 @@ /* Find the old position in the list */ ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface)); cur = ao2_find(q->members, &tmpmem, OBJ_POINTER | OBJ_UNLINK); - if ((newm = create_queue_member(interface, membername, penalty, cur ? cur->paused : 0, state_interface))) { + if ((newm = create_queue_member(interface, membername, state_interface))) { + newm->penalty = penalty; + if (cur) { + newm->paused = cur->paused; + newm->status = cur->status; + newm->lastcall = cur->lastcall; + if (queue_keep_stats) { + newm->calls = cur->calls; + } + } ao2_link(q->members, newm); ao2_ref(newm, -1); } @@ -7068,6 +7085,9 @@ if (!header_found) { ast_set_flag(&mask, AST_FLAGS_ALL); + if (queue_keep_stats) { + ast_clear_flag(&mask, QUEUE_RESET_STATS); + } } if (!reload_handler(1, &mask, queuename)) { @@ -7586,6 +7606,9 @@ ast_set_flag(&mask, QUEUE_RELOAD_PARAMETERS); } else if (!strcasecmp(a->argv[2], "all")) { ast_set_flag(&mask, AST_FLAGS_ALL); + if (queue_keep_stats) { + ast_clear_flag(&mask, QUEUE_RESET_STATS); + } } if (a->argc == 3) { @@ -7738,6 +7761,10 @@ static int reload(void) { struct ast_flags mask = {AST_FLAGS_ALL,}; + + if (queue_keep_stats) { + ast_clear_flag(&mask, QUEUE_RESET_STATS); + } ast_unload_realtime("queue_members"); reload_handler(1, &mask, NULL); return 0;