let filesize = ref 0
let mutex = Mutex.create ()
-let output t ?(key="") ?(extra="") priority (message: string) =
+let output_common t ?(raw=false) ?(key="") ?(extra="") priority (message: string) =
+ let result_string = ref "" in
let construct_string withtime =
(*let key = if key = "" then [] else [ key ] in
let extra = if extra = "" then [] else [ extra ] in
@ [ sprintf "%5s" (string_of_level priority) ] @ extra @ key @ [ message ] in
(* let items = !extra_hook items in*)
String.concat " " items*)
+ result_string := (
+ if raw
+ then Printf.sprintf "%s" message
+ else
Printf.sprintf "[%s%.5s|%s] %s"
(if withtime then gettimestring () else "") (string_of_level priority) extra message
+ );
+ !result_string
in
(* Keep track of how much we write out to streams, so that we can *)
(* log-rotate at appropriate times *)
in
if String.length message > 0 then
- match t.output with
+ (match t.output with
| Syslog k ->
let sys_prio = match priority with
| Debug -> Syslog.Debug
| None -> ())
| Nil -> ()
| String s -> (s := (construct_string true)::!s)
+ );
+ !result_string
+
+let output t ?(key="") ?(extra="") priority (message: string) =
+ ignore(output_common t ~key ~extra priority message)
+
+let output_and_return t ?(raw=false) ?(key="") ?(extra="") priority (message: string) =
+ output_common t ~raw ~key ~extra priority message
let log t level (fmt: ('a, unit, string, unit) format4): 'a =
let b = (int_of_level t.level) <= (int_of_level level) in
val filesize : int ref
val mutex : Mutex.t
val output : t -> ?key:string -> ?extra:string -> level -> string -> unit
+val output_and_return : t -> ?raw:bool -> ?key:string -> ?extra:string -> level -> string -> string
val log : t -> level -> ('a, unit, string, unit) format4 -> 'a
val debug : t -> ('a, unit, string, unit) format4 -> 'a
val info : t -> ('a, unit, string, unit) format4 -> 'a
(** log a fmt message to the key|level logger specified in the log mapping.
* if the logger doesn't exist, assume nil logger.
*)
-let log key level ?(extra="") (fmt: ('a, unit, string, unit) format4): 'a =
+let log_common key level ?(extra="") ~ret_fn1 ~ret_fn2 (fmt: ('a, unit, string, 'b) format4): 'a =
let keylog =
if Hashtbl.mem __log_mapping key then
let keylog = Hashtbl.find __log_mapping key in
__default_logger in
let loggers = get_by_level keylog level in
match loggers with
- | [] -> Printf.kprintf ignore fmt
+ | [] -> Printf.kprintf ret_fn1 fmt
| _ ->
let l = List.fold_left (fun acc logger ->
try get_or_open logger :: acc
with _ -> acc
) [] loggers in
let l = List.rev l in
+ ret_fn2 l
+
+let log key level ?(extra="") (fmt: ('a, unit, string, unit) format4): 'a =
+ log_common key level ~extra ~ret_fn1:(ignore) fmt
+ ~ret_fn2:(fun l ->
+ (* ksprintf is the preferred name for kprintf, but the former
+ * is not available in OCaml 3.08.3 *)
+ Printf.kprintf (fun s ->
+ List.iter (fun t -> Log.output t ~key ~extra level s) l) fmt
+ )
+
+let log_and_return key level ?(raw=false) ?(extra="") (fmt: ('a, unit, string, string) format4): 'a =
+ log_common key level ~extra ~ret_fn1:(fun s->s) fmt
+ ~ret_fn2:(fun l ->
+ let ret_str = ref "" in
+ Printf.kprintf (fun s ->
+ List.iter (fun t -> ret_str := Log.output_and_return t ~raw ~key ~extra level s) l; !ret_str) fmt
+ )
- (* ksprintf is the preferred name for kprintf, but the former
- * is not available in OCaml 3.08.3 *)
- Printf.kprintf (fun s ->
- List.iter (fun t -> Log.output t ~key ~extra level s) l) fmt
(* define some convenience functions *)
let debug t ?extra (fmt: ('a , unit, string, unit) format4) =
log t Log.Warn ?extra fmt
let error t ?extra (fmt: ('a , unit, string, unit) format4) =
log t Log.Error ?extra fmt
+let audit t ?raw ?extra (fmt: ('a , unit, string, string) format4) =
+ log_and_return t Log.Debug ?raw ?extra fmt