home *** CD-ROM | disk | FTP | other *** search
/ Acorn User 10 / AU_CD10.iso / Archived / Internet / Utils / syslog-0.17 / !SysLog / !Help < prev    next >
Text File  |  1997-04-23  |  23KB  |  575 lines

  1. ============================================================================
  2. SysLog Documentation
  3. ----------------------------------------------------------------------------
  4. Version: 0.17
  5. Author:  Jon Ribbens <jon@doggysoft.co.uk>
  6.  
  7. (c) DoggySoft Ltd., 1995, 1996, 1997
  8.  
  9. This program is Freeware and may be freely distributed so long as it is
  10. not charged for, and none of the files are changed or removed. It may be
  11. included with a commercial program which is charged for. There is no
  12. warranty, express or implied. DoggySoft Ltd. is not liable for any loss
  13. or damages caused by the use or misuse of this program.
  14.  
  15.  
  16. Things done:
  17.   * facility to insert arbitrary line
  18.   * considered format of datestamp
  19.   * implemented backoff system for errors writing to logs (partly a bugfix)
  20.   * fixed bug which left files open on errors (e.g. disk full)
  21.   * added Indent/UnIndent/NoIndent
  22.   * do 'temporary logs' thingy for Termite session logs
  23.   * implement log truncation at specified maximum size
  24.   * read <SysLog$Dir> once and once only at startup
  25.   * do automatic tidy-up of 'temporary logs'
  26.   * fixed bug which corrupted the very last line in the options file
  27.   * get allocation for SWI chunk and module name and OS commands
  28.   * user options to disable session logs
  29.   * added "*" line in options file to specify default values
  30.   * reserve disk space option
  31.   * make entry point use two-layer task, so RMEnsuring works
  32.   * add *SysLog ON|OFF and *SysLog <log> <new priority>
  33.   * LogData routine to log a block of hex data (e.g. IP packets)
  34.   * add debugf routine for assembler people
  35.   * add C front-end for C people
  36.   * added SysLog_ReadErrorMessage
  37.   * added %<reg>p and %<reg>a to LogFormatted
  38.   * fixed order of %<reg>a (it was backwards)
  39.   * made log buffer size dependent on logging level
  40.   * made log buffer get de-allocated after ten minutes
  41.   * added SysLog_LogComplete
  42.   * made buffer size be recalculated when log level is changed
  43.   * made setting log level also apply to session logs of that log
  44.   * fixed tidying up of stray session logs (sometimes missed some)
  45.   * fixed a few problems with sessions
  46. 0.15
  47.   * termination of strings is now by zero-byte or line-feed
  48. 0.16
  49.   * add log_forget and call it in CloseSessionLog
  50. 0.17
  51.   * allow CR as a string terminator
  52.   * automatically create 'Old' directory on startup
  53.   * added 'IRQ mode'
  54.  
  55. To do:
  56.   * add expression evaluation to LogFormatted
  57.   * add optional checking of pointer validity
  58.   * add 'features flags'
  59.  
  60. ============================================================================
  61. Rationale
  62. ----------------------------------------------------------------------------
  63.  
  64. Termite is currently lacking in logging facilities. In fact, most
  65. communications software for the Arc is rather poor at logging. This module
  66. is designed to make it easy for comprehensive logging to be added to any
  67. RISC OS program.
  68.  
  69. The logging level can be altered by the user for individual log files, and
  70. buffering is used to speed logging, so it is safe for programs to log large
  71. quantities of data, provided that they use sensible priorities for each type
  72. of message. The logs are also automatically kept to user-specified maximum
  73. lengths, so there is no need to worry about filling up the user's hard disk.
  74.  
  75. Separate log files are used for each application, on the basis that such
  76. segregation of information makes it much easier for the user to find what
  77. they're looking for.
  78.  
  79. A back-off system is used for dealing with errors when writing to logs. Each
  80. error is logged in the "SysLog" log, and the offending log is marked as
  81. "dead". SysLog will then not attempt to write to that log again for one
  82. second. If we again get an error writing to the log, we multiply the
  83. "back-off" time by 1.5, and again mark the log as dead. The back-off time is
  84. not allowed to grow longer than ten minutes.
  85.  
  86.  
  87. ============================================================================
  88. Session logs
  89. ----------------------------------------------------------------------------
  90.  
  91. Usually, log entries are stored strictly chronologically. Sometimes, though,
  92. it may be more useful to store them grouped by 'session'. For example,
  93. NewsBite can have several incoming NNTP connections at once. It is nice to
  94. group the log messages that are coming from each separate connection
  95. together. This can be done using SysLog_OpenSessionLog.
  96.  
  97. SysLog_OpenSessionLog creates a specially-named temporary log file. The log
  98. entries for the session are stored in this log file. When the temporary log
  99. file is closed using SysLog_CloseSessionLog, this data is appended in one
  100. chunk to the end of the main log.
  101.  
  102. SysLog checks for stray temporary log files when it initialises and
  103. finalises, and appends them to the relevant logs. This copes with the
  104. situation where an application crashes or otherwise exits without calling
  105. SysLog_CloseSessionLog.
  106.  
  107.  
  108. ============================================================================
  109. Priorities
  110. ----------------------------------------------------------------------------
  111.  
  112. Message priorities can be in the range 0 to 255, with 0 being the highest
  113. priority and 255 being the lowest. Unless otherwise specified by the user,
  114. only messages with priorities of less than 125 are stored in the log files.
  115. You should therefore think about what things the user is likely to want to
  116. have logged by default, and ensure that these things are logged at
  117. a priority of 124 or less.
  118.  
  119. The priority of errors often depends on how significant the consequences of
  120. the error are, not what the cause of it is. e.g. sometimes "out of memory"
  121. will be an extremely important unrecoverable error (because the program
  122. can't start up), and sometimes it will be unimportant (because the program
  123. can use disk instead, or maybe try again later).
  124.  
  125.  
  126. ============================================================================
  127. Log names
  128. ----------------------------------------------------------------------------
  129.  
  130. Log names are used as the leafnames to store the logs as, so they must
  131. comply with the rules for RISC OS leafnames. They must also not be longer
  132. than ten characters.
  133.  
  134. It is intended that each application have its own log, so an obvious choice
  135. for the log name is the application name (without the '!'). Very large
  136. applications could have more than one log file - in which case the naming
  137. scheme is unspecified. Try and choose sensible log names.
  138.  
  139. If your application is going to be distributed, you should write to
  140. support@doggysoft.co.uk, to request that your log name be formally
  141. allocated. This will hopefully avoid having more than one program using the
  142. same log file.
  143.  
  144. The following log names are reserved for internal use:
  145.  
  146.   any name beginning with a '-' character
  147.   any name beginning with "SysLog"
  148.   "Old"
  149.  
  150.  
  151. ============================================================================
  152. OS commands
  153. ----------------------------------------------------------------------------
  154.  
  155. *SysLog <log name> <priority> <message>
  156.  ------
  157.  
  158. Adds a time-stamped message to the log file, if and only if the specified
  159. log file is set up to log messages of this priority. The priority must be in
  160. the range 0-255.
  161.  
  162.  
  163. *SysLog <log name> <new priority>
  164.  ------
  165.  
  166. Temporarily (but with immediate effect) changes the logging priority of the
  167. specified log. The priority must be in the range 0-256.
  168.  
  169.  
  170. *SysLog ON|OFF
  171.  ------
  172.  
  173. *SysLog OFF will temporary disable SysLog - all log messages received after
  174. this command is issued will be ignored. *SysLog ON resumes normal operation.
  175.  
  176.  
  177. *SysLog_Flush ON|OFF
  178.  ------------
  179.  
  180. *SysLog_Flush with no paramaters flushes all currently open log files to
  181. disk. If it used with the parameter 'ON' then it causes all log files to be
  182. flushed immediately after each message is written to them. *SysLog_Flush OFF
  183. disables this behaviour. (This is intended for use when the a program is
  184. being debugged, and keeps crashing the computer. With SysLog_Flush ON,
  185. you're guaranteed that all the log information your program produces before
  186. it crashes will actually be available after a re-boot. It also makes logging
  187. *very slow*.)
  188.  
  189.  
  190. ============================================================================
  191. SWIs
  192. ----------------------------------------------------------------------------
  193.  
  194. SysLog_LogMessage (&4C880)
  195. -----------------
  196. R0-> log name, or = session log handle
  197. R1-> text to log
  198. R2 = priority
  199.  
  200. Adds a time-stamped message to the log file, if and only if the specified
  201. log file is set up to log messages of this priority. The text to log must
  202. not be longer than 1024 bytes. The priority must be in the range 0-255.
  203.  
  204.  
  205. SysLog_GetLogLevel (&4C881)
  206. ------------------
  207. R0-> log name, or = session log handle
  208. exit:
  209. R0 = priority
  210.  
  211. Reads the logging level for the specified log. Messages of *less than* the
  212. returned priority are being logged. This can be used to avoid creation of
  213. logging information that is only going to be discarded by SysLog_LogMessage
  214. anyway. In some cases it could even be used to decide which version of
  215. a program to load (e.g. whether to load a debugging version of TermiteIP).
  216.  
  217.  
  218. SysLog_FlushLog (&4C882)
  219. ---------------
  220. R0-> log name, or = session log handle, or = 0 to flush all logs
  221.  
  222. Ensures the specified log (or all logs) are fully written to disk, and the
  223. files closed. This can be useful to make sure that the user is immediately
  224. able to read data that has just been written to the log.
  225.  
  226.  
  227. SysLog_SetLogLevel (&4C883)
  228. ------------------
  229. R0-> log name, or = session log handle
  230. R1 = new logging level
  231.  
  232. Sets the logging level for the specified log. This SWI is provided for
  233. debugging and internal use only, and SHOULD NOT BE USED in distribution
  234. code. The logging level is the user's decision, not the programmer's.
  235.  
  236.  
  237. SysLog_LogUnstamped (&4C884)
  238. -------------------
  239. R0-> log name, or = session log handle
  240. R1-> text to log
  241. R2 = priority
  242.  
  243. Adds a message to the log file, if and only if the specified log file is set
  244. to log messages of this priority. The text to log must not be longer than
  245. 1024 bytes. The priority must be in the range 0-255. It is recommended that
  246. you use SysLog_LogMessage for all normal log entries.
  247.  
  248.  
  249. SysLog_Indent (&4C885)
  250. -------------
  251. R0-> log name, or = session log handle
  252.  
  253. Increments the log indent level. In log lines generated by
  254. SysLog_LogMessage, there are <indent_level + 1> spaces in between the
  255. priority and the message. This can be useful to show the hierarchy of the
  256. functions which are producing logging output. The indent level is initially
  257. zero.
  258.  
  259.  
  260. SysLog_UnIndent (&4C886)
  261. ---------------
  262. R0-> log name, or = session log handle
  263.  
  264. Decrements the log indent level. (If it is zero it is not decremented.)
  265.  
  266.  
  267. SysLog_NoIndent (&4C887)
  268. ---------------
  269. R0-> log name, or = session log handle
  270.  
  271. Sets the log indent level to zero. This should be called when your program
  272. loads, if you are using SysLog_Indent/UnIndent.
  273.  
  274.  
  275. SysLog_OpenSessionLog (&4C888)
  276. ---------------------
  277. R0-> log name
  278. R1 = priority
  279. exit:
  280. R0 = session log handle (or 0)
  281.  
  282. Creates a temporary session log file. When the session log is closed (using
  283. SysLog_CloseSessionLog, below), the session log is appended to the main log
  284. as specified in R0 on entry to this SWI. If the main log is set to ignore
  285. log entries of the priority specified then zero will be returned for the
  286. session log handle. This does not necessarily require special case code, as
  287. other SWIs which accept session log handles will accept a handle of zero and
  288. do nothing.
  289.  
  290.  
  291. SysLog_CloseSessionLog (&4C889)
  292. ----------------------
  293. R0 = session log handle
  294.  
  295. Closes the specified temporary session log and appends it to the appropriate
  296. main log file. The specified session log handle is no longer valid.
  297.  
  298.  
  299. SysLog_LogData (&4C88A)
  300. --------------
  301. R0-> log name, or = session log handle
  302. R1 = priority
  303. R2-> data to log
  304. R3 = number of bytes to log
  305. R4 = value to report as block offset (-1 not to show block offset)
  306.  
  307. Logs a block of data, in a hex-and-ASCII format similar to that produced by
  308. *Dump. The block offset is the value that is printed at the beginning of
  309. each line, which is equal to the value given on entry plus the number of
  310. bytes already displayed. If -1 is used as the block offset then the field
  311. will be omitted. Note that if the number of bytes to log is over 10KB then
  312. the SWI will return with an error - logging such a large amount of data in
  313. one go is almost certainly a bug, so SysLog faults it to prevent the
  314. computer going into a semi-infinite loop while it writes huge amounts of
  315. data to disk.
  316.  
  317.  
  318. SysLog_LogFormatted (&4C88B)
  319. -------------------
  320. R0-> log name, or = session log handle
  321. R1-> format string
  322. R2 = priority
  323. R3-> block containing R0-R3,R8-R12,R14
  324. R4-R7 = parameters
  325.  
  326. Evaluates a formatted string using registers R4-R7, and R0-R3, R8-R12 and
  327. R14 from the block passed in R3, and logs the result. See the section
  328. "LogFormatted", below.
  329.  
  330.  
  331. SysLog_ReadErrorMessage (&4C88C)
  332. -----------------------
  333. R0 = error number
  334. exit:
  335. R0-> error message
  336.  
  337. Converts an error number as returned by the FreeNet/Internet/etc modules
  338. into a string describing the error. e.g. SysLog_ReadErrorMessage 60 would
  339. return "Connection timed out".
  340.  
  341.  
  342. SysLog_LogComplete (&4C88D)
  343. ------------------
  344. R0-> log name
  345.  
  346. Flushes the specified log, and de-allocates the buffer associated with it.
  347. This should only be called if the log is definitely not going to be used for
  348. a while (e.g. if your application is the only one which can be writing to
  349. the log, and it's exiting). If this isn't called explicity, SysLog
  350. automatically de-allocates the log buffer after ten minutes of inactivity in
  351. the log.
  352.  
  353.  
  354. SysLog_IRQMode (&4C88E)
  355. --------------
  356. R0 = 0 to disable IRQ mode, 1 to enable IRQ mode
  357.  
  358. Enables or disables IRQ mode. See the section "IRQ Mode", below.
  359.  
  360.  
  361. ============================================================================
  362. IRQ Mode
  363. ----------------------------------------------------------------------------
  364.  
  365. If IRQ mode is enabled, you may call SysLog_LogMessage, SysLog_LogUnstamped,
  366. SysLog_LogData and SysLog_LogFormatted from within interrupt code. Normally
  367. you would not expect to be able to call these SWIs in this situation because
  368. the filing system might be threaded.
  369.  
  370. In IRQ mode, the buffers are not flushed if they become full, so you are
  371. guaranteed to be able to call the SWIs without Bad Things happening (all
  372. they will be doing is writing to memory). If the buffers are full, however,
  373. then log messages will be lost.
  374.  
  375. If log messages are lost due to the buffers becoming full then a line to
  376. this effect will be added to the log at the next opportunity.
  377.  
  378. Do try to ensure that you call SysLog_IRQMode to disable IRQ mode when
  379. you are exiting the interrupt code, otherwise other applications may have
  380. their log messages lost unnecessarily. SysLog maintains a counter of how
  381. man times IRQ mode has been enabled and disabled, and only genuinely
  382. disables it when the counter is zero.
  383.  
  384. SysLog_GetLogLevel, SysLog_Indent, SysLog_UnIndent, SysLog_NoIndent and
  385. SysLog_ReadErrorMessage may always be called from interrupt code. Other
  386. SysLog SWIs may never be called from interrupt code.
  387.  
  388.  
  389. ============================================================================
  390. LogFormatted
  391. ----------------------------------------------------------------------------
  392.  
  393. SWI SysLog_LogFormatted provides C "printf"-style functionality for
  394. assembler programmers. A format string is passed in R1, which is a template
  395. for the output. The string is copied directly to the output, except for '%'
  396. characters, which inserts a string calculated when the SWI is called:
  397.  
  398.         %%      - the literal '%' character
  399.         %<reg>a - the network-byte-ordered IP address in register <reg>
  400.         %<reg>c - the character in register <reg>
  401.         %<reg>d - the signed decimal integer in register <reg>
  402.         %<reg>e - the message for the FreeNet error number in register <reg>
  403.         %<reg>f - the filename of the file handle in register <reg>
  404.         %<reg>p - the object pointed to by register <reg>
  405.         %<reg>s - the control-terminated string pointed to by register <reg>
  406.         %<reg>x - the unsigned hexadecimal integer in register <reg>
  407.         %<reg>z - the zero-terminated string pointed to by register <reg>
  408.  
  409.    where <reg> is a number which can be any of 0 to 12 or 14.
  410.  
  411. Note that the %<reg>p type must be followed by another type indicator. For
  412. example, to log a character pointed to by register R3, use "%3pc". More than
  413. one 'p' can be used to indicate more than one level of indirection.
  414.  
  415. Null pointers are explicitly checked for wherever used, and the string
  416. "(null)" is logged in place of whatever should have been output. Hence it
  417. is explicity defined that it is safe to allow null pointers to be in
  418. registers used by the format string.
  419.  
  420. Registers R4-R7 are taken directly from the registers passed to the SWI.
  421. Registers R0-R3, R8-R12 and R14 are taken from the block passed in R3.
  422.  
  423. It is expected that this SWI would be packaged in a macro in your assembler
  424. source code. For example:
  425.  
  426. ...
  427. .stricmp
  428.   FNlogf("stricmp: comparing %0z and %1z",200)
  429. ...
  430.  
  431. DEF FNlogf(t$,p%)
  432.   [OPT p
  433.     STMFD   R13!,{R0-R3,R8-R12,R14}
  434.     ADR     R0,txt_logname
  435.     ADD     R1,R15,#12
  436.     MOV     R2,#p%
  437.     MOV     R3,R13
  438.     SWI     "SysLog_LogFormatted"
  439.     B       P%+(LENt$+8)ANDNOT3
  440.     EQUS    t$+STRING$(4-(LENt$AND3),CHR$0)
  441.     LDMFD   R13!,{R0-R3,R8-R12,R14}
  442.   ]
  443. =p
  444.  
  445. or the ObjAsm equivalent:
  446.  
  447.         MACRO
  448.         LOGF    $t,$p
  449.  
  450.         STMFD   R13!,{R0-R3,R8-R12,R14}
  451.         ADR     R0,txt_logname
  452.         ADR     R1,%ft90
  453.         MOV     R2,#$p
  454.         MOV     R3,R13
  455.         SWI     SysLog_LogFormatted
  456.         B       %ft91
  457. 90
  458.         =       "$t",0
  459.         ALIGN
  460. 91      LDMFD   R13!,{R0-R3,R8-R12,R14}
  461.         MEND
  462.  
  463. ...
  464. stricmp ROUT
  465.         LOGF    "stricmp: comparing %0z and %1z",200
  466. ...
  467.  
  468.  
  469. ============================================================================
  470. Using SysLog from C programs
  471. ----------------------------------------------------------------------------
  472.  
  473. To make SysLog easy to use from C programs, I have written an APCS veneer
  474. for the module. This takes the form of a "syslog.h" header file which you
  475. should #include from your C source, and a "syslog.o" object file which you
  476. should link your program with.
  477.  
  478. There are two calls for each SWI, one which uses the non-X form and one
  479. which uses the X form and returns a _kernel_oserror *. The non-X forms are
  480. generally nicer as values can be returned in the usual manner, rather than
  481. having to pass a pointer to a location to be filled in with the return code.
  482. I would suggest only using the X forms when you absolutely must - i.e. in
  483. module code, etc.
  484.  
  485. There's also a bonus function "syslogf" (and "xsyslogf") which is like
  486. "printf" except it outputs to the log. The first two arguments are the
  487. logname and priority, and the rest are the usual printf arguments (i.e.
  488. the format string followed by a variable number of arguments).
  489.  
  490. Note that a temporary buffer is used to hold the string before it is passed
  491. to the SysLog module and *THIS BUFFER IS ONLY 1024 BYTES LONG*. i.e. you
  492. must ensure that your format string cannot ever produce more than 1024 bytes
  493. of output. This is especially important in networking software where the
  494. input may be coming from a Bad Miscreant who is trying to hack into or crash
  495. your machine.
  496.  
  497. The ObjAsm source to the veneer object file is provided. If you make any
  498. changes which you think people might find useful, or you find any bugs,
  499. please e-mail me and tell me about it.
  500.  
  501. Thanks go to Stewart Brodie for assistance with vsprintf ;-).
  502.  
  503.  
  504. ============================================================================
  505. Options
  506. ----------------------------------------------------------------------------
  507.  
  508. The options file is stored as !SysLog.Options. Each line of the options file
  509. specifies the options for a single log. This line is of the format:
  510.     <logname> [Reserve <size>|NoReserve] [Sessions|NoSessions]
  511.               [<level> [<max. size>]]
  512. <size> and <max. size> are specified in kilobytes.
  513.  
  514. An entry for log "*" is treated as the default values, which are used if
  515. the log doesn't have a specific entry in the Options file. So, for example,
  516. to specify "NoSessions" for every log except "NewsBite" you could use:
  517.   * NoSessions
  518.   NewsBite Sessions
  519.  
  520. The options have the following meanings:
  521.  
  522.   Reserve <size>
  523.     SysLog will make sure that at least <size> KB of disk space is free for
  524.     this log, by padding the log file with zeros which are later overwritten
  525.     by the real log data.
  526.   NoReserve
  527.     SysLog won't reserve disk space for this log as described above. This is
  528.     the default.
  529.  
  530.   Sessions
  531.     SysLog will use Session Logs for this log (as described above) where
  532.     instructed. This is the default.
  533.   NoSessions
  534.     Session Logs are disabled for this log, and log entries will appear
  535.     strictly in chronological order.
  536.  
  537.   <level>
  538.     SysLog will ignore log entries for this log which have a priority
  539.     greater to or equal than this value. The default value is 125.
  540.  
  541.   <max. size>
  542.     The log will be moved to the "Old" directory when it becomes larger
  543.     than this size. The default value is 256KB.
  544.  
  545.  
  546. ============================================================================
  547. Usage guidelines
  548. ----------------------------------------------------------------------------
  549.  
  550. Previously in this section I recommended that programs should not fail to
  551. work if logging is not available. This is reasonable - however there are
  552. very few reasons that logging will fail, and all of these reasons are very
  553. likely to cause the main function of the program to fail. I would suggest
  554. therefore that programs should RMEnsure the SysLog module in their !Run
  555. files, and then use it as any other SWI.
  556.  
  557. Errors from SysLog SWIs, while strictly speaking non-fatal for the main
  558. program, are indicative of something being badly wrong with the system. Use
  559. 'X' SWIs in situations such as modules where you have to, of course, but in
  560. application code where you have an error handler, you might as well use the
  561. non-'X' form and treat the errors as you would any other.
  562.  
  563. Programs which use SysLog should RMEnsure it in their !Run files. The
  564. suggested lines to use are as follows:
  565.  
  566. If "<SysLog$Dir>"="" then Error !SysLog application not seen by filer
  567. RMEnsure SysLog 0.17 Run <SysLog$Dir>.!Run
  568. RMEnsure SysLog 0.17 Error MyApp needs SysLog 0.17 or later
  569.  
  570. Note that you must *not* just RMLoad the SysLog module, as it requires its
  571. Wimp task to be activated, and this will not happen if you just RMLoad the
  572. module. The module has a two-stage application entry point, so it will
  573. return immediately when you RMRun it, allowing the !Run file to continue as
  574. normal.
  575.