\ (email-log-report) NOTICE add-error-logging\r
\r
: email-log-report ( service word-names -- )\r
- "logging.insomniac" [ (email-log-report) ] with-logging ;\r
+ "logging.insomniac" DEBUG [ (email-log-report) ] with-logging ;\r
\r
: schedule-insomniac ( service word-names -- )\r
[ [ email-log-report ] assoc-each rotate-logs ] 2curry\r
HELP: NOTICE
{ $description "Log level for ordinary messages." } ;
+HELP: WARNING
+{ $description "Log level for warnings." } ;
+
HELP: ERROR
{ $description "Log level for error messages." } ;
"Several log levels are supported, from lowest to highest:"
{ $subsection DEBUG }
{ $subsection NOTICE }
+{ $subsection WARNING }
{ $subsection ERROR }
{ $subsection CRITICAL } ;
HELP: log-message
{ $values { "msg" string } { "word" word } { "level" "a log level" } }
-{ $description "Sends a message to the current log. Does nothing if not executing in a dynamic scope established by " { $link with-logging } "." } ;
+{ $description "Sends a message to the current log if the level is more urgent than " { $link log-level } ". Does nothing if not executing in a dynamic scope established by " { $link with-logging } "." } ;
HELP: add-logging
{ $values { "level" "a log level" } { "word" word } }
{ $description "Closes all open log streams. Subsequent logging will re-open the streams. This should be used before moving or deleting log files." } ;
HELP: with-logging
-{ $values { "service" "a log service name" } { "quot" quotation } }
-{ $description "Calls the quotation a new dynamic scope where all logging calls are sent to the log file for " { $snippet "service" } "." } ;
+{ $values { "service" "a log service name" } { "level" "a log level" } { "quot" quotation } }
+{ $description "Calls the quotation a new dynamic scope where all logging calls more urgent than " { $link log-level } " are sent to the log file for " { $snippet "service" } "." } ;
ARTICLE: "logging.rotation" "Log rotation"
"Log files should be rotated periodically to prevent unbounded growth."
{ $subsection "logging.server" } ;
ABOUT: "logging"
-
words kernel arrays shuffle tools.annotations\r
prettyprint.config prettyprint debugger io.streams.string\r
splitting continuations effects generalizations parser strings\r
-quotations fry accessors ;\r
+quotations fry accessors math assocs math.order ;\r
IN: logging\r
\r
SYMBOLS: DEBUG NOTICE WARNING ERROR CRITICAL ;\r
\r
-: log-levels { DEBUG NOTICE NOTICE WARNING ERROR CRITICAL } ;\r
+SYMBOL: log-level\r
+\r
+: log-levels ( -- assoc )\r
+ H{\r
+ { DEBUG 0 }\r
+ { NOTICE 10 }\r
+ { WARNING 20 }\r
+ { ERROR 30 }\r
+ { CRITICAL 40 }\r
+ } ;\r
+\r
+ERROR: undefined-log-level ;\r
+\r
+: log-level<=> ( log-level log-level -- ? )\r
+ [ log-levels at* [ undefined-log-level ] unless ] bi@ <=> ;\r
+\r
+: log? ( log-level -- ? )\r
+ log-level get log-level<=> +lt+ = not ;\r
\r
: send-to-log-server ( array string -- )\r
prefix "log-server" get send ;\r
\r
: log-message ( msg word level -- )\r
check-log-message\r
- log-service get dup [\r
+ dup log?\r
+ log-service get dup and [\r
[ [ string-lines ] [ name>> ] [ name>> ] tri* ] dip\r
4array "log-message" send-to-log-server\r
] [\r
: close-logs ( -- )\r
{ } "close-logs" send-to-log-server ;\r
\r
-: with-logging ( service quot -- )\r
- log-service swap with-variable ; inline\r
+: with-logging ( service level quot -- )\r
+ '[\r
+ _ log-service [ _ log-level _ with-variable ] with-variable\r
+ ] call ; inline\r
\r
! Aspect-oriented programming idioms\r
\r
USING: accessors peg peg.parsers memoize kernel sequences\r
logging arrays words strings vectors io io.files\r
io.encodings.utf8 namespaces make combinators logging.server\r
-calendar calendar.format ;\r
+calendar calendar.format assocs ;\r
IN: logging.parser\r
\r
TUPLE: log-entry date level word-name message ;\r
"[" "]" surrounded-by ;\r
\r
: 'log-level' ( -- parser )\r
- log-levels [\r
+ log-levels keys [\r
[ name>> token ] keep [ nip ] curry action\r
] map choice ;\r
\r