Packages

Fault-tolerant dataflow DSL

Current section

Files

Jump to
kflow src framework kflow_http_healthcheck_handler.erl
Raw

src/framework/kflow_http_healthcheck_handler.erl

%%%
%%% Copyright (c) 2018-2020 Klarna Bank AB (publ)
%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
%%% You may obtain a copy of the License at
%%%
%%% http://www.apache.org/licenses/LICENSE-2.0
%%%
%%% Unless required by applicable law or agreed to in writing, software
%%% distributed under the License is distributed on an "AS IS" BASIS,
%%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%%% See the License for the specific language governing permissions and
%%% limitations under the License.
%%%
-module(kflow_http_healthcheck_handler).
-export([ init/2
, init/3
, handle_request/2
, content_types_provided/2
]).
init(Req, Opts) ->
{cowboy_rest, Req, Opts}.
init(_Transport, _Req, []) ->
{upgrade, protocol, cowboy_rest}.
content_types_provided(Req, State) ->
{[{<<"application/json">>, handle_request}], Req, State}.
handle_request(Req, State) ->
Response = check_processes(),
{jsone:encode(Response), Req, State}.
check_processes() ->
Procs = supervisor:which_children(kflow_pipe_sup) ++
supervisor3:which_children(kflow_sup2),
lists:foldl( fun({Id, Child, _, _}, Acc) ->
Name = iolist_to_binary(io_lib:format("~p", [Id])),
{Healthy, Message} = healthy_child(Child),
HealthCheck0 = #{ <<"actionable">> => true
, <<"name">> => Name
, <<"type">> => <<"SELF">>
, <<"healthy">> => Healthy
, <<"message">> => Message
},
{Key, HealthCheck} =
case Healthy of
true ->
{<<"healthy">>, HealthCheck0};
false ->
{<<"unhealthy">>, HealthCheck0#{<<"severity">> => <<"CRITICAL">>}}
end,
maps:update_with( Key
, fun(Old) ->
[HealthCheck|Old]
end
, Acc
)
end
, #{<<"healthy">> => [], <<"unhealthy">> => []}
, Procs
).
%% Brain-dead test checking that child isn't in cyclic restart
healthy_child(Child) ->
if is_pid(Child) ->
case erlang:process_info(Child, reductions) of
{reductions, Reds} when Reds > 1000 ->
{true, <<"">>};
{reductions, _} ->
{false, <<"Server is in cyclic restart">>};
_ ->
{false, <<"Server is dead">>}
end;
true ->
{false, <<"Server is dead">>}
end.
%%%_* Emacs ====================================================================
%%% Local Variables:
%%% allout-layout: t
%%% erlang-indent-level: 2
%%% End: