-
-
Notifications
You must be signed in to change notification settings - Fork 104
/
plug.ex
86 lines (72 loc) · 2.6 KB
/
plug.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
if Code.ensure_loaded?(Plug) do
defmodule PromEx.MetricsServer.Plug do
@moduledoc """
This plug is used to serve metrics when PromEx is run in a
standalone server configuration. This plug supports the
following options:
* `:path` - The route that should expose the metrics (default is "/metrics")
* `:prom_ex_module` - The PromEx module that this plug will expose
In order to use this standalone metrics server plug you need to have `:plug` and `:plug_cowboy`
as dependencies in your project.
"""
@behaviour Plug
require Logger
import Plug.Conn
alias Plug.Conn
@impl true
def init(opts) do
Map.pop(opts, :auth_strategy, :none)
end
@impl true
def call(%Conn{request_path: path} = conn, {:none, %{path: path, prom_ex_module: prom_ex_module}}) do
case PromEx.get_metrics(prom_ex_module) do
:prom_ex_down ->
Logger.warning("Attempted to fetch metrics from #{prom_ex_module}, but the module has not been initialized")
conn
|> put_resp_content_type("text/plain")
|> send_resp(503, "Service Unavailable")
metrics ->
PromEx.ETSCronFlusher.defer_ets_flush(prom_ex_module.__ets_cron_flusher_name__())
conn
|> put_resp_content_type("text/plain")
|> send_resp(200, metrics)
end
end
def call(
%Conn{request_path: path} = conn,
{:bearer, %{auth_token: auth_token, path: path} = plug_opts}
) do
with ["Bearer " <> req_auth_token] <- get_req_header(conn, "authorization"),
true <- req_auth_token == auth_token do
call(conn, {:none, plug_opts})
else
_ ->
conn
|> put_resp_content_type("text/plain")
|> send_resp(401, "Unauthorized")
end
end
def call(
%Conn{request_path: path} = conn,
{:basic, %{auth_user: auth_user, auth_password: auth_password, path: path} = plug_opts}
) do
with ["Basic " <> req_auth_user_pass] <- get_req_header(conn, "authorization"),
{:ok, user_and_pass} <- Base.decode64(req_auth_user_pass),
[req_user, req_pass] <- String.split(user_and_pass, ":", parts: 2),
true <- req_user == auth_user,
true <- req_pass == auth_password do
call(conn, {:none, plug_opts})
else
_ ->
conn
|> put_resp_content_type("text/plain")
|> send_resp(401, "Unauthorized")
end
end
def call(conn, _opts) do
conn
|> put_resp_content_type("text/plain")
|> send_resp(404, "Not Found")
end
end
end