Skip to content

Commit

Permalink
Avoid compiling Peep.Plug when Plug module is not present.
Browse files Browse the repository at this point in the history
  • Loading branch information
scudelletti committed Jan 3, 2025
1 parent 3589c9b commit a38d6de
Showing 1 changed file with 101 additions and 99 deletions.
200 changes: 101 additions & 99 deletions lib/plug.ex
Original file line number Diff line number Diff line change
@@ -1,109 +1,111 @@
defmodule Peep.Plug do
@moduledoc """
Use this plug to expose your metrics on an endpoint for scraping. This is useful if you are using Prometheus.
if Code.ensure_loaded?(Plug) do
defmodule Peep.Plug do
@moduledoc """
Use this plug to expose your metrics on an endpoint for scraping. This is useful if you are using Prometheus.
This plug accepts the following options:
* `:peep_worker` - The name of the Peep worker to use. This is required.
* `:path` - The path to expose the metrics on. Defaults to `"/metrics"`.
* `:on_unmatched_path` - The intended behavior of this plug when handling a
request to a different path. There are two possible values:
- `:continue` (default) - This allows for subsequent Plugs in a router to
be executed. This option is useful when Peep.Plug is part of a router
for a Phoenix application, or a router that matches other paths after
Peep.Plug.
- `:halt` - Responds to requests with 404. This option is useful when
Peep.Plug is used for serving metrics on a separate port, which is a
practice that is encouraged by other libraries that export Prometheus
metrics.
## Usage
You can use this plug in your Phoenix endpoint like this:
```elixir
plug Peep.Plug, peep_worker: :my_peep_worker
```
Or if you'd rather use a different path:
```elixir
plug Peep.Plug, path: "/my-metrics"
```
If you are not using Phoenix, you can use it directly with Cowboy by adding this to your applications's supervision tree:
```elixir
{Plug.Cowboy, scheme: :http, plug: Peep.Plug, options: [port: 9000]}
```
Similarly, if you are using Bandit, you can use it like so:
```elixir
{Bandit, [
scheme: :http,
plug: {Peep.Plug, peep_worker: :my_app},
port: 9000
]}
```
"""

@behaviour Plug

import Plug.Conn
alias Plug.Conn
require Logger

@default_metrics_path "/metrics"

@impl Plug
def init(opts) do
%{
metrics_path: Keyword.get(opts, :path, @default_metrics_path),
peep_worker: Keyword.fetch!(opts, :peep_worker),
on_unmatched_path: Keyword.get(opts, :on_unmatched_path, :continue)
}
end

@impl Plug
def call(%Conn{request_path: metrics_path, method: "GET"} = conn, %{
metrics_path: metrics_path,
peep_worker: peep_worker
}) do
metrics =
Peep.get_all_metrics(peep_worker)
|> Peep.Prometheus.export()

This plug accepts the following options:
* `:peep_worker` - The name of the Peep worker to use. This is required.
* `:path` - The path to expose the metrics on. Defaults to `"/metrics"`.
* `:on_unmatched_path` - The intended behavior of this plug when handling a
request to a different path. There are two possible values:
- `:continue` (default) - This allows for subsequent Plugs in a router to
be executed. This option is useful when Peep.Plug is part of a router
for a Phoenix application, or a router that matches other paths after
Peep.Plug.
- `:halt` - Responds to requests with 404. This option is useful when
Peep.Plug is used for serving metrics on a separate port, which is a
practice that is encouraged by other libraries that export Prometheus
metrics.
## Usage
You can use this plug in your Phoenix endpoint like this:
```elixir
plug Peep.Plug, peep_worker: :my_peep_worker
```
Or if you'd rather use a different path:
```elixir
plug Peep.Plug, path: "/my-metrics"
```
If you are not using Phoenix, you can use it directly with Cowboy by adding this to your applications's supervision tree:
```elixir
{Plug.Cowboy, scheme: :http, plug: Peep.Plug, options: [port: 9000]}
```
Similarly, if you are using Bandit, you can use it like so:
```elixir
{Bandit, [
scheme: :http,
plug: {Peep.Plug, peep_worker: :my_app},
port: 9000
]}
```
"""

@behaviour Plug

import Plug.Conn
alias Plug.Conn
require Logger

@default_metrics_path "/metrics"

@impl Plug
def init(opts) do
%{
metrics_path: Keyword.get(opts, :path, @default_metrics_path),
peep_worker: Keyword.fetch!(opts, :peep_worker),
on_unmatched_path: Keyword.get(opts, :on_unmatched_path, :continue)
}
end
conn
|> put_resp_content_type("text/plain")
|> send_resp(200, metrics)
|> halt()
rescue
error ->
Logger.error(Exception.format(:error, error, __STACKTRACE__))

@impl Plug
def call(%Conn{request_path: metrics_path, method: "GET"} = conn, %{
metrics_path: metrics_path,
peep_worker: peep_worker
}) do
metrics =
Peep.get_all_metrics(peep_worker)
|> Peep.Prometheus.export()

conn
|> put_resp_content_type("text/plain")
|> send_resp(200, metrics)
|> halt()
rescue
error ->
Logger.error(Exception.format(:error, error, __STACKTRACE__))
conn
|> put_resp_content_type("text/plain")
|> send_resp(503, "Service Unavailable")
|> halt()
end

def call(%Conn{request_path: metrics_path} = conn, %{metrics_path: metrics_path}) do
conn
|> put_resp_content_type("text/plain")
|> send_resp(503, "Service Unavailable")
|> send_resp(400, "Invalid Request")
|> halt()
end
end

def call(%Conn{request_path: metrics_path} = conn, %{metrics_path: metrics_path}) do
conn
|> put_resp_content_type("text/plain")
|> send_resp(400, "Invalid Request")
|> halt()
end

def call(%Conn{} = conn, %{on_unmatched_path: :continue}) do
conn
end
def call(%Conn{} = conn, %{on_unmatched_path: :continue}) do
conn
end

def call(%Conn{} = conn, %{on_unmatched_path: :halt}) do
conn
|> put_resp_content_type("text/plain")
|> send_resp(404, "Not Found")
|> halt()
def call(%Conn{} = conn, %{on_unmatched_path: :halt}) do
conn
|> put_resp_content_type("text/plain")
|> send_resp(404, "Not Found")
|> halt()
end
end
end

0 comments on commit a38d6de

Please sign in to comment.