Navigation


Changeset 687:026802543f57 in freeDiameter for libfdproto/messages.c


Ignore:
Timestamp:
Jan 19, 2011, 5:08:21 PM (13 years ago)
Author:
Sebastien Decugis <sdecugis@nict.go.jp>
Branch:
default
Phase:
public
Message:

Prepare for new message log facility

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libfdproto/messages.c

    r686 r687  
    661661
    662662/* Dump a msg_t object */
    663 static void obj_dump_msg (struct msg * msg, int indent )
     663static void obj_dump_msg (struct msg * msg, int indent, FILE * fstr )
    664664{
    665665        int ret = 0;
    666666       
    667         fd_log_debug("%*sMSG: %p\n", INOBJHDRVAL, msg);
     667        fd_log_debug_fstr(fstr, "%*sMSG: %p\n", INOBJHDRVAL, msg);
    668668       
    669669        if (!CHECK_MSG(msg)) {
    670                 fd_log_debug(INOBJHDR "INVALID!\n", INOBJHDRVAL);
     670                fd_log_debug_fstr(fstr, INOBJHDR "INVALID!\n", INOBJHDRVAL);
    671671                return;
    672672        }
     
    674674        if (!msg->msg_model) {
    675675               
    676                 fd_log_debug(INOBJHDR "(no model)\n", INOBJHDRVAL);
     676                fd_log_debug_fstr(fstr, INOBJHDR "(no model)\n", INOBJHDRVAL);
    677677               
    678678        } else {
     
    682682                ret = fd_dict_gettype(msg->msg_model, &dicttype);
    683683                if (ret || (dicttype != DICT_COMMAND)) {
    684                         fd_log_debug(INOBJHDR "(invalid model: %d %d)\n", INOBJHDRVAL, ret, dicttype);
     684                        fd_log_debug_fstr(fstr, INOBJHDR "(invalid model: %d %d)\n", INOBJHDRVAL, ret, dicttype);
    685685                        goto public;
    686686                }
    687687                ret = fd_dict_getval(msg->msg_model, &dictdata);
    688688                if (ret != 0) {
    689                         fd_log_debug(INOBJHDR "(error getting model data: %s)\n", INOBJHDRVAL, strerror(ret));
     689                        fd_log_debug_fstr(fstr, INOBJHDR "(error getting model data: %s)\n", INOBJHDRVAL, strerror(ret));
    690690                        goto public;
    691691                }
    692                 fd_log_debug(INOBJHDR "model : v/m:" DUMP_CMDFL_str "/" DUMP_CMDFL_str ", %u \"%s\"\n", INOBJHDRVAL,
     692                fd_log_debug_fstr(fstr, INOBJHDR "model : v/m:" DUMP_CMDFL_str "/" DUMP_CMDFL_str ", %u \"%s\"\n", INOBJHDRVAL,
    693693                        DUMP_CMDFL_val(dictdata.cmd_flag_val), DUMP_CMDFL_val(dictdata.cmd_flag_mask), dictdata.cmd_code, dictdata.cmd_name);
    694694        }
    695695public:
    696         fd_log_debug(INOBJHDR "public: V:%d L:%d fl:" DUMP_CMDFL_str " CC:%u A:%d hi:%x ei:%x\n", INOBJHDRVAL,
     696        fd_log_debug_fstr(fstr, INOBJHDR "public: V:%d L:%d fl:" DUMP_CMDFL_str " CC:%u A:%d hi:%x ei:%x\n", INOBJHDRVAL,
    697697                msg->msg_public.msg_version,
    698698                msg->msg_public.msg_length,
     
    703703                msg->msg_public.msg_eteid
    704704                );
    705         fd_log_debug(INOBJHDR "intern: rwb:%p rt:%d cb:%p(%p) qry:%p asso:%d sess:%p src:%s\n",
     705        fd_log_debug_fstr(fstr, INOBJHDR "intern: rwb:%p rt:%d cb:%p(%p) qry:%p asso:%d sess:%p src:%s\n",
    706706                        INOBJHDRVAL, msg->msg_rawbuffer, msg->msg_routable, msg->msg_cb.fct, msg->msg_cb.data, msg->msg_query, msg->msg_associated, msg->msg_sess, msg->msg_src_id?:"(nil)");
    707707}
    708708
    709709/* Dump an avp object */
    710 static void obj_dump_avp ( struct avp * avp, int indent )
     710static void obj_dump_avp ( struct avp * avp, int indent, FILE * fstr )
    711711{
    712712        int ret = 0;
     
    714714       
    715715        if (!CHECK_AVP(avp)) {
    716                 fd_log_debug(INOBJHDR "INVALID!\n", INOBJHDRVAL);
     716                fd_log_debug_fstr(fstr, INOBJHDR "INVALID!\n", INOBJHDRVAL);
    717717                return;
    718718        }
     
    720720        if (!avp->avp_model) {
    721721               
    722                 fd_log_debug(INOBJHDR "(no model)\n", INOBJHDRVAL);
     722                fd_log_debug_fstr(fstr, INOBJHDR "(no model)\n", INOBJHDRVAL);
    723723               
    724724        } else {
     
    728728                ret = fd_dict_gettype(avp->avp_model, &dicttype);
    729729                if (ret || (dicttype != DICT_AVP)) {
    730                         fd_log_debug(INOBJHDR "(invalid model: %d %d)\n", INOBJHDRVAL, ret, dicttype);
     730                        fd_log_debug_fstr(fstr, INOBJHDR "(invalid model: %d %d)\n", INOBJHDRVAL, ret, dicttype);
    731731                        goto public;
    732732                }
    733733                ret = fd_dict_getval(avp->avp_model, &dictdata);
    734734                if (ret != 0) {
    735                         fd_log_debug(INOBJHDR "(error getting model data: %s)\n", INOBJHDRVAL, strerror(ret));
     735                        fd_log_debug_fstr(fstr, INOBJHDR "(error getting model data: %s)\n", INOBJHDRVAL, strerror(ret));
    736736                        goto public;
    737737                }
    738                 fd_log_debug(INOBJHDR "model : v/m:" DUMP_AVPFL_str "/" DUMP_AVPFL_str ", %12s, %u \"%s\"\n", INOBJHDRVAL,
     738                fd_log_debug_fstr(fstr, INOBJHDR "model : v/m:" DUMP_AVPFL_str "/" DUMP_AVPFL_str ", %12s, %u \"%s\"\n", INOBJHDRVAL,
    739739                        DUMP_AVPFL_val(dictdata.avp_flag_val),
    740740                        DUMP_AVPFL_val(dictdata.avp_flag_mask),
     
    745745        }
    746746public:
    747         fd_log_debug(INOBJHDR "public: C:%u fl:" DUMP_AVPFL_str " L:%d V:%u  data:@%p\n", INOBJHDRVAL,
     747        fd_log_debug_fstr(fstr, INOBJHDR "public: C:%u fl:" DUMP_AVPFL_str " L:%d V:%u  data:@%p\n", INOBJHDRVAL,
    748748                avp->avp_public.avp_code,
    749749                DUMP_AVPFL_val(avp->avp_public.avp_flags),
     
    755755        if (avp->avp_public.avp_value) {
    756756                if (!avp->avp_model) {
    757                         fd_log_debug(INOBJHDR "(data set but no model: ERROR)\n", INOBJHDRVAL);
     757                        fd_log_debug_fstr(fstr, INOBJHDR "(data set but no model: ERROR)\n", INOBJHDRVAL);
    758758                } else {
    759                         fd_dict_dump_avp_value(avp->avp_public.avp_value, avp->avp_model, indent);
    760                 }
    761         }
    762 
    763         fd_log_debug(INOBJHDR "intern: src:%p mf:%d raw:%p(%d)\n", INOBJHDRVAL, avp->avp_source, avp->avp_mustfreeos, avp->avp_rawdata, avp->avp_rawlen);
     759                        fd_dict_dump_avp_value(avp->avp_public.avp_value, avp->avp_model, indent, fstr);
     760                }
     761        }
     762
     763        fd_log_debug_fstr(fstr, INOBJHDR "intern: src:%p mf:%d raw:%p(%d)\n", INOBJHDRVAL, avp->avp_source, avp->avp_mustfreeos, avp->avp_rawdata, avp->avp_rawlen);
    764764}
    765765
    766766/* Dump a single object content */
    767 static void msg_dump_intern ( int level, msg_or_avp * obj, int indent )
     767static void msg_dump_intern ( int level, msg_or_avp * obj, int indent, FILE * fstr )
    768768{
    769769        /* Log only if we are at least at level */
     
    773773        /* Check the object */
    774774        if (!VALIDATE_OBJ(obj)) {
    775                 fd_log_debug( ">>> invalid object (%p)!.\n", obj);
     775                fd_log_debug_fstr(fstr, ">>> invalid object (%p)!.\n", obj);
    776776                return;
    777777        }
     
    780780        switch (_C(obj)->type) {
    781781                case MSG_AVP:
    782                         obj_dump_avp ( _A(obj), indent );
     782                        obj_dump_avp ( _A(obj), indent, fstr );
    783783                        break;
    784784               
    785785                case MSG_MSG:
    786                         obj_dump_msg ( _M(obj), indent );
     786                        obj_dump_msg ( _M(obj), indent, fstr );
    787787                        break;
    788788               
     
    792792}
    793793
     794/* Dump a message to a specified file stream */
     795static void fd_msg_dump_fstr ( struct msg * msg, FILE * fstr )
     796{
     797        msg_or_avp * ref = msg;
     798        int indent = 2;
     799        do {
     800                msg_dump_intern ( NONE, ref, indent, fstr );
     801               
     802                /* Now find the next object */
     803                CHECK_FCT_DO(  fd_msg_browse ( ref, MSG_BRW_WALK, &ref, &indent ), break  );
     804               
     805                /* dump next object */
     806        } while (ref);
     807}
     808
    794809/* Dump a message content -- for debug mostly */
    795810void fd_msg_dump_walk ( int level, msg_or_avp *obj )
     
    800815        TRACE_DEBUG(level, "------ Dumping object %p (w)-------", obj);
    801816        do {
    802                 msg_dump_intern ( level, ref, indent );
     817                msg_dump_intern ( level, ref, indent, fd_g_debug_fstr );
    803818               
    804819                /* Now find the next object */
     
    815830{
    816831        TRACE_DEBUG(level, "------ Dumping object %p (s)-------", obj);
    817         msg_dump_intern ( level, obj, 1 );
     832        msg_dump_intern ( level, obj, 1, fd_g_debug_fstr );
    818833        TRACE_DEBUG(level, "------ /end of object %p -------", obj);
    819834}
     
    16451660                if (mandatory && (avp->avp_public.avp_flags & AVP_FLAG_MANDATORY)) {
    16461661                        TRACE_DEBUG(INFO, "Unsupported mandatory AVP found:");
    1647                         msg_dump_intern(INFO, avp, 2);
     1662                        msg_dump_intern(INFO, avp, 2, fd_g_debug_fstr);
    16481663                        if (error_info) {
    16491664                                error_info->pei_errcode = "DIAMETER_AVP_UNSUPPORTED";
     
    23092324        return ret;
    23102325}
     2326
     2327
     2328/***************************************************************************************************************/
     2329/* messages logging facility */
     2330#include <stdarg.h>
     2331
     2332static struct {
     2333        struct {
     2334                enum fd_msg_log_method  meth;
     2335                const char *            metharg;
     2336        } causes[FD_MSG_LOG_MAX + 1];
     2337        pthread_mutex_t lock;
     2338        int             init;
     2339} ml_conf = { .lock = PTHREAD_MUTEX_INITIALIZER, .init = 0 };
     2340
     2341static void ml_conf_init(void)
     2342{
     2343        memset(&ml_conf.causes, 0, sizeof(ml_conf.causes));
     2344        ml_conf.init = 1;
     2345}
     2346
     2347/* Set a configuration property */
     2348int fd_msg_log_config(enum fd_msg_log_cause cause, enum fd_msg_log_method method, const char * arg)
     2349{
     2350        /* Check the parameters are valid */
     2351        TRACE_ENTRY("%d %d %p", cause, method, arg);
     2352        CHECK_PARAMS( (cause >= 0) && (cause <= FD_MSG_LOG_MAX) );
     2353        CHECK_PARAMS( (method >= FD_MSG_LOGTO_DEBUGONLY) && (method <= FD_MSG_LOGTO_DIR) );
     2354        CHECK_PARAMS( (method == FD_MSG_LOGTO_DEBUGONLY) || (arg != NULL) );
     2355       
     2356        /* Lock the configuration */
     2357        CHECK_POSIX( pthread_mutex_lock(&ml_conf.lock) );
     2358        if (!ml_conf.init) {
     2359                ml_conf_init();
     2360        }
     2361       
     2362        /* Now set the parameter */
     2363        ml_conf.causes[cause].meth = method;
     2364        ml_conf.causes[cause].metharg = arg;
     2365       
     2366        if (method) {
     2367                TRACE_DEBUG(INFO, "Logging %s messages set to %s '%s'",
     2368                        (cause == FD_MSG_LOG_DROPPED) ? "DROPPED" :
     2369                                (cause == FD_MSG_LOG_RECEIVED) ? "RECEIVED" :
     2370                                        (cause == FD_MSG_LOG_SENT) ? "SENT" :
     2371                                                "???",
     2372                        (method == FD_MSG_LOGTO_FILE) ? "file" :
     2373                                (method == FD_MSG_LOGTO_DIR) ? "directory" :
     2374                                        "???",
     2375                        arg);
     2376        }
     2377       
     2378        CHECK_POSIX( pthread_mutex_unlock(&ml_conf.lock) );
     2379       
     2380        /* Done */
     2381        return 0;
     2382}
     2383
     2384/* Do not log anything within this one, since log lock is held */
     2385static void fd_cleanup_mutex_silent( void * mutex )
     2386{
     2387        (void)pthread_mutex_unlock((pthread_mutex_t *)mutex);
     2388}
     2389
     2390/* Really log the message */
     2391void fd_msg_log( enum fd_msg_log_cause cause, struct msg * msg, const char * prefix_format, ... )
     2392{
     2393        va_list ap;
     2394        enum fd_msg_log_method  meth;
     2395        const char *            metharg;
     2396        FILE * fstr;
     2397       
     2398        TRACE_ENTRY("%d %p %p", cause, msg, prefix_format);
     2399        CHECK_PARAMS_DO( (cause >= 0) && (cause <= FD_MSG_LOG_MAX),
     2400        {
     2401                TRACE_DEBUG(INFO, "Invalid cause received (%d)! Message was:", cause);
     2402                fd_msg_dump_walk(INFO, msg);
     2403        } );
     2404       
     2405        /* First retrieve the config for this message */
     2406        CHECK_POSIX_DO( pthread_mutex_lock(&ml_conf.lock), );
     2407        if (!ml_conf.init) {
     2408                ml_conf_init();
     2409        }
     2410        meth    = ml_conf.causes[cause].meth;
     2411        metharg = ml_conf.causes[cause].metharg;
     2412        CHECK_POSIX_DO( pthread_mutex_unlock(&ml_conf.lock), );
     2413       
     2414        /* Okay, now we will create the file descriptor */
     2415        switch (meth) {
     2416                case FD_MSG_LOGTO_DEBUGONLY:
     2417                        fstr = fd_g_debug_fstr;
     2418                        break;
     2419                       
     2420                case FD_MSG_LOGTO_FILE:
     2421                        TODO("Log to arg file");
     2422                        break;
     2423                case FD_MSG_LOGTO_DIR:
     2424                        TODO("Log to arg directory in a new file");
     2425                        break;
     2426        }
     2427       
     2428        /* Then dump the prefix message to this stream */
     2429        (void)pthread_mutex_lock(&fd_log_lock);
     2430        pthread_cleanup_push(fd_cleanup_mutex_silent, &fd_log_lock);
     2431        va_start(ap, prefix_format);
     2432        vfprintf( fstr, prefix_format, ap);
     2433        va_end(ap);
     2434        fflush(fstr);
     2435        pthread_cleanup_pop(0);
     2436        (void)pthread_mutex_unlock(&fd_log_lock);
     2437        fd_log_debug_fstr(fstr, "\n\n");
     2438       
     2439        /* And now the message itself */
     2440        fd_msg_dump_fstr(msg, fstr);
     2441       
     2442        /* And finally close the stream if needed */
     2443        TODO("close?");
     2444}
     2445
Note: See TracChangeset for help on using the changeset viewer.