   and how to process the existing options.
   """
 
-  @type backend :: :gen_event.handler
-  @type message :: IO.chardata | String.Chars.t
+  @type backend :: :gen_event.handler()
+  @type message :: IO.chardata() | String.Chars.t()
   @type level :: :error | :info | :warn | :debug
-  @type metadata :: keyword(String.Chars.t)
+  @type metadata :: keyword(String.Chars.t())
   @levels [:error, :info, :warn, :debug]
 
   @metadata :logger_metadata

    %{module: module, function: fun, file: file, line: line} = caller

    caller =
      compile_time_application() ++
        [module: module, function: form_fa(fun), file: file, line: line]

    quote do
      Logger.bare_log(unquote(level), unquote(data), unquote(caller) ++ unquote(metadata))

  explicitly avoid embedding metadata.
  """
  @spec bare_log(level, message | (() -> message | {message, keyword}), keyword) ::
          :ok | {:error, :noproc} | {:error, term}
  def bare_log(level, chardata_or_fun, metadata \\ []) when level in @levels and is_list(metadata) do
    case __metadata__() do
      {true, pdict} ->
        %{mode: mode, truncate: truncate, level: min_level, utc_log: utc_log?} =
          Logger.Config.__data__()

        if compare_levels(level, min_level) != :lt do
          metadata = [pid: self()] ++ Keyword.merge(pdict, metadata)
