cdr: allow disabling CDR by default on new channels

Adds a new option, defaultenabled, to the CDR core to
control whether or not CDR is enabled on a newly created
channel. This allows CDR to be disabled by default on
new channels and require the user to explicitly enable
CDR if desired. Existing behavior remains unchanged.

ASTERISK-29808 #close

Change-Id: Ibb78c11974bda229bbb7004b64761980e0b2c6d1
This commit is contained in:
Naveen Albert 2021-12-15 18:36:42 +00:00 committed by Friendly Automation
parent 70f8ea0d1a
commit 386c5e495f
5 changed files with 48 additions and 3 deletions

View File

@ -13,6 +13,11 @@
; any loading of backend CDR modules. Default is "yes".
;enable=yes
; Define whether or not to use CDR logging on new channels by default.
; Setting this to "no" will disable CDR on channels unless it is explicitly
; enabled. Default is "yes".
;channeldefaultenabled=yes
; Define whether or not to log unanswered calls that don't involve an outgoing
; party. Setting this to "yes" will make calls to extensions that don't answer
; and don't set a B side channel (such as by using the Dial application)

View File

@ -0,0 +1,8 @@
Subject: cdr
A new CDR option, channeldefaultenabled, allows controlling
whether CDR is enabled or disabled by default on
newly created channels. The default behavior remains
unchanged from previous versions of Asterisk (new
channels will have CDR enabled, as long as CDR is
enabled globally).

View File

@ -224,6 +224,7 @@ enum ast_cdr_settings {
CDR_END_BEFORE_H_EXTEN = 1 << 4, /*!< End the CDR before the 'h' extension runs */
CDR_INITIATED_SECONDS = 1 << 5, /*!< Include microseconds into the billing time */
CDR_DEBUG = 1 << 6, /*!< Enables extra debug statements */
CDR_CHANNEL_DEFAULT_ENABLED = 1 << 7, /*!< Whether CDR is enabled for each channel by default */
};
/*! \brief CDR Batch Mode settings */

View File

@ -96,6 +96,21 @@
any loading of backend CDR modules. Default is "yes".</para>
</description>
</configOption>
<configOption name="channeldefaultenabled">
<synopsis>Whether CDR is enabled on a channel by default</synopsis>
<description><para>Define whether or not CDR should be enabled on a channel by default.
Setting this to "yes" will enable CDR on every channel unless it is explicitly disabled.
Setting this to "no" will disable CDR on every channel unless it is explicitly enabled.
Default is "yes".</para>
<para>Note that CDR must still be globally enabled (<literal>enable = yes</literal>) for this
option to have any effect. This only applies to whether CDR is enabled or disabled on
newly created channels, which can be changed in the dialplan during a call.</para>
<para>If this is set to "yes", you should use <literal>Set(CDR_PROP(disable)=1)</literal>
to disable CDR for a call.</para>
<para>If this is set to "no", you should use <literal>Set(CDR_PROP(disable)=0)</literal>
to undisable (enable) CDR for a call.</para>
</description>
</configOption>
<configOption name="unanswered">
<synopsis>Log calls that are never answered and don't set an outgoing party.</synopsis>
<description><para>
@ -192,6 +207,7 @@
#define DEFAULT_CONGESTION "0"
#define DEFAULT_END_BEFORE_H_EXTEN "1"
#define DEFAULT_INITIATED_SECONDS "0"
#define DEFAULT_CHANNEL_ENABLED "1"
#define DEFAULT_BATCH_SIZE "100"
#define MAX_BATCH_SIZE 1000
@ -2281,12 +2297,25 @@ static void handle_channel_snapshot_update_message(void *data, struct stasis_sub
}
if (update->new_snapshot && !update->old_snapshot) {
struct module_config *mod_cfg = NULL;
cdr = cdr_object_alloc(update->new_snapshot, stasis_message_timestamp(message));
if (!cdr) {
return;
}
mod_cfg = ao2_global_obj_ref(module_configs);
cdr->is_root = 1;
ao2_link(active_cdrs_master, cdr);
/* If CDR should be disabled unless enabled on a per-channel basis, then disable
CDR, right from the get go */
if (mod_cfg) {
if (!ast_test_flag(&mod_cfg->general->settings, CDR_CHANNEL_DEFAULT_ENABLED)) {
ast_debug(3, "Disable CDR by default\n");
ast_set_flag(&cdr->flags, AST_CDR_FLAG_DISABLE_ALL);
}
ao2_cleanup(mod_cfg);
}
} else {
cdr = ao2_find(active_cdrs_master, update->new_snapshot->base->uniqueid, OBJ_SEARCH_KEY);
}
@ -4168,6 +4197,7 @@ static char *handle_cli_status(struct ast_cli_entry *e, int cmd, struct ast_cli_
ast_cli(a->fd, " Logging: %s\n", ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED) ? "Enabled" : "Disabled");
ast_cli(a->fd, " Mode: %s\n", ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE) ? "Batch" : "Simple");
if (ast_test_flag(&mod_cfg->general->settings, CDR_ENABLED)) {
ast_cli(a->fd, " Log calls by default: %s\n", ast_test_flag(&mod_cfg->general->settings, CDR_CHANNEL_DEFAULT_ENABLED) ? "Yes" : "No");
ast_cli(a->fd, " Log unanswered calls: %s\n", ast_test_flag(&mod_cfg->general->settings, CDR_UNANSWERED) ? "Yes" : "No");
ast_cli(a->fd, " Log congestion: %s\n\n", ast_test_flag(&mod_cfg->general->settings, CDR_CONGESTION) ? "Yes" : "No");
if (ast_test_flag(&mod_cfg->general->settings, CDR_BATCHMODE)) {
@ -4348,6 +4378,7 @@ static int process_config(int reload)
aco_option_register(&cfg_info, "safeshutdown", ACO_EXACT, general_options, DEFAULT_BATCH_SAFE_SHUTDOWN, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, batch_settings.settings), BATCH_MODE_SAFE_SHUTDOWN);
aco_option_register(&cfg_info, "size", ACO_EXACT, general_options, DEFAULT_BATCH_SIZE, OPT_UINT_T, PARSE_IN_RANGE, FLDSET(struct ast_cdr_config, batch_settings.size), 0, MAX_BATCH_SIZE);
aco_option_register(&cfg_info, "time", ACO_EXACT, general_options, DEFAULT_BATCH_TIME, OPT_UINT_T, PARSE_IN_RANGE, FLDSET(struct ast_cdr_config, batch_settings.time), 1, MAX_BATCH_TIME);
aco_option_register(&cfg_info, "channeldefaultenabled", ACO_EXACT, general_options, DEFAULT_CHANNEL_ENABLED, OPT_BOOLFLAG_T, 1, FLDSET(struct ast_cdr_config, settings), CDR_CHANNEL_DEFAULT_ENABLED);
}
if (aco_process_config(&cfg_info, reload) == ACO_PROCESS_ERROR) {

View File

@ -59,17 +59,17 @@ static struct ast_cdr_config *saved_config;
/*! \brief A configuration suitable for 'normal' CDRs */
static struct ast_cdr_config debug_cdr_config = {
.settings.flags = CDR_ENABLED | CDR_DEBUG,
.settings.flags = CDR_ENABLED | CDR_CHANNEL_DEFAULT_ENABLED | CDR_DEBUG,
};
/*! \brief A configuration suitable for CDRs with unanswered records */
static struct ast_cdr_config unanswered_cdr_config = {
.settings.flags = CDR_ENABLED | CDR_UNANSWERED | CDR_DEBUG,
.settings.flags = CDR_ENABLED | CDR_CHANNEL_DEFAULT_ENABLED | CDR_UNANSWERED | CDR_DEBUG,
};
/*! \brief A configuration suitable for CDRs with congestion enabled */
static struct ast_cdr_config congestion_cdr_config = {
.settings.flags = CDR_ENABLED | CDR_UNANSWERED | CDR_DEBUG | CDR_CONGESTION,
.settings.flags = CDR_ENABLED | CDR_CHANNEL_DEFAULT_ENABLED | CDR_UNANSWERED | CDR_DEBUG | CDR_CONGESTION,
};
/*! \brief Macro to swap a configuration out from the CDR engine. This should be