/* $Id: log.c,v 10.1 92/10/06 23:10:31 ca Exp $ */ /* 'Cluster' to write happenings to a log file. Contains functions for two different types of log--debugging log parameter logs. */ /*LINTLIBRARY*/ #define LOGSOURCE /* So log.h knows this is the real thing */ #ifdef UNICOS #include #else /* UNICOS */ #include #endif /* UNICOS */ #include #include #include "sim.h" #include "q.h" #include "list.h" #include "mempool.h" #include "hash.h" #include "simx.h" #include "packet.h" #include "event.h" #include "log.h" #include #ifdef DEBUG extern Log debug_log; #endif /**************** Debugging log functions */ Log dbg_create(s) char *s; { return((Log)fopen(s, "w")); } /* When using GCC, this function is made inline--see log.h. */ #ifndef INLINE /* Debugging level--can now be DBG_ERR or DBG_INFO */ static int dbg_level = 0; dbg_set_level(level) int level; { int temp = dbg_level; dbg_level = level; return(temp); } #endif /* not INLINE */ /* Debugging log-- writes name of component along with message */ /*VARARGS4*/ /*dbg_write(l, level, c, format, args)*/ dbg_write(Log l, int level, Component *c, char *format, ... ) { va_list p; if (!(dbg_level & level)) return; /* First put the name into the string */ if (c) { fputs(c->co_name, l); putc(' ', l); } /* Add the time */ fprintf(l, "%d ", ev_now()); va_start(p, format); #ifdef __FreeBSD__ vfprintf(l, format, p); #else _doprnt(format, p, l); #endif va_end(p); fputs("\n\0", l); fflush(l); } dbg_close(l) Log l; { fclose(l); } /************* Parameter logging */ static char *log_param_path = ""; log_param_set_path(path) char *path; { log_param_path = path; } /* * Changed to no longer create a seperate file for each parameter that is * logged. When first called, it opens one file, and all of the logs * are written to that file. */ #ifndef INLINE static FILE *log_fp = NULL; #endif /* not INLINE */ extern int seed; static log_param_open_file() { char name[500]; int accessible; /* Create file name by appending the PID to "sim_param." */ name[0] = '\0'; /* Path first */ if (strlen(log_param_path)) { strcpy(name, log_param_path); strcat(name, "/"); } /* Put "sim_log." onto name */ strcat(name, "sim_log."); /* PID */ sprintf(name + strlen(name), "%d", getpid()); /* Make sure that the file doesn't already exist */ do { if ((accessible = access(name, F_OK)) == 0) /* File already exists--add an 'a' to the file name */ strcat(name, "a"); } while (accessible == 0); /* Open it */ if (!(log_fp = fopen(name, "w"))) { #ifdef DEBUG dbg_write(debug_log, DBG_ERR, NULL, "log_param_create: Couldn't open file '%s' for writing", name); #endif return(FALSE); } #ifdef DEBUG dbg_write(debug_log, DBG_INFO, (Component *)NULL, "log_param_create: opened log file '%s'", name); #endif gethostname(name, 499); name[499] = '\0'; fprintf(log_fp, "# Simulation started with seed %d on %s\n", seed, name); return(TRUE); } log_param_create(c, p) Component *c; Param *p; { static int num = 0; int i, j; /* If the file isn't already open, open it. */ if (!log_fp) if (!log_param_open_file()) return(FALSE); /* Write a comment line to the file with the number associated with this parameter, the component name, and the parameter name. */ if (!p->p_log) { fprintf(log_fp, "# %d '%s' '%s'\n", ++num, c->co_name, p->p_name); p->p_log = num; } #ifdef DEBUG dbg_write(debug_log, DBG_INFO, (Component *)NULL, "log_param_create: started logging parameter '%s' from component '%s', number %d", p->p_name, c->co_name, num); #endif return(TRUE); } void log_param_close(p) Param *p; { } /* Log the packet sequence number */ void log_packet_sequence(c, p, pkt) Component *c; Param *p; Packet *pkt; { /* if (p->p_flags & LogMask && pkt->pk_length) fprintf(log_fp, "%d %u %10d %10d\n", p->p_log, ev_now(), pkt->u.t.pk_seq, pkt->u.t.pk_seq + pkt->pk_length - 1); */ } /* Log the arrival of a packet at a component */ void log_a_packet(c, p, pkt) Component *c; Param *p; Packet *pkt; { if (p->p_flags & LogMask && p->p_log) fprintf(log_fp, "%d %u %s %10d\n", p->p_log, ev_now(), pkt->pk_source_socket.so_port->co_name, pkt->pk_uid); } /* Log acks & windows. */ void log_ack_sequence(c, p, una, window) Component *c; Param *p; unsigned una, window; { if (p->p_flags & LogMask && p->p_log) fprintf(log_fp, "%d %u %u %u\n", p->p_log, ev_now(), una, una + window); } /* When using GCC, this function is in log.h as an inline function. */ #ifndef INLINE /* Set the change mask in the parameter, and also log it if necessary. */ log_param(c, p) Component *c; Param *p; { char b[80]; p->p_flags |= ChangeMask; if (p->p_flags & LogMask && p->p_log) fprintf(log_fp, "%d %u %s\n", p->p_log, ev_now(), (*p->p_make_short_text)(c, p)); } #endif /* INLINE */ /* Log packets to a file. Generally useful only for looking for bugs in the simulator code--in any real simulation, the volume of data would be too big to be usable. */ static int packet_logging = FALSE; log_toggle_packet_logging() { packet_logging = !packet_logging; } log_packet(l, c, pkt) Log l; Component *c; Packet *pkt; { if (packet_logging) fprintf(l, "%10d %10u %-15s\n", pkt->pk_uid, ev_now(), c->co_name); }