commit
6e27ad92de
@ -0,0 +1,49 @@ |
||||
defmodule BlockScoutWeb.API.V1.HealthController do |
||||
use BlockScoutWeb, :controller |
||||
|
||||
alias Explorer.Chain |
||||
|
||||
def health(conn, _) do |
||||
with {:ok, number, timestamp} <- Chain.last_block_status() do |
||||
send_resp(conn, :ok, result(number, timestamp)) |
||||
else |
||||
status -> send_resp(conn, :internal_server_error, error(status)) |
||||
end |
||||
end |
||||
|
||||
def result(number, timestamp) do |
||||
%{ |
||||
"healthy" => true, |
||||
"data" => %{ |
||||
"latest_block_number" => to_string(number), |
||||
"latest_block_inserted_at" => to_string(timestamp) |
||||
} |
||||
} |
||||
|> Jason.encode!() |
||||
end |
||||
|
||||
def error({:error, :no_blocks}) do |
||||
%{ |
||||
"healthy" => false, |
||||
"error_code" => 5002, |
||||
"error_title" => "no blocks in db", |
||||
"error_description" => "There are no blocks in the DB" |
||||
} |
||||
|> Jason.encode!() |
||||
end |
||||
|
||||
def error({:error, number, timestamp}) do |
||||
%{ |
||||
"healthy" => false, |
||||
"error_code" => 5001, |
||||
"error_title" => "blocks fetching is stuck", |
||||
"error_description" => |
||||
"There are no new blocks in the DB for the last 5 mins. Check the healthiness of Ethereum archive node or the Blockscout DB instance", |
||||
"data" => %{ |
||||
"latest_block_number" => to_string(number), |
||||
"latest_block_inserted_at" => to_string(timestamp) |
||||
} |
||||
} |
||||
|> Jason.encode!() |
||||
end |
||||
end |
@ -0,0 +1,50 @@ |
||||
defmodule BlockScoutWeb.API.V1.HealthControllerTest do |
||||
use BlockScoutWeb.ConnCase |
||||
|
||||
describe "GET last_block_status/0" do |
||||
test "returns error when there are no blocks in db", %{conn: conn} do |
||||
request = get(conn, api_v1_health_path(conn, :health)) |
||||
|
||||
assert request.status == 500 |
||||
|
||||
assert request.resp_body == |
||||
"{\"error_code\":5002,\"error_description\":\"There are no blocks in the DB\",\"error_title\":\"no blocks in db\",\"healthy\":false}" |
||||
end |
||||
|
||||
test "returns error when last block is stale", %{conn: conn} do |
||||
insert(:block, consensus: true, timestamp: Timex.shift(DateTime.utc_now(), hours: -50)) |
||||
|
||||
request = get(conn, api_v1_health_path(conn, :health)) |
||||
|
||||
assert request.status == 500 |
||||
|
||||
assert %{ |
||||
"healthy" => false, |
||||
"error_code" => 5001, |
||||
"error_title" => "blocks fetching is stuck", |
||||
"error_description" => |
||||
"There are no new blocks in the DB for the last 5 mins. Check the healthiness of Ethereum archive node or the Blockscout DB instance", |
||||
"data" => %{ |
||||
"latest_block_number" => _, |
||||
"latest_block_inserted_at" => _ |
||||
} |
||||
} = Poison.decode!(request.resp_body) |
||||
end |
||||
|
||||
test "returns ok when last block is not stale", %{conn: conn} do |
||||
insert(:block, consensus: true, timestamp: DateTime.utc_now()) |
||||
|
||||
request = get(conn, api_v1_health_path(conn, :health)) |
||||
|
||||
assert request.status == 200 |
||||
|
||||
assert %{ |
||||
"healthy" => true, |
||||
"data" => %{ |
||||
"latest_block_number" => _, |
||||
"latest_block_inserted_at" => _ |
||||
} |
||||
} = Poison.decode!(request.resp_body) |
||||
end |
||||
end |
||||
end |
Loading…
Reference in new issue