syslog.scm 6.5 KB

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