From 24bd2dbb85d12f1d435180c328950035205b0af5 Mon Sep 17 00:00:00 2001 From: David Scott Date: Tue, 19 Mar 2013 16:53:01 +0000 Subject: oxenstored: enable logging via syslog, if specified in the config file. To log to files the config file should contain: xenstored-log-file = /var/log/xenstored.log access-log-file = /var/log/xenstored-access.log (These two files are still the built-in defaults. The log format is unchanged.) To log to syslog the config file should contain: xenstored-log-file = syslog: access-log-file = syslog: where is the syslog facility to use (e.g. 'daemon' 'local2') Signed-off-by: David Scott --- tools/ocaml/xenstored/logging.ml | 124 +++++++++++++++++++++++++++---------- tools/ocaml/xenstored/xenstored.ml | 4 +- 2 files changed, 94 insertions(+), 34 deletions(-) (limited to 'tools/ocaml') diff --git a/tools/ocaml/xenstored/logging.ml b/tools/ocaml/xenstored/logging.ml index bc3a2ea01b..e26f804224 100644 --- a/tools/ocaml/xenstored/logging.ml +++ b/tools/ocaml/xenstored/logging.ml @@ -20,11 +20,42 @@ open Printf (* Logger common *) +type log_destination = + | File of string + | Syslog of Syslog.facility + +let log_destination_of_string s = + let prefix = "syslog:" in + let len_prefix = String.length prefix in + let len = String.length s in + if String.startswith prefix s + then Syslog(Syslog.facility_of_string (String.sub s len_prefix (len - len_prefix))) + else File s + +(* The prefix of a log line depends on the log destination *) +let prefix log_destination ?level ?key date = match log_destination with + | File _ -> + let level = match level with + | Some x -> Printf.sprintf "|%5s" x + | None -> "" in + let key = match key with + | Some x -> "|" ^ x + | None -> "" in + Printf.sprintf "[%s%s%s] " date level key + | Syslog _ -> + let key = match key with + | Some x -> "[" ^ x ^ "] " + | None -> "" in + (* Syslog handles the date and level internally *) + key + +type level = Debug | Info | Warn | Error | Null + type logger = { stop: unit -> unit; restart: unit -> unit; rotate: unit -> unit; - write: 'a. ('a, unit, string, unit) format4 -> 'a } + write: ?level:level -> string -> unit } let truncate_line nb_chars line = if String.length line > nb_chars - 1 then @@ -54,7 +85,7 @@ let log_rotate ref_ch log_file log_nb_files = close_out !ref_ch; ref_ch := open_out log_file -let make_logger log_file log_nb_files log_nb_lines log_nb_chars post_rotate = +let make_file_logger log_file log_nb_files log_nb_lines log_nb_chars post_rotate = let channel = ref (open_out_gen [Open_append; Open_creat] 0o644 log_file) in let counter = ref 0 in let stop() = @@ -67,22 +98,17 @@ let make_logger log_file log_nb_files log_nb_lines log_nb_chars post_rotate = log_rotate channel log_file log_nb_files; (post_rotate (): unit); counter := 0 in - let output s = + let write ?level s = let s = if log_nb_chars > 0 then truncate_line log_nb_chars s else s in let s = s ^ "\n" in output_string !channel s; flush !channel; incr counter; if !counter > log_nb_lines then rotate() in - { stop=stop; restart=restart; rotate=rotate; write = fun fmt -> Printf.ksprintf output fmt } - - -(* Xenstored logger *) + { stop=stop; restart=restart; rotate=rotate; write=write } exception Unknown_level of string -type level = Debug | Info | Warn | Error | Null - let int_of_level = function | Debug -> 0 | Info -> 1 | Warn -> 2 | Error -> 3 | Null -> max_int @@ -104,30 +130,56 @@ let string_of_date () = tm.Unix.tm_hour tm.Unix.tm_min tm.Unix.tm_sec (int_of_float (1000.0 *. msec)) -let xenstored_log_file = ref "/var/log/xenstored.log" +let make_syslog_logger facility = + (* We defer to syslog for log management *) + let nothing () = () in + let write ?level s = + let level = match level with + | Some Error -> Syslog.Err + | Some Warn -> Syslog.Warning + | Some Info -> Syslog.Info + | Some Debug -> Syslog.Debug + | Some Null -> Syslog.Debug + | None -> Syslog.Debug in + (* Syslog handles the date and level internally *) + Syslog.log facility level s in + { stop = nothing; restart = nothing; rotate = nothing; write=write } + +let xenstored_log_destination = ref (File "/var/log/xenstored.log") let xenstored_log_level = ref Warn let xenstored_log_nb_files = ref 10 let xenstored_log_nb_lines = ref 13215 let xenstored_log_nb_chars = ref (-1) let xenstored_logger = ref (None: logger option) -let init_xenstored_log () = - if !xenstored_log_level <> Null && !xenstored_log_nb_files > 0 then - let logger = - make_logger - !xenstored_log_file !xenstored_log_nb_files !xenstored_log_nb_lines - !xenstored_log_nb_chars ignore in - let date = string_of_date() in - logger.write ("[%s|%5s|%s] Xen Storage Daemon, version %d.%d") date "" "startup" - Define.xenstored_major Define.xenstored_minor; - xenstored_logger := Some logger +let set_xenstored_log_destination s = + xenstored_log_destination := log_destination_of_string s + +let set_xenstored_logger logger = + xenstored_logger := Some logger; + logger.write ~level:Info (Printf.sprintf "Xen Storage Daemon, version %d.%d" + Define.xenstored_major Define.xenstored_minor) + + +let init_xenstored_log () = match !xenstored_log_destination with + | File file -> + if !xenstored_log_level <> Null && !xenstored_log_nb_files > 0 then + let logger = + make_file_logger + file !xenstored_log_nb_files !xenstored_log_nb_lines + !xenstored_log_nb_chars ignore in + set_xenstored_logger logger + | Syslog facility -> + set_xenstored_logger (make_syslog_logger facility) + let xenstored_logging level key (fmt: (_,_,_,_) format4) = match !xenstored_logger with | Some logger when int_of_level level >= int_of_level !xenstored_log_level -> let date = string_of_date() in - let level = string_of_level level in - logger.write ("[%s|%5s|%s] " ^^ fmt) date level key + let level' = string_of_level level in + let prefix = prefix !xenstored_log_destination ~level:level' ~key date in + Printf.ksprintf (fun s -> logger.write ~level (prefix ^ s)) fmt | _ -> Printf.ksprintf ignore fmt let debug key = xenstored_logging Debug key @@ -200,7 +252,7 @@ let sanitize_data data = String.escaped data let activate_access_log = ref true -let access_log_file = ref "/var/log/xenstored-access.log" +let access_log_destination = ref (File "/var/log/xenstored-access.log") let access_log_nb_files = ref 20 let access_log_nb_lines = ref 13215 let access_log_nb_chars = ref 180 @@ -209,14 +261,20 @@ let access_log_transaction_ops = ref false let access_log_special_ops = ref false let access_logger = ref None -let init_access_log post_rotate = - if !access_log_nb_files > 0 then - let logger = - make_logger - !access_log_file !access_log_nb_files !access_log_nb_lines - !access_log_nb_chars post_rotate in - access_logger := Some logger - +let set_access_log_destination s = + access_log_destination := log_destination_of_string s + +let init_access_log post_rotate = match !access_log_destination with + | File file -> + if !access_log_nb_files > 0 then + let logger = + make_file_logger + file !access_log_nb_files !access_log_nb_lines + !access_log_nb_chars post_rotate in + access_logger := Some logger + | Syslog facility -> + access_logger := Some (make_syslog_logger facility) + let access_logging ~con ~tid ?(data="") access_type = try maybe @@ -225,7 +283,9 @@ let access_logging ~con ~tid ?(data="") access_type = let tid = string_of_tid ~con tid in let access_type = string_of_access_type access_type in let data = sanitize_data data in - logger.write "[%s] %s %s %s" date tid access_type data) + let prefix = prefix !access_log_destination date in + let msg = Printf.sprintf "%s %s %s %s" prefix tid access_type data in + logger.write msg) !access_logger with _ -> () diff --git a/tools/ocaml/xenstored/xenstored.ml b/tools/ocaml/xenstored/xenstored.ml index 64cc106461..3416666382 100644 --- a/tools/ocaml/xenstored/xenstored.ml +++ b/tools/ocaml/xenstored/xenstored.ml @@ -87,13 +87,13 @@ let parse_config filename = ("quota-maxsize", Config.Set_int Quota.maxsize); ("test-eagain", Config.Set_bool Transaction.test_eagain); ("persistent", Config.Set_bool Disk.enable); - ("xenstored-log-file", Config.Set_string Logging.xenstored_log_file); + ("xenstored-log-file", Config.String Logging.set_xenstored_log_destination); ("xenstored-log-level", Config.String (fun s -> Logging.xenstored_log_level := Logging.level_of_string s)); ("xenstored-log-nb-files", Config.Set_int Logging.xenstored_log_nb_files); ("xenstored-log-nb-lines", Config.Set_int Logging.xenstored_log_nb_lines); ("xenstored-log-nb-chars", Config.Set_int Logging.xenstored_log_nb_chars); - ("access-log-file", Config.Set_string Logging.access_log_file); + ("access-log-file", Config.String Logging.set_access_log_destination); ("access-log-nb-files", Config.Set_int Logging.access_log_nb_files); ("access-log-nb-lines", Config.Set_int Logging.access_log_nb_lines); ("access-log-nb-chars", Config.Set_int Logging.access_log_nb_chars); -- cgit v1.2.3