syslog.scm 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. ; Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees. See file COPYING.
  2. ; Error codes
  3. (import-dynamic-externals "=scheme48external/posix")
  4. (define-enumerated-type syslog-option :syslog-option
  5. syslog-option?
  6. the-syslog-options
  7. syslog-option-name
  8. syslog-option-index
  9. ;; The order of these is known to the C code.
  10. (console
  11. delay
  12. no-delay
  13. log-pid
  14. no-wait))
  15. (define-enum-set-type syslog-options :syslog-options
  16. syslog-options?
  17. make-syslog-options
  18. syslog-option
  19. syslog-option?
  20. the-syslog-options
  21. syslog-option-index)
  22. (define default-syslog-options (syslog-options))
  23. (define-enumerated-type syslog-facility :syslog-facility
  24. syslog-facility?
  25. syslog-facilities
  26. syslog-facility-name
  27. syslog-facility-index
  28. ;; Options for openlog
  29. ;; The order of these is known to the C code.
  30. (authorization
  31. cron
  32. daemon
  33. kernel
  34. lpr
  35. mail
  36. news
  37. user
  38. uucp
  39. local0 local1 local2 local3 local4 local5 local6 local7))
  40. (define default-syslog-facility (syslog-facility user))
  41. (define-enumerated-type syslog-level :syslog-level
  42. syslog-level?
  43. syslog-levels
  44. syslog-level-name
  45. syslog-level-index
  46. ;; The order of these is known to the C code.
  47. (emergency
  48. alert
  49. critical
  50. error
  51. warning
  52. notice
  53. info
  54. debug))
  55. (define-enum-set-type syslog-mask :syslog-mask
  56. syslog-mask?
  57. make-syslog-mask
  58. syslog-level
  59. syslog-level?
  60. syslog-levels
  61. syslog-level-index)
  62. (define (syslog-mask-upto level)
  63. (let loop ((index (syslog-level-index level)) (levels '()))
  64. (if (< index 0)
  65. (make-syslog-mask levels)
  66. (loop (- index 1)
  67. (cons (vector-ref syslog-levels index)
  68. levels)))))
  69. (define syslog-mask-all (make-syslog-mask (vector->list syslog-levels)))
  70. (define default-syslog-mask syslog-mask-all)
  71. ; Low-level interface
  72. (import-lambda-definition-2 posix-openlog (ident options facility) "posix_openlog")
  73. (import-lambda-definition-2 posix-setlogmask (logmask) "posix_setlogmask")
  74. (import-lambda-definition-2 posix-syslog (level facility message) "posix_syslog")
  75. (import-lambda-definition-2 posix-closelog () "posix_closelog")
  76. (define (openlog ident options facility)
  77. (if (not (syslog-options? options))
  78. (assertion-violation 'openlog "options argument is not a :syslog-options object" options))
  79. (posix-openlog (x->os-byte-vector ident)
  80. (enum-set->integer options)
  81. (syslog-facility-index facility)))
  82. (define (setlogmask! logmask)
  83. (if (not (syslog-mask? logmask))
  84. (assertion-violation 'openlog "mask argument is not a :syslog-mask object" logmask))
  85. (posix-setlogmask (enum-set->integer logmask)))
  86. (define (syslog-internal level facility message)
  87. (posix-syslog (syslog-level-index level)
  88. (and facility
  89. (syslog-facility-index facility))
  90. (x->os-byte-vector message)))
  91. (define (closelog)
  92. (posix-closelog))
  93. ; High-level interface
  94. (define-record-type syslog-channel :syslog-channel
  95. (really-make-syslog-channel ident options facility mask)
  96. syslog-channel?
  97. (ident syslog-channel-ident)
  98. (options syslog-channel-options)
  99. (facility syslog-channel-facility)
  100. (mask syslog-channel-mask))
  101. (define (make-syslog-channel ident options facility mask)
  102. (really-make-syslog-channel (x->os-string ident)
  103. options facility mask))
  104. (define (syslog-channel-equivalent? channel-1 channel-2)
  105. (and (os-string=? (syslog-channel-ident channel-1)
  106. (syslog-channel-ident channel-2))
  107. (enum-set=? (syslog-channel-options channel-1)
  108. (syslog-channel-options channel-2))
  109. ;; facility can be specified with each syslog-write
  110. (enum-set=? (syslog-channel-mask channel-1)
  111. (syslog-channel-mask channel-2))))
  112. (define current-syslog-channel 'unitinialized)
  113. (define current-syslog-channel-lock 'unitinialized)
  114. (define (initialize-syslog)
  115. (set! current-syslog-channel #f)
  116. (set! current-syslog-channel-lock (make-lock)))
  117. (define open-syslog-channel make-syslog-channel)
  118. (define (close-syslog-channel channel)
  119. (obtain-lock current-syslog-channel-lock)
  120. (if (syslog-channel-equivalent? channel
  121. current-syslog-channel)
  122. (closelog))
  123. (release-lock current-syslog-channel-lock))
  124. (define (with-syslog-channel channel thunk)
  125. (dynamic-wind
  126. (lambda ()
  127. (obtain-lock current-syslog-channel-lock))
  128. (lambda ()
  129. (if (or (not current-syslog-channel)
  130. (not (syslog-channel-equivalent? channel
  131. current-syslog-channel)))
  132. (begin
  133. (if current-syslog-channel
  134. (closelog))
  135. (openlog (syslog-channel-ident channel)
  136. (syslog-channel-options channel)
  137. (syslog-channel-facility channel))
  138. (if (not (enum-set=? (syslog-channel-mask channel)
  139. default-syslog-mask))
  140. (setlogmask! (syslog-channel-mask channel)))
  141. (set! current-syslog-channel channel)))
  142. (thunk))
  143. (lambda ()
  144. (release-lock current-syslog-channel-lock))))
  145. (define (syslog-write level message channel)
  146. (with-syslog-channel
  147. channel
  148. (lambda ()
  149. (syslog-internal level (syslog-channel-facility channel) message))))
  150. (define (change-syslog-channel channel ident options facility mask)
  151. (make-syslog-channel (if ident
  152. (x->os-string ident)
  153. (syslog-channel-ident channel))
  154. (or options
  155. (syslog-channel-options channel))
  156. (or facility
  157. (syslog-channel-facility channel))
  158. (or mask
  159. (syslog-channel-mask channel))))
  160. ; This is a thread fluid in scsh
  161. (define dynamic-syslog-channel
  162. (make-fluid
  163. (make-syslog-channel "s48"
  164. default-syslog-options
  165. default-syslog-facility
  166. default-syslog-mask)))
  167. (define (syslog level message . rest)
  168. (syslog-write level message
  169. (cond
  170. ((null? rest)
  171. (fluid dynamic-syslog-channel))
  172. ((and (null? (cdr rest))
  173. (syslog-channel? (car rest)))
  174. (car rest))
  175. (else
  176. ;; this might be a little excessive allocation
  177. (apply change-syslog-channel
  178. (fluid dynamic-syslog-channel)
  179. (append rest '(#f)))))))
  180. (define (with-syslog-destination ident options facility mask thunk)
  181. (let-fluid dynamic-syslog-channel
  182. (change-syslog-channel
  183. (fluid dynamic-syslog-channel)
  184. ident options facility mask)
  185. thunk))
  186. ;----------------
  187. ; A record type whose only purpose is to run some code when we start up an
  188. ; image.
  189. (define-record-type reinitializer :reinitializer
  190. (make-reinitializer thunk)
  191. reinitializer?
  192. (thunk reinitializer-thunk))
  193. (define-record-discloser :reinitializer
  194. (lambda (r)
  195. (list 'reinitializer (reinitializer-thunk r))))
  196. (define-record-resumer :reinitializer
  197. (lambda (r)
  198. ((reinitializer-thunk r))))
  199. (initialize-syslog)
  200. (define syslog-reinitializer
  201. (make-reinitializer initialize-syslog))