1 /* 2 * log.h --- the logging module of websh3 3 * nca-073-9 4 * 5 * Copyright (c) 1996-2000 by Netcetera AG. 6 * Copyright (c) 2001 by Apache Software Foundation. 7 * All rights reserved. 8 * 9 * See the file "license.terms" for information on usage and 10 * redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. 11 * 12 * @(#) $Id: log.h 788707 2009-06-26 14:04:40Z ronnie $ 13 * 14 */ 15 16 /* ---------------------------------------------------------------------------- 17 * metaphor -- let me explain the methaphor I am using for the logging module: 18 * 19 * it looks to me like a snail mail handling process -- you write an 20 * address onto your letter and drop it in the box (web::log address 21 * letter). The post office decides whether the address makes sense by 22 * searching through the list of known addresses, and rejects the 23 * letter if it does not pass this filter (manage the list of known 24 * addresses with web::loglevel). If the letter is accepted, it goes 25 * through the distribution system where there are different bags, 26 * labeled with "USA", "Zurich" etc. The distributer will put your 27 * letter into the correct bag which then will be handled by the 28 * respective post office (manage the list of bags with web::logdest). 29 * In our case, once the letter is dropped into one of those bags, it 30 * will be delivered right away. 31 * ------------------------------------------------------------------------- */ 32 33 #include "args.h" 34 #include "hashutl.h" 35 #include "macros.h" 36 #include "tcl.h" 37 #include "webutl.h" 38 #include "request.h" 39 40 41 #ifndef WEBLOG_H 42 #define WEBLOG_H 43 44 /* -------------------------------------------------------------------------- 45 * Log levels 46 * ------------------------------------------------------------------------*/ 47 48 #define WEBLOG_DEBUG "websh.debug" 49 #define WEBLOG_INFO "websh.info" 50 #define WEBLOG_WARNING "websh.warning" 51 #define WEBLOG_ERROR "websh.error" 52 53 54 #define WEB_LOG_DEFAULTFORMAT "%x %X [$p] $f.$l: $m\n" 55 56 /* -------------------------------------------------------------------------- 57 * Commands 58 * ------------------------------------------------------------------------*/ 59 60 /* ---------------------------------------------------------------------------- 61 * SubCommands 62 * ------------------------------------------------------------------------- */ 63 #define WEB_LOG_SUBCMD_ADD "add" 64 #define WEB_LOG_SUBCMD_DELETE "delete" 65 #define WEB_LOG_SUBCMD_NAMES "names" 66 #define WEB_LOG_SUBCMD_LEVELS "levels" 67 68 /* ---------------------------------------------------------------------------- 69 * Parameters (like "web::cmdurl -cmd aCommand", where there is an argument 70 * ------------------------------------------------------------------------- */ 71 #define WEB_LOG_PARAM_FORMAT "-format" 72 #define WEB_LOG_PARAM_MAXCHAR "-maxchar" 73 74 /* -------------------------------------------------------------------------- 75 * Registered Data 76 * ------------------------------------------------------------------------*/ 77 #define WEB_LOG_ASSOC_DATA "web::logData" 78 79 /* -------------------------------------------------------------------------- 80 * messages 81 * ------------------------------------------------------------------------*/ 82 #define WEB_LOG_USAGE_LOGDEST_ADD \ 83 "add ?options? level type ?type-specific-arguments ...?" 84 85 /* -------------------------------------------------------------------------- 86 * other 87 * ------------------------------------------------------------------------*/ 88 #define LOG_LIST_INITIAL_SIZE 10 89 #define LOG_FILTER_PREFIX "loglevel" 90 #define LOG_DEST_PREFIX "logdest" 91 #define LOG_SUBSTDEFAULT 0 92 #define LOG_SAFEDEFAULT 1 93 94 /* ---------------------------------------------------------------------------- 95 * list of possible categories 96 * ------------------------------------------------------------------------- */ 97 typedef enum Severity 98 { 99 none, alert, error, warning, info, debug, invalid = -1 100 } 101 Severity; 102 103 /* ---------------------------------------------------------------------------- 104 * the log level, as attached to a log message and as used for filtering 105 * ------------------------------------------------------------------------- */ 106 typedef struct LogLevel 107 { 108 int keep; 109 char *facility; 110 Severity minSeverity; 111 Severity maxSeverity; /* only used for filter */ 112 } 113 LogLevel; 114 115 LogLevel *createLogLevel(); 116 int destroyLogLevel(void *level, void *dum); 117 118 /* ---------------------------------------------------------------------------- 119 * plug-in interface 120 * ------------------------------------------------------------------------- */ 121 typedef ClientData(LogPlugInConstructor) (Tcl_Interp * interp, 122 ClientData clientData, 123 int objc, Tcl_Obj * CONST objv[]); 124 typedef int (LogPlugInDestructor) (Tcl_Interp * interp, 125 ClientData clientData); 126 typedef int (LogPlugInHandler) (Tcl_Interp * interp, 127 ClientData clientData, char *msg); 128 129 typedef struct LogPlugIn 130 { 131 LogPlugInConstructor *constructor; 132 LogPlugInDestructor *destructor; 133 LogPlugInHandler *handler; 134 } 135 LogPlugIn; 136 LogPlugIn DLLEXPORT *createLogPlugIn(); 137 int destroyLogPlugIn(void *plugIn, void *dum); 138 int DLLEXPORT registerLogPlugIn(Tcl_Interp * interp, char *type, LogPlugIn * plugIn); 139 140 141 /* ---------------------------------------------------------------------------- 142 * log destination (like stderr, file, channel, ...) 143 * ------------------------------------------------------------------------- */ 144 typedef struct LogDest 145 { 146 int keep; 147 LogLevel *filter; 148 char *format; 149 long maxCharInMsg; 150 LogPlugIn *plugIn; 151 ClientData plugInData; 152 } 153 LogDest; 154 LogDest *createLogDest(); 155 int destroyLogDest(void *dest, void *env); 156 char *createLogDestName(char *prefix, int cnt); 157 158 159 160 161 /* ---------------------------------------------------------------------------- 162 * log data structure 163 * ------------------------------------------------------------------------- */ 164 typedef struct LogData 165 { 166 LogLevel **listOfFilters; 167 int filterSize; /* size of filter list */ 168 LogDest **listOfDests; 169 int destSize; /* site of destination list */ 170 Tcl_HashTable *listOfPlugIns; 171 int logSubst; /* 1: subst log message, 0: don't (default 0) */ 172 int safeLog; /* 1: web::log never fails, 0: can throw I/O error (default 1) */ 173 int keep; /* flag for log config to keep during initializer code */ 174 /* needed so that global settings can be accessed */ 175 RequestData * requestData; 176 } 177 LogData; 178 179 LogData *createLogData(); 180 void destroyLogData(ClientData clientData, Tcl_Interp * interp); 181 182 183 /* ---------------------------------------------------------------------------- 184 * Tcl interface and commands 185 * ------------------------------------------------------------------------- */ 186 int DLLEXPORT log_Init(Tcl_Interp * interp); 187 188 int Web_Log(ClientData clientData, 189 Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[]); 190 191 int Web_LogDest(ClientData clientData, 192 Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[]); 193 194 int Web_LogFilter(ClientData clientData, 195 Tcl_Interp * interp, int objc, Tcl_Obj * CONST objv[]); 196 197 198 /* ---------------------------------------------------------------------------- 199 * the functions 200 * ------------------------------------------------------------------------- */ 201 char *getSeverityName(Severity aSeverity); 202 LogLevel *parseLogLevel(Tcl_Interp * interp, 203 char *definition, char *defaultfacility, int cnt); 204 Tcl_Obj *formatMessage(LogLevel * level, char *fmt, long maxCharInMsg, 205 Tcl_Obj * msg); 206 int doesPass(LogLevel * level, LogLevel * filter); 207 int doesPassFilters(LogLevel * logLevel, LogLevel ** logLevels, int size); 208 int logImpl(Tcl_Interp * interp, LogData * logData, 209 char *levelStr, Tcl_Obj * msg); 210 int webLog(Tcl_Interp * interp, char *levelStr, char *msg); 211 212 int sendMsgToDestList(Tcl_Interp * interp, 213 LogData * logData, LogLevel * level, Tcl_Obj * msg); 214 215 char * insertIntoDestList(LogData *logData, LogDest *logDest); 216 char * insertIntoFilterList(LogData *logData, LogLevel *logLevel); 217 218 /* ---------------------------------------------------------------------------- 219 * Logging 220 * ------------------------------------------------------------------------- */ 221 #define WRITE_LOG 1 /* sends message to log facility */ 222 #define SET_RESULT 2 /* store part of message in interpreter result */ 223 #define INTERP_ERRORINFO 4 /* include tcl-interp's errorInfo in log message */ 224 225 /* default use: 226 LOG_MSG(,WRITE_LOG,...) --> just write log msg 227 LOG_MSG(,SET_RESULT,...) --> just set interp result 228 LOG_MSG(,WRITE_LOG | SET_RESULT,...) --> log msg and set interp result 229 LOG_MSG(,0,...) --> don't do this 230 */ 231 232 void DLLEXPORT LOG_MSG(Tcl_Interp * interp, int flag, char *filename, int linenr, 233 char *cmd, char *level, char *msg, ...); 234 235 #endif 236