README.md

# TimeLogPlug

**Plug to log Phoenix requests and responses with a more accurate time than the custom Phoenix logger**

## This Plug(s) is/are not yet tested and will change

## Installation

If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `time_log` to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [
    {:time_log, "~> 0.1.0"}
  ]
end
```

## Usage

To use the TimeLogPlug correctly you have to adjust your `endpoint.ex`. In Phoenix projects >= 1.3 it should be located under `lib/<project_name>_web/endpoint.ex`:

```elixir
defmodule MyProjectWeb.Endpoint do
  use Phoenix.Endpoint, otp_app: :my_project

  socket "/socket", MyProjectWeb.UserSocket
  plug TimeLog.TimePlug

  # Serve at "/" the static files from "priv/static" directory.
  #
  # You should set gzip to true if you are running phoenix.digest
  # when deploying your static files in production.
  #  plug Plug.Static,
  #    at: "/", from: :my_project, gzip: true,
  #    only: ~w(css fonts images js favicon.ico robots.txt)

  # Code reloading can be explicitly enabled under the
  # :code_reloader configuration of your endpoint.
  if code_reloading? do
    plug Phoenix.CodeReloader
  end

  plug Plug.RequestId,
    http_header: "correlation_id"
  plug Plug.Logger

  plug Plug.Parsers,
    parsers: [:urlencoded, :multipart, :json],
    pass: ["*/*"],
    json_decoder: Poison

  plug Plug.MethodOverride
  plug Plug.Head

  # The session will be stored in the cookie and signed,
  # this means its contents can be read but not tampered with.
  # Set :encryption_salt if you would also like to encrypt it.
  plug Plug.Session,
    store: :cookie,
    key: "duefnkaslndfuefnmsdnfuwefn342n",
    signing_salt: "LIwo9Kg1"

  plug CORSPlug
  plug MyProject.PrometheusExporter     # makes the /metrics URL happen
  plug MyProject.PipelineInstrumenter   # measures pipeline exec times

  plug TimeLog.PreLogPlug
  plug MyProjectWeb.Router

  @doc """
  Callback invoked for dynamically configuring the endpoint.

  It receives the endpoint configuration and checks if
  configuration should be loaded from the system environment.
  """
  def init(_key, config) do
    IO.puts "Starting Endpoint...\nWith config #{inspect(config)}"
    if config[:load_from_system_env] do
      IO.puts "Loading from system Env ..."
      port = System.get_env("PORT") || raise "expected the PORT environment variable to be set"
      {:ok, Keyword.put(config, :http, [:inet6, port: port])}
    else
      IO.puts "Not loading from ENV :ok"
      {:ok, config}
    end
  end
end

```

Notice that `TimeLog.TimePlug` gets called right after the socket receives the incoming request with the line `plug TimeLog.TimePlug `. In your project add it as early as possible too.This ensures that the response time measurement is as accurate as possible.
If you want detailed logging of the incoming request, including an ip check for internal ips (that are used for testing for example) include the line `plug TimeLog.PreLogPlug` right before 

Within your config you can setup what an internal ip is for your app, what name should be shown if an internal ip requested something or requests to which urls to ignore altogether.
You can append your config with:

```elixir

  config :time_log,
    internal_ips: ["62.157.212.212", "62.159.255.124", "62.157.212.217", "127.0.0.1"],
    internal_name: "Walz internal IP",
    ignore_urls: ["/health"]

```


Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
be found at [https://hexdocs.pm/time_log](https://hexdocs.pm/time_log).