加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
xlog.c 11.59 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
/**
* Copyright (C) 2001-2003 FhG Fokus
*
* This file is part of opensips, a free SIP server.
*
* opensips is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version
*
* opensips is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <ctype.h>
#include "sr_module.h"
#include "dprint.h"
#include "error.h"
#include "socket_info.h"
#include "mem/mem.h"
#include "xlog.h"
#include "pvar.h"
#include "trace_api.h"
#define XLOG_TRACE_API_MODULE "proto_hep"
#define XLOG_CORRELATION_MAGIC "XLOGCORR"
char *log_buf = NULL;
int xlog_buf_size = 4096;
int xlog_force_color = 0;
/* the log level used when printing xlog messages */
int xlog_print_level = L_NOTICE;
/* the logging level/threshold for filtering the xlog messages for printing */
static int xlog_level_default = L_NOTICE;
static int xlog_level_local = L_NOTICE;
static int *xlog_level_shared = NULL;
/* current logging level for this process.
* During init it points the 'xlog_level_default' in order to store the
* original configured value
* During runtime it may point to:
* - xlog_level_shared - the shared xlog level between all procs
* - &xlog_level_local - for a per-proc changed xlog level
*/
int *xlog_level = &xlog_level_default;
/* id with which xlog will be identified by siptrace module
* and will identify an xlog tracing packet */
int xlog_proto_id;
/* tracing module api */
static trace_proto_t tprot;
/* xlog string identifier */
static const char* xlog_id_s="xlog";
#define is_xlog_printable(_level) \
(((int)(*xlog_level)) >= ((int)(_level)))
void set_shared_xlog_level(int new_level)
{
/* do not accept setting as time the xlog_level still points to the
* starting/default holder as we will loose the original value */
if (xlog_level==&xlog_level_default)
return;
*xlog_level_shared = new_level;
}
void set_local_xlog_level(int new_level)
{
/* do not accept setting as time the xlog_level still points to the
* starting/default holder as we will loose the original value */
if (xlog_level==&xlog_level_default)
return;
xlog_level_local = new_level;
xlog_level = &xlog_level_local;
}
void reset_xlog_level(void)
{
if (xlog_level==&xlog_level_default)
return; /* still init, very unlikely */
if (xlog_level==&xlog_level_local) {
/* points a local/per-proc xlog level hodler,
* so reset it to the shared value */
xlog_level = xlog_level_shared;
return;
}
/* points to the shared holder, so reset the shred value */
*xlog_level_shared = xlog_level_default;
}
static int buf_init(void)
{
LM_DBG("initializing...\n");
log_buf = (char*)pkg_malloc((xlog_buf_size+1)*sizeof(char));
if(log_buf==NULL)
{
LM_ERR("no pkg memory left\n");
return -1;
}
return 0;
}
int init_xlog(void)
{
if (log_buf == NULL) {
if (buf_init()) {
LM_ERR("Cannot print message!\n");
return -1;
}
}
xlog_level_shared = (int*)shm_malloc(sizeof(int));
if (xlog_level_shared==NULL) {
LM_ERR("failed to allocate shared holder for xlog\n");
return -1;
}
xlog_level = xlog_level_shared;
*xlog_level = xlog_level_default;
if (register_trace_type)
xlog_proto_id = register_trace_type((char *)xlog_id_s);
memset(&tprot, 0, sizeof(trace_proto_t));
if (global_trace_api) {
memcpy(&tprot, global_trace_api, sizeof(trace_proto_t));
} else {
if (trace_prot_bind(XLOG_TRACE_API_MODULE, &tprot)) {
LM_DBG("failed to load trace protocol!\n");
}
}
return 0;
}
static inline void add_xlog_data(trace_message message, void* param)
{
str str_level;
xl_trace_t* xtrace_param = param;
static str sip_str = str_init("sip");
switch (*xlog_level) {
case L_ALERT:
str_level.s = DP_ALERT_TEXT; break;
case L_CRIT:
str_level.s = DP_CRIT_TEXT; break;
case L_ERR:
str_level.s = DP_ERR_TEXT; break;
case L_WARN:
str_level.s = DP_WARN_TEXT; break;
case L_NOTICE:
str_level.s = DP_NOTICE_TEXT; break;
case L_INFO:
str_level.s = DP_INFO_TEXT; break;
case L_DBG:
str_level.s = DP_DBG_TEXT;
str_level.len = sizeof(DP_DBG_TEXT) - 2;
break;
default:
LM_BUG("Unexpected log level [%d]\n", xlog_print_level);
return;
}
/* remove ':' after each level */
str_level.len = strlen(str_level.s) - 1;
tprot.add_payload_part( message, "Event", &str_level);
if ( !xtrace_param )
return;
tprot.add_payload_part( message, "text", &xtrace_param->buf);
if (xtrace_param->msg && xtrace_param->msg->callid)
tprot.add_extra_correlation( message, &sip_str, &xtrace_param->msg->callid->body );
}
static inline int trace_xlog(struct sip_msg* msg, char* buf, int len)
{
struct modify_trace mod_p;
xl_trace_t xtrace_param;
str correlation_str;
union sockaddr_union su;
if (msg == NULL || buf == NULL) {
LM_ERR("bad input!\n");
return -1;
}
/* xlog not traced; exit... */
if (!check_is_traced || check_is_traced(xlog_proto_id) == 0)
return 0;
mod_p.mod_f = add_xlog_data;
xtrace_param.msg = msg;
xtrace_param.buf.s = buf;
xtrace_param.buf.len = len;
mod_p.param = &xtrace_param;
if (msg->callid && msg->callid->body.len) {
correlation_str = msg->callid->body;
} else {
correlation_str.s = "<null>";
correlation_str.len = 6;
}
if (msg->rcv.bind_address && msg->rcv.bind_address->port_no)
/* coverity[check_return] - CID #211391 */
init_su( &su, &msg->rcv.bind_address->address,
msg->rcv.bind_address->port_no);
else
su.s.sa_family = 0;
if (sip_context_trace(xlog_proto_id,
su.s.sa_family ? &su : NULL /*src*/, su.s.sa_family ? &su : NULL /*dst*/,
0, IPPROTO_TCP,
&correlation_str, &mod_p) < 0) {
LM_ERR("failed to trace xlog message!\n");
return -1;
}
return 0;
}
int xl_print_log(struct sip_msg* msg, pv_elem_p list, int *len)
{
if (pv_printf(msg, list, log_buf, len) < 0)
return -1;
if (trace_xlog(msg, log_buf, *len) < 0) {
LM_ERR("failed to trace xlog message!\n");
return -2;
}
return 1;
}
int xlog_2(struct sip_msg* msg, char* lev, char* frm)
{
int log_len, ret;
long level;
xl_level_p xlp;
pv_value_t value;
xlp = (xl_level_t*)(void*)lev;
if(xlp->type==1)
{
if(pv_get_spec_value(msg, &xlp->v.sp, &value)!=0
|| value.flags&PV_VAL_NULL || !(value.flags&PV_VAL_INT))
{
LM_ERR("invalid log level value [%d]\n", value.flags);
return -1;
}
level = (long)value.ri;
} else {
level = xlp->v.level;
}
if(!is_xlog_printable((int)level))
return 1;
log_len = xlog_buf_size;
ret = xl_print_log(msg, (pv_elem_t*)(void*)frm, &log_len);
if (ret == -1) {
LM_ERR("global print buffer too small, increase 'xlog_buf_size'\n");
return -1;
}
/* set the xlog as log level to trick "LM_GEN" */
set_proc_log_level( *xlog_level );
/* log_buf[log_len] = '\0'; */
LM_GEN1((int)level, "%.*s", log_len, log_buf);
reset_proc_log_level();
return ret;
}
int xlog_1(struct sip_msg* msg, char* frm)
{
int log_len, ret;
if(!is_xlog_printable(xlog_print_level))
return 1;
log_len = xlog_buf_size;
ret = xl_print_log(msg, (pv_elem_t*)(void*)frm, &log_len);
if (ret == -1) {
LM_ERR("global print buffer too small, increase 'xlog_buf_size'\n");
return -1;
}
/* set the xlog as log level to trick "LM_GEN" */
set_proc_log_level( *xlog_level );
/* log_buf[log_len] = '\0'; */
LM_GEN1(xlog_print_level, "%.*s", log_len, log_buf);
reset_proc_log_level();
return ret;
}
/**
*/
int xdbg(struct sip_msg* msg, char* frm)
{
int log_len, ret;
if(!is_xlog_printable(L_DBG))
return 1;
log_len = xlog_buf_size;
ret = xl_print_log(msg, (pv_elem_t*)(void*)frm, &log_len);
if (ret == -1) {
LM_ERR("global print buffer too small, increase 'xlog_buf_size'\n");
return -1;
}
/* set the xlog as log level to trick "LM_GEN" */
set_proc_log_level( *xlog_level );
/* log_buf[log_len] = '\0'; */
LM_GEN1(L_DBG, "%.*s", log_len, log_buf);
reset_proc_log_level();
return ret;
}
int pv_parse_color_name(pv_spec_p sp, const str *in)
{
if(in==NULL || in->s==NULL || sp==NULL)
return -1;
if(in->len != 2)
{
LM_ERR("color name must have two chars\n");
return -1;
}
/* foreground */
switch(in->s[0])
{
case 'x':
case 's': case 'r': case 'g':
case 'y': case 'b': case 'p':
case 'c': case 'w': case 'S':
case 'R': case 'G': case 'Y':
case 'B': case 'P': case 'C':
case 'W':
break;
default:
goto error;
}
/* background */
switch(in->s[1])
{
case 'x':
case 's': case 'r': case 'g':
case 'y': case 'b': case 'p':
case 'c': case 'w':
break;
default:
goto error;
}
sp->pvp.pvn.type = PV_NAME_INTSTR;
sp->pvp.pvn.u.isname.type = AVP_NAME_STR;
sp->pvp.pvn.u.isname.name.s = *in;
sp->getf = pv_get_color;
/* force the color PV type */
sp->type = PVT_COLOR;
return 0;
error:
LM_ERR("invalid color name\n");
return -1;
}
#define COL_BUF 10
#define append_sstring(p, end, s) \
do{\
if ((p)+(sizeof(s)-1)<=(end)){\
memcpy((p), s, sizeof(s)-1); \
(p)+=sizeof(s)-1; \
}else{ \
/* overflow */ \
LM_ERR("append_sstring overflow\n"); \
goto error;\
} \
} while(0)
int pv_get_color(struct sip_msg *msg, pv_param_t *param,
pv_value_t *res)
{
static char color[COL_BUF];
char* p;
char* end;
str s;
if(xlog_force_color==0)
{
s.s = "";
s.len = 0;
return pv_get_strval(msg, param, res, &s);
}
p = color;
end = p + COL_BUF;
/* excape sequenz */
append_sstring(p, end, "\033[");
if(param->pvn.u.isname.name.s.s[0]!='_')
{
if (islower((int)param->pvn.u.isname.name.s.s[0]))
{
/* normal font */
append_sstring(p, end, "0;");
} else {
/* bold font */
append_sstring(p, end, "1;");
param->pvn.u.isname.name.s.s[0] += 32;
}
}
/* foreground */
switch(param->pvn.u.isname.name.s.s[0])
{
case 'x':
append_sstring(p, end, "39;");
break;
case 's':
append_sstring(p, end, "30;");
break;
case 'r':
append_sstring(p, end, "31;");
break;
case 'g':
append_sstring(p, end, "32;");
break;
case 'y':
append_sstring(p, end, "33;");
break;
case 'b':
append_sstring(p, end, "34;");
break;
case 'p':
append_sstring(p, end, "35;");
break;
case 'c':
append_sstring(p, end, "36;");
break;
case 'w':
append_sstring(p, end, "37;");
break;
default:
LM_ERR("invalid foreground\n");
return pv_get_null(msg, param, res);
}
/* background */
switch(param->pvn.u.isname.name.s.s[1])
{
case 'x':
append_sstring(p, end, "49");
break;
case 's':
append_sstring(p, end, "40");
break;
case 'r':
append_sstring(p, end, "41");
break;
case 'g':
append_sstring(p, end, "42");
break;
case 'y':
append_sstring(p, end, "43");
break;
case 'b':
append_sstring(p, end, "44");
break;
case 'p':
append_sstring(p, end, "45");
break;
case 'c':
append_sstring(p, end, "46");
break;
case 'w':
append_sstring(p, end, "47");
break;
default:
LM_ERR("invalid background\n");
return pv_get_null(msg, param, res);
}
/* end */
append_sstring(p, end, "m");
s.s = color;
s.len = p-color;
return pv_get_strval(msg, param, res, &s);
error:
return -1;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化