Reviewed By: mityal Differential Revision: D15898726 fbshipit-source-id: e8609f10dmaster
parent
3de7acada4
commit
046132b4c5
@ -0,0 +1,40 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*)
|
||||||
|
|
||||||
|
open! IStd
|
||||||
|
|
||||||
|
type count_entry_data = {value: int}
|
||||||
|
|
||||||
|
type time_entry_data = {duration_ms: int}
|
||||||
|
|
||||||
|
type entry_data = Count of count_entry_data | Time of time_entry_data
|
||||||
|
|
||||||
|
type t = {label: string; created_at_ts: int; data: entry_data}
|
||||||
|
|
||||||
|
let mk_count ~label ~value =
|
||||||
|
let created_at_ts = Unix.time () |> int_of_float in
|
||||||
|
let data = Count {value} in
|
||||||
|
{label; created_at_ts; data}
|
||||||
|
|
||||||
|
|
||||||
|
let mk_time ~label ~duration_ms =
|
||||||
|
let created_at_ts = Unix.time () |> int_of_float in
|
||||||
|
let data = Time {duration_ms} in
|
||||||
|
{label; created_at_ts; data}
|
||||||
|
|
||||||
|
|
||||||
|
(** What _global_ mean at this point is subject to discussion. Right now
|
||||||
|
there is only one use-case which is Scuba+Scribe logging at the end of
|
||||||
|
execution. But there might be more. Let's change the naming accordingly
|
||||||
|
when the purpose gets clearer. *)
|
||||||
|
let global_entry_log : t list ref = ref []
|
||||||
|
|
||||||
|
let global_log_get () = List.rev !global_entry_log
|
||||||
|
|
||||||
|
let global_log_erase () = global_entry_log := []
|
||||||
|
|
||||||
|
let global_log_add entry = global_entry_log := entry :: !global_entry_log
|
@ -0,0 +1,32 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*)
|
||||||
|
|
||||||
|
open! IStd
|
||||||
|
|
||||||
|
(**
|
||||||
|
Log entry data model, global log entry store and functions to manipulate it.
|
||||||
|
Direct access to the store is not exposed.
|
||||||
|
*)
|
||||||
|
|
||||||
|
type count_entry_data = {value: int}
|
||||||
|
|
||||||
|
type time_entry_data = {duration_ms: int}
|
||||||
|
|
||||||
|
type entry_data = Count of count_entry_data | Time of time_entry_data
|
||||||
|
|
||||||
|
(** created_at_ts is a unix timestamp (in seconds) *)
|
||||||
|
type t = {label: string; created_at_ts: int; data: entry_data}
|
||||||
|
|
||||||
|
val mk_count : label:string -> value:int -> t
|
||||||
|
|
||||||
|
val mk_time : label:string -> duration_ms:int -> t
|
||||||
|
|
||||||
|
val global_log_get : unit -> t list
|
||||||
|
|
||||||
|
val global_log_erase : unit -> unit
|
||||||
|
|
||||||
|
val global_log_add : t -> unit
|
@ -1,64 +0,0 @@
|
|||||||
(*
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
*)
|
|
||||||
(* FB-ONLY *)
|
|
||||||
|
|
||||||
(*
|
|
||||||
* Utilities to log in "infer_events" key-value scuba table.
|
|
||||||
*)
|
|
||||||
open! IStd
|
|
||||||
|
|
||||||
let hostname = Unix.gethostname ()
|
|
||||||
|
|
||||||
let maybe_add_normal ~name ~value sample =
|
|
||||||
match value with None -> sample | Some value -> Scuba.add_normal ~name ~value sample
|
|
||||||
|
|
||||||
|
|
||||||
let set_command_line_normales sample =
|
|
||||||
let add_normal ~key ~data = Scuba.add_normal ~name:key ~value:data in
|
|
||||||
Map.fold Config.scuba_normals ~init:sample ~f:add_normal
|
|
||||||
|
|
||||||
|
|
||||||
let set_common_fields sample =
|
|
||||||
let open Scuba in
|
|
||||||
sample
|
|
||||||
|> add_int ~name:"pid" ~value:(ProcessPoolState.get_pid () |> Pid.to_int)
|
|
||||||
|> add_int ~name:"is_main_process" ~value:(Bool.to_int CommandLineOption.is_originator)
|
|
||||||
|> add_normal ~name:"hostname" ~value:hostname
|
|
||||||
|> maybe_add_normal ~name:"job_id" ~value:Config.job_id
|
|
||||||
|> add_normal ~name:"command" ~value:(InferCommand.to_string Config.command)
|
|
||||||
|> add_normal ~name:"infer_commit" ~value:Version.commit
|
|
||||||
|
|
||||||
|
|
||||||
let create_sample ~event_name ~value =
|
|
||||||
Scuba.new_sample ~time:None |> set_common_fields |> set_command_line_normales
|
|
||||||
|> Scuba.add_normal ~name:"event" ~value:event_name
|
|
||||||
|> Scuba.add_int ~name:"value" ~value
|
|
||||||
|
|
||||||
|
|
||||||
type event_type = Count | Time
|
|
||||||
|
|
||||||
let string_of_event_type = function Count -> "count" | Time -> "time"
|
|
||||||
|
|
||||||
let log event_type ~event_suffix ~value =
|
|
||||||
let event_name = string_of_event_type event_type ^ "." ^ event_suffix in
|
|
||||||
let sample = create_sample ~event_name ~value in
|
|
||||||
Scuba.log Scuba.InferEvents [sample]
|
|
||||||
|
|
||||||
|
|
||||||
(* If scuba logging is disabled, we would not log anyway, but let's not even try
|
|
||||||
to create samples to save perf *)
|
|
||||||
let log = if Config.scuba_logging then log else fun _ ~event_suffix:_ ~value:_ -> ()
|
|
||||||
|
|
||||||
let log_count ~name ~value = log Count ~event_suffix:name ~value
|
|
||||||
|
|
||||||
let log_time ~name ~duration_ms = log Time ~event_suffix:name ~value:duration_ms
|
|
||||||
|
|
||||||
let execute_with_time_logging name f =
|
|
||||||
let start_time = Mtime_clock.counter () in
|
|
||||||
let ret_val = f () in
|
|
||||||
let duration_ms = Mtime_clock.count start_time |> Mtime.Span.to_ms |> int_of_float in
|
|
||||||
log_time ~name ~duration_ms ; ret_val
|
|
@ -0,0 +1,76 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*)
|
||||||
|
(* FB-ONLY *)
|
||||||
|
|
||||||
|
(*
|
||||||
|
* Utilities to log in "infer_events" key-value scuba table.
|
||||||
|
*)
|
||||||
|
open! IStd
|
||||||
|
|
||||||
|
let hostname = Unix.gethostname ()
|
||||||
|
|
||||||
|
let maybe_add_normal ~name ~value sample =
|
||||||
|
match value with None -> sample | Some value -> Scuba.add_normal ~name ~value sample
|
||||||
|
|
||||||
|
|
||||||
|
let set_command_line_normales sample =
|
||||||
|
let add_normal ~key ~data = Scuba.add_normal ~name:key ~value:data in
|
||||||
|
Map.fold Config.scuba_normals ~init:sample ~f:add_normal
|
||||||
|
|
||||||
|
|
||||||
|
let set_common_fields sample =
|
||||||
|
let open Scuba in
|
||||||
|
sample
|
||||||
|
|> add_int ~name:"pid" ~value:(ProcessPoolState.get_pid () |> Pid.to_int)
|
||||||
|
|> add_int ~name:"is_main_process" ~value:(Bool.to_int CommandLineOption.is_originator)
|
||||||
|
|> add_normal ~name:"hostname" ~value:hostname
|
||||||
|
|> maybe_add_normal ~name:"job_id" ~value:Config.job_id
|
||||||
|
|> add_normal ~name:"command" ~value:(InferCommand.to_string Config.command)
|
||||||
|
|> add_normal ~name:"infer_commit" ~value:Version.commit
|
||||||
|
|
||||||
|
|
||||||
|
let sample_from_event ({label; created_at_ts; data} : LogEntry.t) =
|
||||||
|
let event_name, value =
|
||||||
|
match data with
|
||||||
|
| LogEntry.Count {value} ->
|
||||||
|
(Printf.sprintf "count.%s" label, value)
|
||||||
|
| LogEntry.Time {duration_ms} ->
|
||||||
|
(Printf.sprintf "time.%s" label, duration_ms)
|
||||||
|
in
|
||||||
|
Scuba.new_sample ~time:(Some created_at_ts)
|
||||||
|
|> set_common_fields |> set_command_line_normales
|
||||||
|
|> Scuba.add_normal ~name:"event" ~value:event_name
|
||||||
|
|> Scuba.add_int ~name:"value" ~value
|
||||||
|
|
||||||
|
|
||||||
|
(** Consider buffering or batching if proves to be a problem *)
|
||||||
|
let log_many entries =
|
||||||
|
let samples = List.map entries ~f:sample_from_event in
|
||||||
|
Scuba.log Scuba.InferEvents samples
|
||||||
|
|
||||||
|
|
||||||
|
(** If scuba logging is disabled, we would not log anyway, but let's not even try
|
||||||
|
to create samples to save perf *)
|
||||||
|
let log_many = if Config.scuba_logging then log_many else fun _ -> ()
|
||||||
|
|
||||||
|
let log_one entry = log_many [entry]
|
||||||
|
|
||||||
|
let log_count ~label ~value = log_one (LogEntry.mk_count ~label ~value)
|
||||||
|
|
||||||
|
let execute_with_time_logging label f =
|
||||||
|
let ret_val, duration_ms = Utils.timeit ~f in
|
||||||
|
let entry = LogEntry.mk_time ~label ~duration_ms in
|
||||||
|
log_one entry ; ret_val
|
||||||
|
|
||||||
|
|
||||||
|
let flush_log_events () =
|
||||||
|
log_many (LogEntry.global_log_get ()) ;
|
||||||
|
LogEntry.global_log_erase ()
|
||||||
|
|
||||||
|
|
||||||
|
let register_global_log_flushing_at_exit () =
|
||||||
|
Epilogues.register ~f:flush_log_events ~description:"Flushing global log entries to Scuba"
|
Loading…
Reference in new issue