Skip to content

Instantly share code, notes, and snippets.

@kuniyoshi
Created April 20, 2014 16:11
Show Gist options
  • Save kuniyoshi/11117845 to your computer and use it in GitHub Desktop.
Save kuniyoshi/11117845 to your computer and use it in GitHub Desktop.
Measure HTTP Response Time, and store it.
-module(metrics_http).
-export([start_loop/1, stop/0]).
-export([loop/1]).
-export([measure_tat/1]).
-export([add/1, update/2]).
-export([loop_query/1, start_querier/1, start_querier/0]).
-include_lib("eunit/include/eunit.hrl").
-define(CONNECTION_TIMEOUT, 10 * 1000).
-define(TIMEOUT, 10 * 1000).
-define(USER_AGENT, "MetricsHttp/0.1").
-define(INTERVAL, 10 * 1000).
measure_tat(Options) ->
Url = proplists:get_value(url, Options),
Series = proplists:get_value(series, Options),
DbUrl = proplists:get_value(db_url, Options),
Start = now(),
HttpHeaders = [{"User-Agent", ?USER_AGENT}],
{ok, {{_HttpVersion, 200, _StatusMessage},
_Headers,
_Body}} = httpc:request(get,
{Url, HttpHeaders},
[{timeout, ?TIMEOUT},
{connect_timeout, ?CONNECTION_TIMEOUT}],
[]),
Tat = timer:now_diff(now(), Start),
Time = lists:sum(lists:zipwith(fun(A, B) -> A * B end,
tuple_to_list(Start),
[1000 * 1000 * 1000, 1000, 1 / 1000])),
Json = jiffy:encode([{[{name, atom_to_binary(Series, utf8)},
{columns, [<<"time">>, <<"tat">>]},
{points, [[round(Time), Tat / 1000 / 1000]]}]}]),
Request = {DbUrl, HttpHeaders, "application/json", Json},
{ok, {_StatusLine2, _Headers2, _Body2}} = httpc:request(post, Request, [], []),
ok.
measure_all(Options) ->
Urls = proplists:get_value(urls, Options),
DbUrl = proplists:get_value(db_url, Options),
[spawn(?MODULE, measure_tat, [[{url, Url}, {series, Series}, {db_url, DbUrl}]])
|| {Url, Series} <- Urls].
loop(Options) ->
receive
{update, Options2} ->
loop(Options2);
measure ->
measure_all(Options),
loop(Options);
{Pid, get} ->
Pid ! {self(), Options},
loop(Options);
stop ->
ok
end.
start_loop(Options) ->
register(?MODULE, spawn_link(?MODULE, loop, [Options])).
stop() ->
?MODULE ! stop.
add(Options) ->
?MODULE ! {self(), get},
Pid = whereis(?MODULE),
receive
{Pid, LoopOptions} ->
Urls = proplists:get_value(urls, LoopOptions, []),
Urls2 = [Options | Urls],
LoopOptions2 = lists:keystore(urls, 1, LoopOptions, {urls, Urls2}),
?MODULE ! {update, LoopOptions2}
end.
update(Key, Value) ->
?MODULE ! {self(), get},
Pid = whereis(?MODULE),
receive
{Pid, LoopOptions} ->
LoopOptions2 = lists:keystore(Key, 1, LoopOptions, {Key, Value}),
?MODULE ! {update, LoopOptions2}
end.
loop_query(Interval) ->
?MODULE ! measure,
timer:sleep(Interval),
loop_query(Interval).
start_querier(Interval) ->
spawn_link(?MODULE, loop_query, [Interval]).
start_querier() ->
start_querier(?INTERVAL).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment