From bf8673d8ed5629c393ae9c9b7f7f4c54689008bb Mon Sep 17 00:00:00 2001 From: Sergey Yelin Date: Fri, 23 Oct 2020 22:13:20 +0300 Subject: [PATCH] Add prometeus (#34) * Add prometeus * Add error mapping * Fix format --- Makefile | 5 ++-- apps/shortener/src/shortener.app.src | 4 ++- apps/shortener/src/shortener.erl | 12 ++++++-- apps/shortener/src/shortener_handler.erl | 22 ++++++++++++++ config/sys.config | 4 +++ rebar.config | 3 ++ rebar.lock | 38 ++++++++++++++++++++++-- 7 files changed, 79 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 958ac8e..f2a3783 100644 --- a/Makefile +++ b/Makefile @@ -14,10 +14,11 @@ SERVICE_IMAGE_PUSH_TAG ?= $(SERVICE_IMAGE_TAG) # Base image for the service BASE_IMAGE_NAME := service-erlang -BASE_IMAGE_TAG := da0ab769f01b650b389d18fc85e7418e727cbe96 +BASE_IMAGE_TAG := b7873e38b777322bbb1ce5d73507c26e6280c144 # Build image tag to be used -BUILD_IMAGE_TAG := 442c2c274c1d8e484e5213089906a4271641d95e +BUILD_IMAGE_NAME := build-erlang +BUILD_IMAGE_TAG := 491bc06c745a07c6fe9e8b5dbbe958e8e0b82c4c CALL_ANYWHERE := all submodules rebar-update compile xref lint dialyze start \ devrel release clean distclean check_format format diff --git a/apps/shortener/src/shortener.app.src b/apps/shortener/src/shortener.app.src index 38ea328..c14ed44 100644 --- a/apps/shortener/src/shortener.app.src +++ b/apps/shortener/src/shortener.app.src @@ -16,7 +16,9 @@ mg_proto, woody, woody_user_identity, - erl_health + erl_health, + prometheus, + prometheus_cowboy ]}, {env, []}, {modules, []}, diff --git a/apps/shortener/src/shortener.erl b/apps/shortener/src/shortener.erl index 4450e2c..9a31b95 100644 --- a/apps/shortener/src/shortener.erl +++ b/apps/shortener/src/shortener.erl @@ -35,16 +35,22 @@ start_link() -> -spec init([]) -> {ok, {supervisor:sup_flags(), [supervisor:child_spec()]}}. init([]) -> HealthRoutes = get_health_routes(genlib_app:env(?MODULE, health_check, #{})), + PrometeusRout = get_prometheus_route(), + AdditionalRoutes = [PrometeusRout | HealthRoutes], {ok, { {one_for_all, 0, 1}, % TODO - get_processor_childspecs(genlib_app:env(?MODULE, processor), HealthRoutes) ++ + get_processor_childspecs(genlib_app:env(?MODULE, processor), AdditionalRoutes) ++ get_api_childspecs(genlib_app:env(?MODULE, api), HealthRoutes) }}. get_health_routes(Check) -> [erl_health_handle:get_route(enable_health_logging(Check))]. +-spec get_prometheus_route() -> {iodata(), module(), _Opts :: any()}. +get_prometheus_route() -> + {"/metrics/[:registry]", prometheus_cowboy2_handler, []}. + enable_health_logging(Check = #{}) -> maps:map( fun(_, V = {_, _, _}) -> @@ -53,7 +59,7 @@ enable_health_logging(Check = #{}) -> Check ). -get_processor_childspecs(Opts, HealthRoutes) -> +get_processor_childspecs(Opts, AdditionalRoutes) -> {ok, IP} = inet:parse_address(maps:get(ip, Opts, "::")), [ woody_server:child_spec( @@ -70,7 +76,7 @@ get_processor_childspecs(Opts, HealthRoutes) -> shortener_slug }} ], - additional_routes => HealthRoutes + additional_routes => AdditionalRoutes } ) ]. diff --git a/apps/shortener/src/shortener_handler.erl b/apps/shortener/src/shortener_handler.erl index f7c94d8..b6dec89 100644 --- a/apps/shortener/src/shortener_handler.erl +++ b/apps/shortener/src/shortener_handler.erl @@ -6,6 +6,7 @@ -export([authorize_api_key/3]). -export([handle_request/4]). +-export([map_error/2]). %% Cowboy http handler @@ -23,6 +24,9 @@ -type request_ctx() :: swag_server:request_context(). -type request_data() :: #{atom() | binary() => term()}. -type subject_id() :: woody_user_identity:id(). +-type validation_error() :: swag_server_validation:error(). +-type error_type() :: validation_error. +-type error_message() :: swag_server:error_reason(). -spec authorize_api_key(operation_id(), swag_server:api_key(), swag_server:handler_opts(_)) -> Result :: false | {true, shortener_auth:context()}. @@ -50,6 +54,24 @@ handle_request(OperationID, Req, Context, _Opts) -> ok = scoper:remove_scope() end. +-spec map_error(error_type(), validation_error()) -> error_message(). +map_error(validation_error, Error) -> + Type = genlib:to_binary(maps:get(type, Error)), + Name = genlib:to_binary(maps:get(param_name, Error)), + Message = + case maps:get(description, Error, undefined) of + undefined -> + <<"Request parameter: ", Name/binary, ", error type: ", Type/binary>>; + Description -> + DescriptionBin = genlib:to_binary(Description), + <<"Request parameter: ", Name/binary, ", error type: ", Type/binary, ", description: ", + DescriptionBin/binary>> + end, + jsx:encode(#{ + <<"code">> => <<"invalidRequest">>, + <<"message">> => Message + }). + -spec prefetch_slug(request_data(), woody_context:ctx()) -> shortener_slug:slug() | no_slug. prefetch_slug(#{'shortenedUrlID' := ID}, WoodyCtx) -> case shortener_slug:get(ID, WoodyCtx) of diff --git a/config/sys.config b/config/sys.config index 925c7d7..101f3c7 100644 --- a/config/sys.config +++ b/config/sys.config @@ -79,6 +79,10 @@ formatter => {logger_logstash_formatter, #{}} }} ]} + ]}, + + {prometheus, [ + {collectors, [default]} ]} ]. diff --git a/rebar.config b/rebar.config index 501368d..86b12f7 100644 --- a/rebar.config +++ b/rebar.config @@ -30,6 +30,8 @@ {deps, [ {cowboy, "2.7.0"}, {jose, "1.7.9"}, + {prometheus, "4.6.0"}, + {prometheus_cowboy, "0.1.8"}, {genlib, {git, "https://github.com/rbkmoney/genlib.git", {branch, "master"} @@ -102,6 +104,7 @@ {vm_args, "./config/vm.args"}, {dev_mode, true}, {include_erts, false}, + {include_src, false}, {extended_start_script, true} ]}. diff --git a/rebar.lock b/rebar.lock index 3963f8a..398fd39 100644 --- a/rebar.lock +++ b/rebar.lock @@ -1,5 +1,6 @@ -{"1.1.0", -[{<<"base64url">>,{pkg,<<"base64url">>,<<"0.0.1">>},1}, +{"1.2.0", +[{<<"accept">>,{pkg,<<"accept">>,<<"0.3.5">>},2}, + {<<"base64url">>,{pkg,<<"base64url">>,<<"0.0.1">>},1}, {<<"bear">>,{pkg,<<"bear">>,<<"0.8.7">>},3}, {<<"cache">>,{pkg,<<"cache">>,<<"2.2.0">>},1}, {<<"certifi">>,{pkg,<<"certifi">>,<<"2.3.1">>},1}, @@ -66,6 +67,9 @@ {git,"https://github.com/rbkmoney/parse_trans.git", {ref,"5ee45f5bfa6c04329bea3281977b774f04c89f11"}}, 0}, + {<<"prometheus">>,{pkg,<<"prometheus">>,<<"4.6.0">>},0}, + {<<"prometheus_cowboy">>,{pkg,<<"prometheus_cowboy">>,<<"0.1.8">>},0}, + {<<"prometheus_httpd">>,{pkg,<<"prometheus_httpd">>,<<"2.1.11">>},1}, {<<"ranch">>,{pkg,<<"ranch">>,<<"1.7.1">>},1}, {<<"rfc3339">>,{pkg,<<"rfc3339">>,<<"0.2.2">>},0}, {<<"scoper">>, @@ -92,6 +96,7 @@ 0}]}. [ {pkg_hash,[ + {<<"accept">>, <<"B33B127ABCA7CC948BBE6CAA4C263369ABF1347CFA9D8E699C6D214660F10CD1">>}, {<<"base64url">>, <<"36A90125F5948E3AFD7BE97662A1504B934DD5DAC78451CA6E9ABF85A10286BE">>}, {<<"bear">>, <<"16264309AE5D005D03718A5C82641FCC259C9E8F09ADEB6FD79CA4271168656F">>}, {<<"cache">>, <<"3C11DBF4CD8FCD5787C95A5FB2A04038E3729CFCA0386016EEA8C953AB48A5AB">>}, @@ -107,8 +112,35 @@ {<<"lager">>, <<"CED6E98070FB4E58EE93174D006D46479C79844DF7FC17FA4FEFC1049A320D88">>}, {<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>}, {<<"mimerl">>, <<"993F9B0E084083405ED8252B99460C4F0563E41729AB42D9074FD5E52439BE88">>}, + {<<"prometheus">>, <<"20510F381DB1CCAB818B4CF2FAC5FA6AB5CC91BC364A154399901C001465F46F">>}, + {<<"prometheus_cowboy">>, <<"CFCE0BC7B668C5096639084FCD873826E6220EA714BF60A716F5BD080EF2A99C">>}, + {<<"prometheus_httpd">>, <<"F616ED9B85B536B195D94104063025A91F904A4CFC20255363F49A197D96C896">>}, {<<"ranch">>, <<"6B1FAB51B49196860B733A49C07604465A47BDB78AA10C1C16A3D199F7F8C881">>}, {<<"rfc3339">>, <<"1552DF616ACA368D982E9F085A0E933B6688A3F4938A671798978EC2C0C58730">>}, {<<"ssl_verify_fun">>, <<"28A4D65B7F59893BC2C7DE786DEC1E1555BD742D336043FE644AE956C3497FBE">>}, - {<<"unicode_util_compat">>, <<"A1F612A7B512638634A603C8F401892AFBF99B8CE93A45041F8AACA99CADB85E">>}]} + {<<"unicode_util_compat">>, <<"A1F612A7B512638634A603C8F401892AFBF99B8CE93A45041F8AACA99CADB85E">>}]}, +{pkg_hash_ext,[ + {<<"accept">>, <<"11B18C220BCC2EAB63B5470C038EF10EB6783BCB1FCDB11AA4137DEFA5AC1BB8">>}, + {<<"base64url">>, <<"FAB09B20E3F5DB886725544CBCF875B8E73EC93363954EB8A1A9ED834AA8C1F9">>}, + {<<"bear">>, <<"534217DCE6A719D59E54FB0EB7A367900DBFC5F85757E8C1F94269DF383F6D9B">>}, + {<<"cache">>, <<"3E7D6706DE5DF76C4D71C895B4BE62B01C3DE6EDB63197035E465C3BCE63F19B">>}, + {<<"certifi">>, <<"E12D667D042C11D130594BAE2B0097E63836FE8B1E6D6B2CC48F8BB7A2CF7D68">>}, + {<<"cowboy">>, <<"04FD8C6A39EDC6AAA9C26123009200FC61F92A3A94F3178C527B70B767C6E605">>}, + {<<"cowlib">>, <<"79F954A7021B302186A950A32869DBC185523D99D3E44CE430CD1F3289F41ED4">>}, + {<<"goldrush">>, <<"99CB4128CFFCB3227581E5D4D803D5413FA643F4EB96523F77D9E6937D994CEB">>}, + {<<"gproc">>, <<"580ADAFA56463B75263EF5A5DF4C86AF321F68694E7786CB057FD805D1E2A7DE">>}, + {<<"hackney">>, <<"4D605D33DD07EE1B82B105033CCCB02379515105FCEB1850746591814B00C205">>}, + {<<"idna">>, <<"8FDDB3AEC4692C71647D67DE72536254BCE9069851754E370A99F2AAE69FBDF4">>}, + {<<"jose">>, <<"0EFAAC15223E7CD29773296214AB3B85700D2CD1354C931342750AA1AFAF6146">>}, + {<<"jsx">>, <<"B4C5D3230B397C8D95579E4A3D72826BB6463160130CCF4182F5BE8579B5F44C">>}, + {<<"lager">>, <<"6CBEF7E038D772A6BF834BA7AAF55A1484A97ADFE8075B4A23B0086A8FE697A8">>}, + {<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>}, + {<<"mimerl">>, <<"7A4C8E1115A2732A67D7624E28CF6C9F30C66711A9E92928E745C255887BA465">>}, + {<<"prometheus">>, <<"4905FD2992F8038ECCD7AA0CD22F40637ED618C0BED1F75C05AACEC15B7545DE">>}, + {<<"prometheus_cowboy">>, <<"BA286BECA9302618418892D37BCD5DC669A6CC001F4EB6D6AF85FF81F3F4F34C">>}, + {<<"prometheus_httpd">>, <<"0BBE831452CFDF9588538EB2F570B26F30C348ADAE5E95A7D87F35A5910BCF92">>}, + {<<"ranch">>, <<"451D8527787DF716D99DC36162FCA05934915DB0B6141BBDAC2EA8D3C7AFC7D7">>}, + {<<"rfc3339">>, <<"986D7F9BAC6891AA4D5051690058DE4E623245620BBEADA7F239F85C4DF8F23C">>}, + {<<"ssl_verify_fun">>, <<"4F8805EB5C8A939CF2359367CB651A3180B27DFB48444846BE2613D79355D65E">>}, + {<<"unicode_util_compat">>, <<"DA1D9BEF8A092CC7E1E51F1298037A5DDFB0F657FE862DFE7BA4C5807B551C29">>}]} ].