|
|
1.1 ! root 1: % run this through LaTeX with the appropriate wrapper ! 2: ! 3: \chapter {The ISODE Logging Facility}\label{logging} ! 4: Although not a database mechanisms, per se, the ISODE logging facility ! 5: is used to manipulate general logs: ! 6: used by both the ISODE and programs which use the ISODE. ! 7: ! 8: \subsection {Data-Structures} ! 9: There is one primary data-structure, the \verb"LLog": ! 10: \begin{quote}\index{LLog}\small\begin{verbatim} ! 11: typedef struct ll_struct { ! 12: char *ll_file; ! 13: ! 14: char *ll_hdr; ! 15: char *ll_dhdr; ! 16: ! 17: int ll_events; ! 18: #define LLOG_NONE 0 ! 19: #define LLOG_FATAL 0x01 ! 20: #define LLOG_EXCEPTIONS 0x02 ! 21: #define LLOG_NOTICE 0x04 ! 22: #define LLOG_PDUS 0x08 ! 23: #define LLOG_TRACE 0x10 ! 24: #define LLOG_DEBUG 0x20 ! 25: #define LLOG_ALL 0xff ! 26: #define LLOG_MASK \ ! 27: "\020\01FATAL\02EXCEPTIONS\03NOTICE\04PDUS\05TRACE\06DEBUG" ! 28: ! 29: int ll_syslog; ! 30: ! 31: int ll_msize; ! 32: ! 33: int ll_stat; ! 34: #define LLOGNIL 0x00 ! 35: #define LLOGCLS 0x01 ! 36: #define LLOGCRT 0x02 ! 37: #define LLOGZER 0x04 ! 38: #define LLOGERR 0x08 ! 39: #define LLOGTTY 0x10 ! 40: #define LLOGHDR 0x20 ! 41: #define LLOGDHR 0x40 ! 42: ! 43: int ll_fd; ! 44: } LLog; ! 45: \end{verbatim}\end{quote} ! 46: The elements of this structure are: ! 47: \begin{describe} ! 48: \item[\verb"ll\_file":] the name of the file to use for the log, ! 49: unless an absolute pathname (e.g., \file{/usr/tmp/logfile}) ! 50: or an anchored pathname (e.g., \file{./logfile}), ! 51: the name is interpreted relative to the the \verb"logpath" directory ! 52: in the ISODE tailoring file (see Chapter~\ref{isotailor}); ! 53: ! 54: \item[\verb"ll\_hdr":] the logging header which ! 55: is usually set by one of the utility routines described below; ! 56: ! 57: \item[\verb"ll\_hdr"/\verb"ll\_dhdr":] the so-called dynamic header; ! 58: ! 59: \item[\verb"ll\_events"/\verb"ll\_syslog":] a bitmask describing the logging ! 60: events which are interesting to this log, any combination of: ! 61: \[\begin{tabular}{|l|l|} ! 62: \hline ! 63: \multicolumn{1}{|c|}{\bf Value}& ! 64: \multicolumn{1}{c|}{\bf Meaning}\\ ! 65: \hline ! 66: \tt LLOG\_FATAL& fatal errors\\ ! 67: \tt LLOG\_EXCEPTIONS& exceptional events\\ ! 68: \tt LLOG\_NOTICE& informational notices\\ ! 69: \tt LLOG\_PDUS& PDU printing\\ ! 70: \tt LLOG\_TRACE& program tracing\\ ! 71: \tt LLOG\_DEBUG& full debugging\\ ! 72: \hline ! 73: \end{tabular}\] ! 74: In addition, the values \verb"LLOG_NONE" by itself refers to no events ! 75: and \verb"LLOG_ALL" refers to all events being of interest. ! 76: For those systems with a \man syslog(3) routine, ! 77: the \verb"ll_syslog" element indicates if the event should be given to ! 78: \man syslog(8) as well; ! 79: ! 80: \item[\verb"ll\_msize":] the maximum size of the log, in units of Kbytes ! 81: (a non-positive number indicates no limit); ! 82: ! 83: \item[\verb"ll\_stat":] assorted switches, any combination of: ! 84: \[\begin{tabular}{|l|l|} ! 85: \hline ! 86: \multicolumn{1}{|c|}{\bf Value}& ! 87: \multicolumn{1}{c|}{\bf Meaning}\\ ! 88: \hline ! 89: \tt LOGCLS& keep log closed, except when writing\\ ! 90: \tt LOGCRT& create log if necessary\\ ! 91: \tt LOGZER& truncate log when limits reached\\ ! 92: \tt LOGERR& log closed due to (soft) error\\ ! 93: \tt LOGTTY& also log to stderr\\ ! 94: \tt LOGHDR& static header allocated\\ ! 95: \tt LOGDHR& dynamic header allcoated\\ ! 96: \hline ! 97: \end{tabular}\] ! 98: ! 99: \item[\verb"ll\_fd":] the file-descriptor corresponding to the log. ! 100: \end{describe} ! 101: ! 102: \section {Accessing the Log} ! 103: Typically, ! 104: logs are not opened or closed directly~---~when an entry is made to a log, ! 105: the log is opened (if necessary), the entry is written, and (usually) the log ! 106: is then closed. ! 107: ! 108: To open a log associated with a \verb"LLog" structure, ! 109: the routine \verb"ll_open" is used: ! 110: \begin{quote}\index{ll\_open}\small\begin{verbatim} ! 111: int ll_open (lp) ! 112: LLog *lp; ! 113: \end{verbatim}\end{quote} ! 114: The parameter to this routine is: ! 115: \begin{describe} ! 116: \item[\verb"lp":] a pointer to a \verb"LLog" structure. ! 117: \end{describe} ! 118: The \verb"ll_open" routine will open the log, ! 119: creating the corresponding file (if necessary). ! 120: Logs are created mode \verb"0666". ! 121: If the name of the file to use for the log is ``\verb"-"'', ! 122: then the \verb"LLOGTTY" option is enabled and no file is actually opened. ! 123: When determining the actual name of the file to use, ! 124: a ``\verb"%d"'' in the name will be replaced by the process-id of the program ! 125: opening the log. ! 126: On failure, the manifest constant \verb"NOTOK" is returned. ! 127: Otherwise, the log is opened ! 128: (and left open, regardless of the presence of the \verb"LLOGCLS" option), ! 129: and the manifest constant \verb"OK" is returned. ! 130: ! 131: To close a log, the routine \verb"ll_close" is used: ! 132: \begin{quote}\index{ll\_close}\small\begin{verbatim} ! 133: int ll_close (lp) ! 134: LLog *lp; ! 135: \end{verbatim}\end{quote} ! 136: The parameter to this routine is: ! 137: \begin{describe} ! 138: \item[\verb"lp":] a pointer to a \verb"LLog" structure. ! 139: \end{describe} ! 140: This routine returns the manifest constant \verb"OK" on success ! 141: (even if the log was already closed), ! 142: or \verb"NOTOK" otherwise. ! 143: ! 144: \subsection {Timestamps} ! 145: One of the characteristics of a log is that it contains an informational ! 146: timestamp for each entry. ! 147: This timestamp contains the date and time of the log and also two ``header'' ! 148: strings, a static header and a dynamic header. ! 149: Normally, these strings are constructed from the name of the program or ! 150: subsystem using the log. ! 151: The routine \verb"ll_hdinit" is used to initialize the static header: ! 152: \begin{quote}\index{ll\_hdinit}\small\begin{verbatim} ! 153: void ll_hdinit (lp, prefix) ! 154: LLog *lp; ! 155: char *prefix; ! 156: \end{verbatim}\end{quote} ! 157: The parameters to this routine are: ! 158: \begin{describe} ! 159: \item[\verb"lp":] a pointer to a \verb"LLog" structure; and, ! 160: ! 161: \item[\verb"prefix":] the name of the program or subsystem using the log. ! 162: \end{describe} ! 163: This routine will form a header consisting of the program name, ! 164: the process-id, and the user-name. ! 165: ! 166: The routine \verb"ll_dbinit" is similar, but also enables debugging features: ! 167: \begin{quote}\index{ll\_dbinit}\small\begin{verbatim} ! 168: void ll_dbinit (lp, prefix) ! 169: LLog *lp; ! 170: char *prefix; ! 171: \end{verbatim}\end{quote} ! 172: The parameters to this routine are: ! 173: \begin{describe} ! 174: \item[\verb"lp":] a pointer to a \verb"LLog" structure; and, ! 175: ! 176: \item[\verb"prefix":] the name of the program or subsystem using the log. ! 177: \end{describe} ! 178: This routine will form a header identical to the one formed by ! 179: \verb"ll_hdinit". ! 180: It will then set the name of the file associated with the log to be relative ! 181: to the current working directory. ! 182: Finally, it turns on all event logging and logging to the user's terminal. ! 183: ! 184: \subsection {Making Log Entries} ! 185: At the lowest level, the \verb"ll_log" routine is used to append an entry to a ! 186: log: ! 187: \begin{quote}\index{ll\_log}\small\begin{verbatim} ! 188: int ll_log (lp, event, what, fmt, args ...) ! 189: LLog *lp; ! 190: int event; ! 191: char *what, ! 192: *fmt; ! 193: \end{verbatim} ! 194: \end{quote} ! 195: The parameters to this routine are: ! 196: \begin{describe} ! 197: \item[\verb"lp":] a pointer to a \verb"LLog" structure; ! 198: ! 199: \item[\verb"event":] the event type being logged (e.g., \verb"LLOG_NOTICE"); ! 200: ! 201: \item[\verb"what":] some text associated with a system call error ! 202: (use the manifest constant \verb"NULLCP" if the entry is not associated with ! 203: an error in a system call); and, ! 204: ! 205: \item[\verb"fmt"/\verb"args":] an argument list to \man printf(3s). ! 206: \end{describe} ! 207: The entry is only made if the log is enabled ! 208: (in the \verb"ll_events" field of the \verb"LLog" structure) ! 209: for the event listed as a parameter to \verb"ll_log". ! 210: If there was a problem in writing to the log, ! 211: \verb"ll_log" returns the manifest constant \verb"NOTOK". ! 212: Otherwise, \verb"OK" is returned. ! 213: ! 214: The \verb"ll_log" routine is actually a simple wrapper around the ! 215: \verb"_ll_log" routine: ! 216: \begin{quote}\index{\_ll\_log}\small\begin{verbatim} ! 217: int _ll_log (lp, event, ap) ! 218: LLog *lp; ! 219: int event; ! 220: va_list ap; ! 221: \end{verbatim} ! 222: \end{quote} ! 223: The parameters to this routine are: ! 224: \begin{describe} ! 225: \item[\verb"lp":] a pointer to a \verb"LLog" structure; ! 226: ! 227: \item[\verb"event":] the event type being logged; and, ! 228: ! 229: \item[\verb"ap":] an argument pointer to a variable-length argument list ! 230: as described in \man varargs(3). ! 231: \end{describe} ! 232: ! 233: It may be necessary to have multi-line log entries. ! 234: In this case, the first line of the entry should be made with \verb"ll_log". ! 235: The remaining lines should be made with the \verb"ll_printf" routine: ! 236: \begin{quote}\index{ll\_printf}\small\begin{verbatim} ! 237: int ll_printf (lp, fmt, args ...) ! 238: LLog *lp; ! 239: char *fmt; ! 240: \end{verbatim} ! 241: \end{quote} ! 242: The parameters to this routine are: ! 243: \begin{describe} ! 244: \item[\verb"lp":] a pointer to a \verb"LLog" structure; and, ! 245: ! 246: \item[\verb"fmt"/\verb"args ...":] an argument list to \man printf(3s). ! 247: \end{describe} ! 248: As with \verb"ll_log", this routine returns either \verb"OK" on success or ! 249: \verb"NOTOK" on error. ! 250: Unlink \verb"ll_log" however, ! 251: \verb"ll_printf" will ignore the setting of the \verb"LLOGCLS" option). ! 252: As such, when the last line of a multi-line entry has been made, ! 253: the routine \verb"ll_sync" should always be called to synchronize the log: ! 254: \begin{quote}\index{ll\_sync}\small\begin{verbatim} ! 255: int ll_sync (lp) ! 256: LLog *lp; ! 257: \end{verbatim} ! 258: \end{quote} ! 259: The parameter to this routine is: ! 260: \begin{describe} ! 261: \item[\verb"lp":] a pointer to a \verb"LLog" structure. ! 262: \end{describe} ! 263: ! 264: \subsection {More About Making Log Entries} ! 265: Although the \verb"ll_log" routine has a basic functionality, ! 266: programmers often prefer a slightly simpler interface. ! 267: A few macros have been defined for this purpose. ! 268: ! 269: The \verb"SLOG" macro is the most commonly used: ! 270: \begin{quote}\index{SLOG}\small\begin{verbatim} ! 271: SLOG (lp, event, what, args) ! 272: \end{verbatim}\end{quote} ! 273: The parameters to this macro are: ! 274: \begin{describe} ! 275: \item[\verb"lp":] a pointer to a \verb"LLog" structure; ! 276: ! 277: \item[\verb"event":] the event type being logged; ! 278: ! 279: \item[\verb"what":] some text associated with a system call error ! 280: (use the manifest constant \verb"NULLCP" if the entry is not associated with ! 281: an error in a system call); and, ! 282: ! 283: \item[\verb"args":] a parenthesized argument list for \man printf(3s). ! 284: \end{describe} ! 285: The \verb"SLOG" macro compares the event enabled for a log to the event being ! 286: logged to see if \verb"ll_log" should be called. ! 287: ! 288: Since, the need for a \verb"what" parameter is not common in many ! 289: applications, ! 290: the \verb"LLOG" macro has been supplied. ! 291: It is essentially the \verb"SLOG" macro but with a value of \verb"NULLCP" ! 292: supplied for the \verb"what" parameter of \verb"ll_log": ! 293: \begin{quote}\index{LLOG}\small\begin{verbatim} ! 294: LLOG (lp, what, args) ! 295: \end{verbatim}\end{quote} ! 296: ! 297: Further, ! 298: even though logging is contingent on an event type being enabled, ! 299: a programmer may still wish that calls to logging package still be ! 300: conditionally compiled. ! 301: The \verb"DLOG" macro has been supplied for this purpose. ! 302: If the pre-processor symbol \verb"DEBUG" is defined, ! 303: then \verb"DLOG" is equivalent to \verb"LLOG" otherwise it compiles no code ! 304: whatsoever: ! 305: \begin{quote}\index{DLOG}\small\begin{verbatim} ! 306: DLOG (lp, what, args) ! 307: \end{verbatim}\end{quote} ! 308: ! 309: Finally, it may be useful to log PDUs (protocol data units), again under ! 310: conditional compilation. ! 311: The \verb"PLOG" macro takes the address of a pretty-printer function generated ! 312: by \man pepy(1) ! 313: (see Section~\ref{pepy:pretty} on page~\pageref{pepy:pretty} in \volfour/) ! 314: along with a presentation element ! 315: (as described in Chapter~\ref{libpsap} in \volone/) ! 316: and a brief textual title, and directs the pretty-printer to output to the log: ! 317: \begin{quote}\index{PLOG}\small\begin{verbatim} ! 318: PLOG (lp, fnx, pe, text, rw) ! 319: \end{verbatim}\end{quote} ! 320: The \verb"rw" parameter is an integer saying wheter the PDU was read from the ! 321: network (non-zero) or written to the network (zero-valued). ! 322: As with the \verb"DLOG" macro, ! 323: if the \verb"DDEBUG" symbol is not defined, ! 324: then no code is generated. ! 325: ! 326: \subsection {Miscellaneous Routines} ! 327: In order to support some of the more esoteric log capabilities, ! 328: there are a few utility routines. ! 329: ! 330: The routine \verb"ll_preset" evaluates a \man printf(3s) argument list ! 331: and returns a pointer to static buffer containing the result: ! 332: \begin{quote}\index{ll\_preset}\small\begin{verbatim} ! 333: char *ll_preset (fmt, args ...) ! 334: char *fmt; ! 335: \end{verbatim} ! 336: \end{quote} ! 337: ! 338: The routine \verb"ll_check" determines if a log has exceeded its size, ! 339: and if so, if a correction can be made: ! 340: \begin{quote}\index{ll\_check}\small\begin{verbatim} ! 341: int ll_check (lp) ! 342: LLog *lp; ! 343: \end{verbatim} ! 344: \end{quote} ! 345: This routine returns \verb"OK" if the log is within its bounds. ! 346: ! 347: \section {Use of Logging in Programs} ! 348: From the perspective of applications programmers, ! 349: there are three kinds of styles for using the logging package, ! 350: depending on the kind of program being written. ! 351: ! 352: In all three cases, ! 353: \verb"LLog" structures are usually declared statically in the main module of a ! 354: program and a pointer to the structure is made available for general use: ! 355: \begin{quote}\small\begin{verbatim} ! 356: static LLog _pgm_log = { ! 357: "myname.log", NULLCP, NULLCP, ! 358: LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE, ! 359: -1, ! 360: LLOGCLS | LLOGCRT | LLOGZER, ! 361: NOTOK ! 362: }; ! 363: ! 364: LLog *pgm_log = &_pgm_log; ! 365: \end{verbatim}\end{quote} ! 366: Where the \verb"myname" in ``\verb"myname.log"'' is replaced with the name of ! 367: the program. ! 368: ! 369: Note that in all cases, ! 370: in order to ensure consistent logging it is {\bf critical\/} that the call to ! 371: \verb"isodetailor" be the first call made to {\em any \/} of the ISODE ! 372: routines. ! 373: ! 374: For static responders, ! 375: two routines are called in the initialization code: ! 376: \begin{quote}\small\begin{verbatim} ! 377: isodetailor (argv[0], 0); ! 378: ll_hdinit (pgm_log, argv[0]); ! 379: \end{verbatim}\end{quote} ! 380: Later on, after argument parsing, if a debug option is enabled, then ! 381: \begin{quote}\small\begin{verbatim} ! 382: ll_dbinit (pgm_log, argv[0]); ! 383: \end{verbatim}\end{quote} ! 384: is called. ! 385: ! 386: For dynamic responders, ! 387: a similiar code sequence is used: ! 388: \begin{quote}\small\begin{verbatim} ! 389: isodetailor (argv[0], 0); ! 390: if (debug = isatty (fileno (stderr))) ! 391: ll_hdinit (pgm_log, argv[0]); ! 392: else ! 393: ll_dbinit (pgm_log, argv[0]); ! 394: \end{verbatim}\end{quote} ! 395: ! 396: For user-interfaces, the code is simply: ! 397: \begin{quote}\small\begin{verbatim} ! 398: isodetailor (argv[0], 1); ! 399: ll_hdinit (pgm_log, argv[0]); ! 400: \end{verbatim}\end{quote} ! 401: which will ask the tailoing system to read both the standard tailoring file ! 402: and a user-specific tailoring file and then to initialize the program log.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.