modules/up/src/Core/util/Trail.cc

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. EnabledTrace
  2. EnabledTrace
  3. Trail
  4. Trail
  5. trace
  6. log
  7. Trace
  8. Trace
  9. enable
  10. disable
  11. makeStatusKnown
  12. isDisabled
  13. isEnabled
  14. isUnknown
  15. name

//
// $Id: Trail.cc,v 1.1.1.1 2000/03/10 16:32:20 engin Exp $
//
// Trail.cc
// Author: Ramesh Govindan <govindan@isi.edu>
//
// Tracing implementation

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <cstdio>
#include <cstdlib>
#include <cstdarg>

#include "util/Types.hh"
#include "util/Trail.hh"
#include "sched/Dispatcher.hh"

extern "C" {
#include <sys/types.h>
#include <syslog.h>
#include <string.h>    

#ifndef STDC_HEADERS
extern void openlog(const char*, int, int);
extern void syslog(int, const char*, ...);
extern void closelog(void);
extern int setlinebuf(...);
#endif
}

#ifndef LOG_LOCAL0
#define LOG_LOCAL0      (16 << 3)
#endif // LOG_LOCAL0

// Globals
Trail*          systemTrail = NULL;
TrailConfig     trailConfig;

// Constants
const int       MaxTraceBufferSize  = 1024;

EnabledTrace::EnabledTrace(char* n)
/* [<][>][^][v][top][bottom][index][help] */
        : ListNode()
{
    name = new char[strlen(n)+1];
    strcpy(name, n);
    return;
}

EnabledTrace::~EnabledTrace()
/* [<][>][^][v][top][bottom][index][help] */
{
    delete [] name;
}

Trail::Trail(char *programName)
/* [<][>][^][v][top][bottom][index][help] */
{
    buffer = new char[MaxTraceBufferSize];
    dispatcher.systemClock.sync();
    start = dispatcher.systemClock;

    // Open the log if necessary
    if (trailConfig.background) {
        int     l;
        
        l = LOG_LOCAL0;
        if (trailConfig.logLevel <= 7) {        // Is this kosher?
            l += (trailConfig.logLevel << 3);
        }
        trailConfig.logLevel = l;
        openlog(programName, LOG_PID | LOG_NDELAY, trailConfig.logLevel);
    }
    return;
}

Trail::~Trail()
/* [<][>][^][v][top][bottom][index][help] */
{
    trailConfig.enabled.clear();
    closelog();
}

void
Trail::trace(const char *func,
/* [<][>][^][v][top][bottom][index][help] */
             TraceCode& code,
             const char *fmt,
             ...)
{
    va_list ap;
    
    // cengiz 
    // return immediately if this trace is disabled
    if (code.isDisabled()) {
        return;
    }

    // it is a bug to return w/o va_end after a va_start
    va_start(ap, fmt);
#ifdef HAVE_VSNPRINTF
    (void) vsnprintf(buffer, MaxTraceBufferSize, fmt, ap);
#else
    (void) vsprintf(buffer, fmt, ap);
#endif
    va_end(ap);
    if (trailConfig.background) {
        syslog(trailConfig.logLevel | LOG_DEBUG, 
               "(%s) %s", code.name(), buffer);
    } else {
        if (trailConfig.printTimeStamp) {
           time_t t = time(NULL);
           struct tm *tm = localtime(&t);
  
           fprintf(stderr,
                   "%02d/%02d/%04d %02d:%02d:%02d ", 
                   tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900,
                   tm->tm_hour, tm->tm_min, tm->tm_sec);

           /*
            TimeShort   diff;
        
            dispatcher.systemClock.sync();
            diff = dispatcher.systemClock - start;
            (void) fprintf(stderr,
                           "(%u,%u) ",
                           (u_int) diff.seconds(),
                           (u_int) diff.fraction());
           */
        }
        (void) fprintf(stderr, "(%s) ", code.name());
        (void) fprintf(stderr, "%s", buffer);
        if (trailConfig.printFuncs) {
            (void) fprintf(stderr, "\t\t%.40s\n", func);
        }
    }
    (void) fflush(stderr);
    return;
}

void
Trail::log(Boolean fatal,
/* [<][>][^][v][top][bottom][index][help] */
           const char* func,
           const char* fmt,
           ...)
{
    va_list ap;
    
    va_start(ap, fmt);
#ifdef HAVE_VSNPRINTF
    (void) vsnprintf(buffer, MaxTraceBufferSize, fmt, ap);
#else
    (void) vsprintf(buffer, fmt, ap);
#endif
    va_end(ap);
    if (trailConfig.background) {
        (void) syslog(trailConfig.logLevel | 
                      ((fatal) ? LOG_CRIT : LOG_WARNING), 
                      "%s\t\t%.40s%s\n", buffer, func);
    } else {
        (void) fprintf(stderr, "ERROR in %s: %s", func, buffer);
        (void) fflush(stderr);
    }
    return;
}

TraceCode::Trace(const char* str)
/* [<][>][^][v][top][bottom][index][help] */
{
    nameString = new char[strlen(str)+1];
    strcpy(nameString, str);
    status = TraceStatusUnknown;
}

TraceCode::~Trace()
/* [<][>][^][v][top][bottom][index][help] */
{
  // Modified by wlee
  // delete nameString;
  delete []nameString;
}

void
TraceCode::enable()
/* [<][>][^][v][top][bottom][index][help] */
{
    status = TraceStatusEnabled;
}

void
TraceCode::disable()
/* [<][>][^][v][top][bottom][index][help] */
{
    status = TraceStatusDisabled;
}

inline void TraceCode::makeStatusKnown() {
/* [<][>][^][v][top][bottom][index][help] */
   if (!isUnknown())
      return;

   for (EnabledTrace *et = trailConfig.enabled.head(); 
        et != NULL; 
        et = trailConfig.enabled.next(et))
      if (!strcmp(name(), et->name)) {
         enable();
         return;
      }
   disable();
   return;
}

Boolean
TraceCode::isDisabled()
/* [<][>][^][v][top][bottom][index][help] */
{
    // cengiz modified the following
    if (status == TraceStatusDisabled)
       return true;
    makeStatusKnown();
    
    return (status == TraceStatusDisabled);
}

Boolean
TraceCode::isEnabled()
/* [<][>][^][v][top][bottom][index][help] */
{
    // cengiz modified the following
    if (status == TraceStatusEnabled)
       return true;
    makeStatusKnown();
    
    return (status == TraceStatusEnabled);
}

Boolean
TraceCode::isUnknown()
/* [<][>][^][v][top][bottom][index][help] */
{
    return (status == TraceStatusUnknown);
}

char*
TraceCode::name()
/* [<][>][^][v][top][bottom][index][help] */
{
    return nameString;
}

// 
//  Copyright (c) 1994 by the University of Southern California.
//  All rights reserved.
//
//  Permission to use, copy, modify, and distribute this software and
//  its documentation in source and binary forms for lawful
//  non-commercial purposes and without fee is hereby granted, provided
//  that the above copyright notice appear in all copies and that both
//  the copyright notice and this permission notice appear in supporting
//  documentation, and that any documentation, advertising materials,
//  and other materials related to such distribution and use acknowledge
//  that the software was developed by the University of Southern
//  California and/or Information Sciences Institute.
//  The name of the University of Southern California may not
//  be used to endorse or promote products derived from this software
//  without specific prior written permission.
//
//  THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY REPRESENTATIONS
//  ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE.  THIS SOFTWARE IS
//  PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
//  INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
//  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND 
//  NON-INFRINGEMENT.
//
//  IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
//  SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT,
//  TORT, OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH,
//  THE USE OR PERFORMANCE OF THIS SOFTWARE.
//
//  Questions concerning this software should be directed to 
//  info-ra@isi.edu.
//
//  Author(s): Ramesh Govindan <govindan@isi.edu>


/* [<][>][^][v][top][bottom][index][help] */