Skip to content

Commit

Permalink
Merge pull request #2272 from kamailio/jchavanton/dlg_dump
Browse files Browse the repository at this point in the history
dialog: adding dlg.dump
  • Loading branch information
jchavanton committed Apr 8, 2020
2 parents bc17104 + 2d00e26 commit 776f2f6
Show file tree
Hide file tree
Showing 2 changed files with 169 additions and 0 deletions.
151 changes: 151 additions & 0 deletions src/modules/dialog/dialog.c
Expand Up @@ -2196,6 +2196,118 @@ int mod_register(char *path, int *dlflags, void *p1, void *p2)
}

/**************************** RPC functions ******************************/
/*!
* \brief Helper method that outputs a dialog in a file
* \see rpc_dump_file_dlg
* \param dlg printed dialog
* \param output file descriptor
* \return 0 on success, -1 on failure
*/
static inline void internal_rpc_dump_file_dlg(dlg_cell_t *dlg, FILE* dialogf)
{
dlg_profile_link_t *pl;
dlg_var_t *var;
srjson_doc_t jdoc;
srjson_t * jdoc_caller = NULL;
srjson_t * jdoc_callee = NULL;
srjson_t * jdoc_profiles = NULL;
srjson_t * jdoc_variables = NULL;

srjson_InitDoc(&jdoc, NULL);
jdoc.root = srjson_CreateObject(&jdoc);
if (!jdoc.root) {
LM_ERR("cannot create json\n");
goto clear;
}
srjson_AddNumberToObject(&jdoc, jdoc.root, "h_entry", dlg->h_entry);
srjson_AddNumberToObject(&jdoc, jdoc.root, "h_id", dlg->h_id);
srjson_AddNumberToObject(&jdoc, jdoc.root, "ref", dlg->ref);
srjson_AddStrToObject(&jdoc, jdoc.root, "call_id", dlg->callid.s, dlg->callid.len);
srjson_AddStrToObject(&jdoc, jdoc.root, "from_uri", dlg->from_uri.s, dlg->from_uri.len);
srjson_AddStrToObject(&jdoc, jdoc.root, "to_uri", dlg->to_uri.s, dlg->to_uri.len);
srjson_AddNumberToObject(&jdoc, jdoc.root, "state", dlg->state);
srjson_AddNumberToObject(&jdoc, jdoc.root, "start_ts", dlg->start_ts);
srjson_AddNumberToObject(&jdoc, jdoc.root, "init_ts", dlg->init_ts);
srjson_AddNumberToObject(&jdoc, jdoc.root, "end_ts", dlg->end_ts);
srjson_AddNumberToObject(&jdoc, jdoc.root, "timeout", dlg->tl.timeout ? time(0) + dlg->tl.timeout - get_ticks() : 0);
srjson_AddNumberToObject(&jdoc, jdoc.root, "lifetime", dlg->lifetime);
srjson_AddNumberToObject(&jdoc, jdoc.root, "dflags", dlg->dflags);
srjson_AddNumberToObject(&jdoc, jdoc.root, "sflags", dlg->sflags);
srjson_AddNumberToObject(&jdoc, jdoc.root, "iflags", dlg->iflags);

jdoc_caller = srjson_CreateObject(&jdoc);
if (!jdoc_caller) {
LM_ERR("cannot create json caller\n");
goto clear;
}
srjson_AddStrToObject(&jdoc, jdoc_caller, "tag", dlg->tag[DLG_CALLER_LEG].s, dlg->tag[DLG_CALLER_LEG].len);
srjson_AddStrToObject(&jdoc, jdoc_caller, "contact", dlg->contact[DLG_CALLER_LEG].s, dlg->contact[DLG_CALLER_LEG].len);
srjson_AddStrToObject(&jdoc, jdoc_caller, "cseq", dlg->cseq[DLG_CALLER_LEG].s, dlg->cseq[DLG_CALLER_LEG].len);
srjson_AddStrToObject(&jdoc, jdoc_caller, "route_set", dlg->route_set[DLG_CALLER_LEG].s, dlg->route_set[DLG_CALLER_LEG].len);
srjson_AddStrToObject(&jdoc, jdoc_caller, "socket",
dlg->bind_addr[DLG_CALLER_LEG] ? dlg->bind_addr[DLG_CALLER_LEG]->sock_str.s : empty_str.s,
dlg->bind_addr[DLG_CALLER_LEG] ? dlg->bind_addr[DLG_CALLER_LEG]->sock_str.len : empty_str.len);
srjson_AddItemToObject(&jdoc, jdoc.root, "caller", jdoc_caller);

jdoc_callee = srjson_CreateObject(&jdoc);
if (!jdoc_callee) {
LM_ERR("cannot create json callee\n");
goto clear;
}
srjson_AddStrToObject(&jdoc, jdoc_callee, "tag", dlg->tag[DLG_CALLEE_LEG].s, dlg->tag[DLG_CALLEE_LEG].len);
srjson_AddStrToObject(&jdoc, jdoc_callee, "contact", dlg->contact[DLG_CALLEE_LEG].s, dlg->contact[DLG_CALLEE_LEG].len);
srjson_AddStrToObject(&jdoc, jdoc_callee, "cseq", dlg->cseq[DLG_CALLEE_LEG].s, dlg->cseq[DLG_CALLEE_LEG].len);
srjson_AddStrToObject(&jdoc, jdoc_callee, "route_set", dlg->route_set[DLG_CALLEE_LEG].s, dlg->route_set[DLG_CALLEE_LEG].len);
srjson_AddStrToObject(&jdoc, jdoc_callee, "socket",
dlg->bind_addr[DLG_CALLEE_LEG] ? dlg->bind_addr[DLG_CALLEE_LEG]->sock_str.s : empty_str.s,
dlg->bind_addr[DLG_CALLEE_LEG] ? dlg->bind_addr[DLG_CALLEE_LEG]->sock_str.len : empty_str.len);
srjson_AddItemToObject(&jdoc, jdoc.root, "callee", jdoc_callee);

// profiles section
jdoc_profiles = srjson_CreateObject(&jdoc);
if (!jdoc_profiles) {
LM_ERR("cannot create json profiles\n");
goto clear;
}
for (pl = dlg->profile_links ; pl && (dlg->state<DLG_STATE_DELETED) ; pl=pl->next) {
if (pl->profile->has_value) {
srjson_AddStrToObject(&jdoc, jdoc_profiles, pl->profile->name.s, pl->hash_linker.value.s, pl->hash_linker.value.len);
} else {
srjson_AddStrToObject(&jdoc, jdoc_profiles, pl->profile->name.s, empty_str.s, empty_str.len);
}
}
srjson_AddItemToObject(&jdoc, jdoc.root, "profiles", jdoc_profiles);

// variables section
jdoc_variables = srjson_CreateObject(&jdoc);
if (!jdoc_variables) {
LM_ERR("cannot create json variables\n");
goto clear;
}
for (var=dlg->vars ; var && (dlg->state<DLG_STATE_DELETED) ; var=var->next) {
srjson_AddStrToObject(&jdoc, jdoc_variables, var->key.s, var->value.s, var->value.len);
}
srjson_AddItemToObject(&jdoc, jdoc.root, "variables", jdoc_variables);

// serialize and print to file
jdoc.buf.s = srjson_PrintUnformatted(&jdoc, jdoc.root);
if (!jdoc.buf.s) {
LM_ERR("unable to serialize data\n");
goto clear;
}
jdoc.buf.len = strlen(jdoc.buf.s);
LM_DBG("sending serialized data %.*s\n", jdoc.buf.len, jdoc.buf.s);
fprintf(dialogf,"%s\n", jdoc.buf.s);

clear:
if (jdoc.buf.s) {
jdoc.free_fn(jdoc.buf.s);
jdoc.buf.s = NULL;
}
srjson_DestroyDoc(&jdoc);
return;
}

/*!
* \brief Helper method that outputs a dialog via the RPC interface
* \see rpc_print_dlg
Expand Down Expand Up @@ -2276,6 +2388,38 @@ static inline void internal_rpc_print_dlg(rpc_t *rpc, void *c, dlg_cell_t *dlg,
return;
}

/*!
* \brief Helper function that outputs all dialogs via the RPC interface
* \see rpc_dump_file_dlgs
* \param rpc RPC node that should be filled
* \param c RPC void pointer
* \param with_context if 1 then the dialog context will be also printed
*/
static void internal_rpc_dump_file_dlgs(rpc_t *rpc, void *c, int with_context)
{
dlg_cell_t *dlg;
str output_file_name;
FILE* dialogf;
unsigned int i;
if (rpc->scan(c, ".S", &output_file_name) < 1) return;

dialogf = fopen(output_file_name.s, "a+");
if (!dialogf) {
LM_ERR("failed to open output file: %s\n", output_file_name.s);
return;
}

for( i=0 ; i<d_table->size ; i++ ) {
dlg_lock( d_table, &(d_table->entries[i]) );

for( dlg=d_table->entries[i].first ; dlg ; dlg=dlg->next ) {
internal_rpc_dump_file_dlg(dlg, dialogf);
}
dlg_unlock( d_table, &(d_table->entries[i]) );
}
fclose(dialogf);
}

/*!
* \brief Helper function that outputs all dialogs via the RPC interface
* \see rpc_print_dlgs
Expand Down Expand Up @@ -2415,6 +2559,9 @@ static int w_dlg_set_ruri(sip_msg_t *msg, char *p1, char *p2)
static const char *rpc_print_dlgs_doc[2] = {
"Print all dialogs", 0
};
static const char *rpc_dump_file_dlgs_doc[2] = {
"Print all dialogs to json file", 0
};
static const char *rpc_print_dlgs_ctx_doc[2] = {
"Print all dialogs with associated context", 0
};
Expand Down Expand Up @@ -2459,6 +2606,9 @@ static const char *rpc_dlg_is_alive_doc[2] = {
static void rpc_print_dlgs(rpc_t *rpc, void *c) {
internal_rpc_print_dlgs(rpc, c, 0);
}
static void rpc_dump_file_dlgs(rpc_t *rpc, void *c) {
internal_rpc_dump_file_dlgs(rpc, c, 0);
}
static void rpc_print_dlgs_ctx(rpc_t *rpc, void *c) {
internal_rpc_print_dlgs(rpc, c, 1);
}
Expand Down Expand Up @@ -2946,6 +3096,7 @@ static void rpc_dlg_briefing(rpc_t *rpc, void *c)
static rpc_export_t rpc_methods[] = {
{"dlg.briefing", rpc_dlg_briefing, rpc_dlg_briefing_doc, RET_ARRAY},
{"dlg.list", rpc_print_dlgs, rpc_print_dlgs_doc, RET_ARRAY},
{"dlg.dump_file", rpc_dump_file_dlgs, rpc_dump_file_dlgs_doc, 0},
{"dlg.list_ctx", rpc_print_dlgs_ctx, rpc_print_dlgs_ctx_doc, RET_ARRAY},
{"dlg.list_match", rpc_dlg_list_match, rpc_dlg_list_match_doc, RET_ARRAY},
{"dlg.list_match_ctx", rpc_dlg_list_match_ctx, rpc_dlg_list_match_ctx_doc, RET_ARRAY},
Expand Down
18 changes: 18 additions & 0 deletions src/modules/dialog/doc/dialog_admin.xml
Expand Up @@ -2537,6 +2537,24 @@ dlg_reset_property("timeout-noreset");
</programlisting>
</section>

<section id="dlg.r.dump_file">
<title>dlg.dump_file</title>
<para>Dump all dialogs in a json file. (much faster than dlg.list)</para>
<para>Name: <emphasis>dlg.dump_file</emphasis></para>
<para>Parameters:</para>
<itemizedlist>
<listitem><para>
<emphasis>file name</emphasis> output file name
</para></listitem>
</itemizedlist>
<para>RPC Command Format:</para>
<programlisting format="linespecific">
...
&kamcmd; dlg.dump_file "/tmp/dlg.json"
...
</programlisting>
</section>

<section id="dlg.r.dlg_list">
<title>dlg.dlg_list</title>
<para>
Expand Down

0 comments on commit 776f2f6

Please sign in to comment.