scm: add support for logging
Add functions debug, info, warning, critical which log to the mu logging facilities.
This commit is contained in:
@ -21,6 +21,7 @@
|
|||||||
;; after printing UNIX-CONNECT:<socket-file>\n on stdout
|
;; after printing UNIX-CONNECT:<socket-file>\n on stdout
|
||||||
(let ((socket-path (getenv "MU_SCM_SOCKET_PATH")))
|
(let ((socket-path (getenv "MU_SCM_SOCKET_PATH")))
|
||||||
(when socket-path
|
(when socket-path
|
||||||
|
(info "listening on domain socket ~a" socket-path)
|
||||||
(format #t "~a\n" socket-path)
|
(format #t "~a\n" socket-path)
|
||||||
(run-server
|
(run-server
|
||||||
(make-unix-domain-server-socket #:path socket-path))))
|
(make-unix-domain-server-socket #:path socket-path))))
|
||||||
|
|||||||
@ -127,7 +127,8 @@ to_sort_field_id(SCM field, const char *func, int pos)
|
|||||||
|
|
||||||
const auto sym{from_scm<std::string>(scm_symbol_to_string(field), func, pos)};
|
const auto sym{from_scm<std::string>(scm_symbol_to_string(field), func, pos)};
|
||||||
if (const auto field_opt{field_from_name(sym)}; !field_opt) {
|
if (const auto field_opt{field_from_name(sym)}; !field_opt) {
|
||||||
throw ScmError{ScmError::Id::WrongType, func, pos, field, "sort-field-symbol"};
|
throw ScmError{ScmError::Id::WrongType, func, pos, field,
|
||||||
|
"sort-field-symbol"};
|
||||||
} else
|
} else
|
||||||
return field_opt->id;
|
return field_opt->id;
|
||||||
}
|
}
|
||||||
@ -144,7 +145,8 @@ subr_cc_store_mfind(SCM store_scm, SCM query_scm, SCM related_scm, SCM skip_dups
|
|||||||
const auto skip_dups(from_scm<bool>(skip_dups_scm, func, 4));
|
const auto skip_dups(from_scm<bool>(skip_dups_scm, func, 4));
|
||||||
|
|
||||||
if (!scm_is_false(sort_field_scm) && !scm_is_symbol(sort_field_scm))
|
if (!scm_is_false(sort_field_scm) && !scm_is_symbol(sort_field_scm))
|
||||||
throw ScmError{ScmError::Id::WrongType, func, 5, sort_field_scm, "#f or sort-field-symbol"};
|
throw ScmError{ScmError::Id::WrongType, func, 5, sort_field_scm,
|
||||||
|
"#f or sort-field-symbol"};
|
||||||
|
|
||||||
const auto sort_field_id = to_sort_field_id(sort_field_scm, func, 5);
|
const auto sort_field_id = to_sort_field_id(sort_field_scm, func, 5);
|
||||||
const auto reverse(from_scm<bool>(reverse_scm, func, 6));
|
const auto reverse(from_scm<bool>(reverse_scm, func, 6));
|
||||||
|
|||||||
@ -64,6 +64,46 @@ init_options(const Options& opts)
|
|||||||
scm_c_define("%options", scm_opts);
|
scm_c_define("%options", scm_opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_misc()
|
||||||
|
{
|
||||||
|
scm_define(make_symbol("level-critical"), to_scm(G_LOG_LEVEL_CRITICAL));
|
||||||
|
scm_define(make_symbol("level-warning"), to_scm(G_LOG_LEVEL_WARNING));
|
||||||
|
scm_define(make_symbol("level-info"), to_scm(G_LOG_LEVEL_INFO));
|
||||||
|
scm_define(make_symbol("level-debug"), to_scm(G_LOG_LEVEL_DEBUG));
|
||||||
|
}
|
||||||
|
|
||||||
|
static SCM
|
||||||
|
subr_cc_log(SCM level_scm, SCM str_scm) try {
|
||||||
|
constexpr auto func{"cc-log"};
|
||||||
|
|
||||||
|
const auto level{static_cast<GLogLevelFlags>(from_scm<int>(level_scm, func, 1))};
|
||||||
|
if (level != G_LOG_LEVEL_CRITICAL && level != G_LOG_LEVEL_WARNING &&
|
||||||
|
level != G_LOG_LEVEL_INFO && level != G_LOG_LEVEL_DEBUG)
|
||||||
|
throw ScmError{ScmError::Id::WrongType, func, 1, level_scm, "level"};
|
||||||
|
|
||||||
|
const auto str{from_scm<std::string>(str_scm, func, 2)};
|
||||||
|
|
||||||
|
g_log("mu-scm", level, "%s", str.c_str());
|
||||||
|
|
||||||
|
return SCM_UNSPECIFIED;
|
||||||
|
|
||||||
|
} catch (const ScmError& err) {
|
||||||
|
err.throw_scm();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_subrs()
|
||||||
|
{
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||||
|
scm_c_define_gsubr("cc-log", 2/*req*/, 0/*opt*/, 0/*rst*/,
|
||||||
|
reinterpret_cast<scm_t_subr>(subr_cc_log));
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static const Result<std::string>
|
static const Result<std::string>
|
||||||
make_mu_scm_path(const std::string& fname) {
|
make_mu_scm_path(const std::string& fname) {
|
||||||
|
|
||||||
@ -157,8 +197,6 @@ maybe_remove_socket_path()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
prepare_shell(const Options& opts, StrVec& args)
|
prepare_shell(const Options& opts, StrVec& args)
|
||||||
{
|
{
|
||||||
@ -186,6 +224,9 @@ init_module_mu(void* data)
|
|||||||
const ModMuData& conf{*reinterpret_cast<ModMuData*>(data)};
|
const ModMuData& conf{*reinterpret_cast<ModMuData*>(data)};
|
||||||
|
|
||||||
init_options(conf.opts);
|
init_options(conf.opts);
|
||||||
|
init_misc();
|
||||||
|
init_subrs();
|
||||||
|
|
||||||
init_store(conf.store);
|
init_store(conf.store);
|
||||||
init_message();
|
init_message();
|
||||||
init_mime();
|
init_mime();
|
||||||
|
|||||||
@ -227,6 +227,10 @@ namespace Mu::Scm {
|
|||||||
return scm_from_bool(val);
|
return scm_from_bool(val);
|
||||||
else if constexpr (std::is_same_v<Type, size_t>)
|
else if constexpr (std::is_same_v<Type, size_t>)
|
||||||
return scm_from_size_t(val);
|
return scm_from_size_t(val);
|
||||||
|
else if constexpr (std::is_same_v<Type, int>)
|
||||||
|
return scm_from_int(val);
|
||||||
|
else if constexpr (std::is_same_v<Type, GLogLevelFlags>)
|
||||||
|
return scm_from_int(static_cast<int>(val));
|
||||||
else if constexpr (std::is_same_v<Type, int64_t>)
|
else if constexpr (std::is_same_v<Type, int64_t>)
|
||||||
return scm_from_int64(val);
|
return scm_from_int64(val);
|
||||||
else if constexpr (std::is_same_v<Type, uint64_t>)
|
else if constexpr (std::is_same_v<Type, uint64_t>)
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
:use-module (system foreign)
|
:use-module (system foreign)
|
||||||
:use-module (rnrs bytevectors)
|
:use-module (rnrs bytevectors)
|
||||||
:use-module (ice-9 optargs)
|
:use-module (ice-9 optargs)
|
||||||
|
:use-module (ice-9 format)
|
||||||
:use-module (ice-9 binary-ports)
|
:use-module (ice-9 binary-ports)
|
||||||
#:export (
|
#:export (
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
@ -100,11 +101,16 @@
|
|||||||
%options
|
%options
|
||||||
;; %preferences
|
;; %preferences
|
||||||
|
|
||||||
|
;; logging
|
||||||
|
debug
|
||||||
|
info
|
||||||
|
warning
|
||||||
|
critical
|
||||||
|
|
||||||
;; helpers
|
;; helpers
|
||||||
string->time
|
string->time
|
||||||
time->string))
|
time->string))
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;;
|
;;
|
||||||
;; Helpers
|
;; Helpers
|
||||||
@ -637,3 +643,43 @@ UTC time.
|
|||||||
(let ((t (if utc? (gmtime time-t) (localtime time-t))))
|
(let ((t (if utc? (gmtime time-t) (localtime time-t))))
|
||||||
(strftime format t))
|
(strftime format t))
|
||||||
#f)))
|
#f)))
|
||||||
|
|
||||||
|
|
||||||
|
;; Logging to mu's log
|
||||||
|
|
||||||
|
(define (mlog level frmstr . args)
|
||||||
|
"Log to the mu logger.
|
||||||
|
|
||||||
|
LEVEL is the logging-level, a symbol one of:
|
||||||
|
debug, info, warning, critical
|
||||||
|
|
||||||
|
FRMSTR is a format string like `(format)', and the ARGS are the parameters for
|
||||||
|
that format string."
|
||||||
|
(let ((msg (if (null? args)
|
||||||
|
frmstr
|
||||||
|
(apply format #f frmstr args))))
|
||||||
|
(cc-log level msg)))
|
||||||
|
|
||||||
|
(define (info frm . args)
|
||||||
|
"Log a message at info level to the mu logger.
|
||||||
|
FRM is the format string and ARGS are its arguments, see `(format)' for details
|
||||||
|
on the precise format."
|
||||||
|
(apply mlog level-info frm args))
|
||||||
|
|
||||||
|
(define (warning frm . args)
|
||||||
|
"Log a message at warning level to the mu logger.
|
||||||
|
FRM is the format string and ARGS are its arguments, see `(format)' for details
|
||||||
|
on the precise format."
|
||||||
|
(apply mlog level-warning frm args))
|
||||||
|
|
||||||
|
(define (critical frm . args)
|
||||||
|
"Log a message at critical level to the mu logger.
|
||||||
|
FRM is the format string and ARGS are its arguments, see `(format)' for details
|
||||||
|
on the precise format."
|
||||||
|
(apply mlog level-critical frm args))
|
||||||
|
|
||||||
|
(define (debug frm . args)
|
||||||
|
"Log a message at debug level to the mu logger.
|
||||||
|
FRM is the format string and ARGS are its arguments, see `(format)' for details
|
||||||
|
on the precise format."
|
||||||
|
(apply mlog level-debug frm args))
|
||||||
|
|||||||
@ -939,6 +939,26 @@ their default values.
|
|||||||
@node Helpers
|
@node Helpers
|
||||||
@section Helpers
|
@section Helpers
|
||||||
|
|
||||||
|
@deffn {Scheme Procedure} debug frm . args
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn {Scheme Procedure} info frm . args
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn {Scheme Procedure} warning frm . args
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
@deffn {Scheme Procedure} critical frm . args
|
||||||
|
@end deffn
|
||||||
|
|
||||||
|
Log using @t{mu}'s logging facilities at the given level (debug, info, warning
|
||||||
|
or critical). @code{frm} and @code{args} are expected to be a format string and
|
||||||
|
its arguments, respectively, according to Guile's @code{format} function.
|
||||||
|
|
||||||
|
Note: where the log output exactly appears (i.e., log-file, journal, console,
|
||||||
|
nowhere) dependis on the particulars of the system and how mu was started; see
|
||||||
|
the @t{mu (1)} man-page for details on the latter.
|
||||||
|
|
||||||
@deffn {Scheme Procedure} string->time timestr [#:utc? (assoc-ref %preferences 'utc?)]
|
@deffn {Scheme Procedure} string->time timestr [#:utc? (assoc-ref %preferences 'utc?)]
|
||||||
@end deffn
|
@end deffn
|
||||||
Convert some ISO-8601-style time-string to a seconds-since-epoch @t{time_t}
|
Convert some ISO-8601-style time-string to a seconds-since-epoch @t{time_t}
|
||||||
|
|||||||
Reference in New Issue
Block a user