log_entry.ex (2472B)
1 defmodule DBConnection.LogEntry do 2 @moduledoc """ 3 Struct containing log entry information. 4 """ 5 6 defstruct [ 7 :call, 8 :query, 9 :params, 10 :result, 11 :pool_time, 12 :connection_time, 13 :decode_time, 14 :idle_time 15 ] 16 17 @typedoc """ 18 Log entry information. 19 20 * `:call` - The `DBConnection` function called 21 * `:query` - The query used by the function 22 * `:params` - The params passed to the function (if any) 23 * `:result` - The result of the call 24 * `:pool_time` - The length of time awaiting a connection from the pool (if 25 the connection was not already checked out) 26 * `:connection_time` - The length of time using the connection (if a 27 connection was used) 28 * `:decode_time` - The length of time decoding the result (if decoded the 29 result using `DBConnection.Query.decode/3`) 30 * `:idle_time` - The amount of time the connection was idle before use 31 32 All times are in the native time units of the VM, see 33 `System.monotonic_time/0`. 34 """ 35 @type t :: %__MODULE__{ 36 call: atom, 37 query: any, 38 params: any, 39 result: {:ok, any} | {:ok, any, any} | {:error, Exception.t()}, 40 pool_time: non_neg_integer | nil, 41 connection_time: non_neg_integer | nil, 42 idle_time: non_neg_integer | nil, 43 decode_time: non_neg_integer | nil 44 } 45 46 @doc false 47 def new(call, query, params, times, result) do 48 entry = %__MODULE__{call: call, query: query, params: params, result: result} 49 parse_times(times, entry) 50 end 51 52 ## Helpers 53 54 defp parse_times([], entry), do: entry 55 56 defp parse_times(times, entry) do 57 stop = :erlang.monotonic_time() 58 {_, entry} = Enum.reduce(times, {stop, entry}, &parse_time/2) 59 entry 60 end 61 62 defp parse_time({:decode, start}, {stop, entry}) do 63 {start, %{entry | decode_time: stop - start}} 64 end 65 66 defp parse_time({:checkout, start}, {stop, entry}) do 67 {start, %{entry | pool_time: stop - start}} 68 end 69 70 defp parse_time({:checkin, start}, {stop, entry}) do 71 # The checkin time was most likely before checkout but it is 72 # not guaranteed as they are tracked by different processes. 73 # There should be no further measurements after checkin. 74 {stop, %{entry | idle_time: max(stop - start, 0)}} 75 end 76 77 defp parse_time({_, start}, {stop, entry}) do 78 %{connection_time: connection_time} = entry 79 {start, %{entry | connection_time: (connection_time || 0) + (stop - start)}} 80 end 81 end