Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/settings.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# These settings are synced to GitHub by https://probot.github.io/apps/settings/
_extends: .github

teams:
- name: devs
permission: push
- name: bots
permission: push
- name: maintainers
permission: push
- name: erlang
permission: maintain

branches:
- name: "master"
# https://developer.github.com/v3/repos/branches/#update-branch-protection
# Branch Protection settings. Set to null to disable
protection:
required_pull_request_reviews:
required_approving_review_count: 1
dismiss_stale_reviews: false
require_code_owner_reviews: true
dismissal_restrictions: {}
required_status_checks:
strict: true
checks:
- context: "Load .env"
app_id: 15368
- context: "Run checks / Build"
app_id: 15368
- context: "Run checks / Check"
app_id: 15368
- context: "Run checks / Dialyze"
app_id: 15368
- context: "Run checks / Test"
app_id: 15368
- context: "codecov/patch"
app_id: 254
- context: "codecov/project"
app_id: 254
enforce_admins: false
required_conversation_resolution: false
required_linear_history: true
restrictions: null
allow_force_pushes: false
allow_deletions: false
10 changes: 10 additions & 0 deletions .github/workflows/basic-linters.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: Vality basic linters

on:
pull_request:
branches:
- "*"

jobs:
lint:
uses: valitydev/base-workflows/.github/workflows/basic-linters.yml@v1
5 changes: 3 additions & 2 deletions .github/workflows/erlang-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
thrift-version: ${{ steps.thrift-version.outputs.version }}
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
- run: grep -v '^#' .env >> $GITHUB_ENV
- id: otp-version
run: echo "::set-output name=version::$OTP_VERSION"
Expand All @@ -30,9 +30,10 @@ jobs:
run:
name: Run checks
needs: setup
uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.9
uses: valitydev/erlang-workflows/.github/workflows/erlang-parallel-build.yml@v1.0.10
with:
otp-version: ${{ needs.setup.outputs.otp-version }}
rebar-version: ${{ needs.setup.outputs.rebar-version }}
use-thrift: true
thrift-version: ${{ needs.setup.outputs.thrift-version }}
upload-coverage: false
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,4 @@
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS
END OF TERMS AND CONDITIONS
107 changes: 107 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,80 @@ check_loan_limits(Limits, Context, N) ->
### Woody Event Handler
Интерфейс для получения и логирования событий RPC библиотеки. Также содержит вспомогательные функции для удобного форматирования событий. Пример реализации _event handler_'а - [woody_event_handler_default.erl](src/woody_event_handler_default.erl).

Через опции обработчика можно сообщить параметры соответствия событий RPC для уровня логирования:

``` erlang
woody_event_handler_default:handle_event(Event, RpcId, Meta, #{
formatter_opts => ...,
events_severity => #{
['call service'] => debug,
...
}
}).
```

Где эти параметры имеют значения по умолчанию в следующем виде:

``` erlang
#{
events_severity => #{
%% Пограничные события работы клиента
['client begin'] => debug,
['client end'] => debug,

%% Начало вызова сервиса, перед формированием запроса
['call service'] => info,

%% Результат вызова сервиса на клиенте
['service result'] => info,
['service result', error] => error,
%% Событие состоявшегося вызова с возвращённой ошибкой в качестве
%% результата
['service result', warning] => warning,

%% Клиентские события, включая обнаружения хоста
['client send'] => debug,
['client resolve begin'] => debug,
['client resolve result'] => debug,
['client receive'] => debug,
['client receive', error] => warning,

%% Непосредственные события обслуживания запроса сервером
['server receive'] => debug,
['server send'] => debug,
['server send', error] => warning,

%% Начало обслуживания вызова функции сервиса
['invoke service handler'] => info,

%% Завершение обслуживание вызова с разным итогом
['service handler result'] => info,
['service handler result', error, business] => info,
['service handler result', error, system] => error,
%% Обслуживание вызова завершилось поправимой ошибкой;
%% по крайней мере она не в рамках бизнес-логики но и не системное
%% исключение
['service handler result', warning] => warning,

%% События кеширующей обертки клиента
['client cache begin'] => debug,
['client cache end'] => debug,
['client cache hit'] => info,
['client cache miss'] => debug,
['client cache update'] => debug,
['client cache result'] => debug,

%% Внутренние ошибки с разным контекстом/происхождением
['internal error', system] => error,
['internal error', business] => warning,
%% Событие трассировки на уровне woody, см. далее

['trace event'] => debug
}
}.
```


### Tracing
Можно динамически включать и выключать трассировку http запросов и ответов.

Expand All @@ -176,3 +250,36 @@ check_loan_limits(Limits, Context, N) ->
application:set_env(woody, trace_http_server, true).
application:unset_env(woody, trace_http_server).
```

### Prometheus metrics

Чтобы осуществлять экспорт метрик следует добавить [соответствующий хэндлер](https://github.com/deadtrickster/prometheus-cowboy#exporting-metrics-with-handlers) для cowboy-сервера.

``` erlang
{deps, [
...
{prometheus_cowboy, "0.1.8"}
]}
```

Для сбора серверных метрик необходимо на старте приложения объявить их

``` erlang
ok = woody_ranch_prometheus_collector:setup()
```

Если дополнительно интересуют все метрики ковбоя то можно добавить [реализацию обсервера из библиотеки](https://github.com/deadtrickster/prometheus-cowboy?tab=readme-ov-file#exporting-cowboy2-metrics).

Для сбора клиентских метрик необходимо на старте приложения объявить их

``` erlang
ok = woody_hackney_prometheus_collector:setup()
```

Это будет публиковать целочисленные значения в шкале 'woody_hackney_pool_usage' с метками `pool` в качестве названия пула и `status` в качестве параметра соответствующего значения:

- `in_use_count` -- используемые соединения в пуле;
- `free_count` -- свободное количество в пуле;
- `queue_count` -- очередь за свободными соединенеиями

**TODO** Возможно стоит рассмотреть публикацию метрик по количеству исполняемых запросов в общем, с разбивкой по хосту и количества новых и переиспользуемых соедининий в каждом из пулов. [Хакни это предоставляет](https://github.com/benoitc/hackney/tree/1.18.0#metrics).
12 changes: 6 additions & 6 deletions rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@
{gproc, "0.9.0"},
{cache, "2.3.3"},
{snowflake, {git, "https://github.com/valitydev/snowflake.git", {branch, "master"}}},
{genlib, {git, "https://github.com/valitydev/genlib.git", {branch, "master"}}}
{genlib, {git, "https://github.com/valitydev/genlib.git", {branch, "master"}}},
{prometheus, "4.8.1"},
{opentelemetry_api, "1.2.1"}
]}.

%% XRef checks
Expand Down Expand Up @@ -102,17 +104,15 @@
{thrift,
{git, "https://github.com/valitydev/thrift_erlang.git",
{ref, "3f3e11246d90aefa8f58b35e4f2eab14c0c28bd2"}}},
{woody_api_hay,
{git, "https://github.com/valitydev/woody_api_hay.git",
{ref, "4c39134cddaa9bf6fb8db18e7030ae64f1efb3a9"}}},
{damsel,
{git, "https://github.com/valitydev/damsel.git", {ref, "3fa6f31db54b2ae781b27898ab4daf56bb36eb36"}}},
{mg_proto,
{git, "https://github.com/valitydev/machinegun-proto.git",
{ref, "ebae56fe2b3e79e4eb34afc8cb55c9012ae989f8"}}}
{ref, "ebae56fe2b3e79e4eb34afc8cb55c9012ae989f8"}}},
{opentelemetry, "1.3.0"}
]},
{dialyzer, [
{plt_extra_apps, [thrift, how_are_you, eunit, proper, common_test, cth_readable]}
{plt_extra_apps, [thrift, prometheus, eunit, proper, common_test, cth_readable, opentelemetry]}
]}
]}
]}.
Expand Down
14 changes: 14 additions & 0 deletions rebar.lock
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@
{<<"idna">>,{pkg,<<"idna">>,<<"6.1.1">>},1},
{<<"metrics">>,{pkg,<<"metrics">>,<<"1.0.1">>},1},
{<<"mimerl">>,{pkg,<<"mimerl">>,<<"1.2.0">>},1},
{<<"opentelemetry_api">>,{pkg,<<"opentelemetry_api">>,<<"1.2.1">>},0},
{<<"opentelemetry_semantic_conventions">>,
{pkg,<<"opentelemetry_semantic_conventions">>,<<"0.2.0">>},
1},
{<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.1">>},1},
{<<"prometheus">>,{pkg,<<"prometheus">>,<<"4.8.1">>},0},
{<<"quantile_estimator">>,{pkg,<<"quantile_estimator">>,<<"0.2.1">>},1},
{<<"ranch">>,{pkg,<<"ranch">>,<<"1.8.0">>},1},
{<<"snowflake">>,
{git,"https://github.com/valitydev/snowflake.git",
Expand All @@ -31,7 +37,11 @@
{<<"idna">>, <<"8A63070E9F7D0C62EB9D9FCB360A7DE382448200FBBD1B106CC96D3D8099DF8D">>},
{<<"metrics">>, <<"25F094DEA2CDA98213CECC3AEFF09E940299D950904393B2A29D191C346A8486">>},
{<<"mimerl">>, <<"67E2D3F571088D5CFD3E550C383094B47159F3EEE8FFA08E64106CDF5E981BE3">>},
{<<"opentelemetry_api">>, <<"7B69ED4F40025C005DE0B74FCE8C0549625D59CB4DF12D15C32FE6DC5076FF42">>},
{<<"opentelemetry_semantic_conventions">>, <<"B67FE459C2938FCAB341CB0951C44860C62347C005ACE1B50F8402576F241435">>},
{<<"parse_trans">>, <<"16328AB840CC09919BD10DAB29E431DA3AF9E9E7E7E6F0089DD5A2D2820011D8">>},
{<<"prometheus">>, <<"FA76B152555273739C14B06F09F485CF6D5D301FE4E9D31B7FF803D26025D7A0">>},
{<<"quantile_estimator">>, <<"EF50A361F11B5F26B5F16D0696E46A9E4661756492C981F7B2229EF42FF1CD15">>},
{<<"ranch">>, <<"8C7A100A139FD57F17327B6413E4167AC559FBC04CA7448E9BE9057311597A1D">>},
{<<"ssl_verify_fun">>, <<"CF344F5692C82D2CD7554F5EC8FD961548D4FD09E7D22F5B62482E5AEAEBD4B0">>},
{<<"unicode_util_compat">>, <<"BC84380C9AB48177092F43AC89E4DFA2C6D62B40B8BD132B1059ECC7232F9A78">>}]},
Expand All @@ -45,7 +55,11 @@
{<<"idna">>, <<"92376EB7894412ED19AC475E4A86F7B413C1B9FBB5BD16DCCD57934157944CEA">>},
{<<"metrics">>, <<"69B09ADDDC4F74A40716AE54D140F93BEB0FB8978D8636EADED0C31B6F099F16">>},
{<<"mimerl">>, <<"F278585650AA581986264638EBF698F8BB19DF297F66AD91B18910DFC6E19323">>},
{<<"opentelemetry_api">>, <<"6D7A27B7CAD2AD69A09CABF6670514CAFCEC717C8441BEB5C96322BAC3D05350">>},
{<<"opentelemetry_semantic_conventions">>, <<"D61FA1F5639EE8668D74B527E6806E0503EFC55A42DB7B5F39939D84C07D6895">>},
{<<"parse_trans">>, <<"07CD9577885F56362D414E8C4C4E6BDF10D43A8767ABB92D24CBE8B24C54888B">>},
{<<"prometheus">>, <<"6EDFBE928D271C7F657A6F2C46258738086584BD6CAE4A000B8B9A6009BA23A5">>},
{<<"quantile_estimator">>, <<"282A8A323CA2A845C9E6F787D166348F776C1D4A41EDE63046D72D422E3DA946">>},
{<<"ranch">>, <<"49FBCFD3682FAB1F5D109351B61257676DA1A2FDBE295904176D5E521A2DDFE5">>},
{<<"ssl_verify_fun">>, <<"BDB0D2471F453C88FF3908E7686F86F9BE327D065CC1EC16FA4540197EA04680">>},
{<<"unicode_util_compat">>, <<"25EEE6D67DF61960CF6A794239566599B09E17E668D3700247BC498638152521">>}]}
Expand Down
3 changes: 2 additions & 1 deletion src/woody.app.src
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
cowboy,
hackney,
gproc,
cache
cache,
opentelemetry_api
]},
{optional_applications, [
thrift
Expand Down
2 changes: 1 addition & 1 deletion src/woody_client_thrift_http_transport.erl
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ send(Url, Body, Options, ResOpts, WoodyState) ->
Headers = add_host_header(OldUrl, make_woody_headers(Context)),
Options1 = set_defaults(Options),
Options2 = set_timeouts(Options1, Context),
HeaderList = maps:to_list(Headers),
HeaderList = otel_propagator_text_map:inject(maps:to_list(Headers)),
Result = hackney:request(post, NewUrl, HeaderList, Body, maps:to_list(Options2)),
transform_request_results(Result);
{error, Reason} ->
Expand Down
5 changes: 3 additions & 2 deletions src/woody_client_thrift_v2.erl
Original file line number Diff line number Diff line change
Expand Up @@ -155,15 +155,16 @@ send_call(Buffer, #{url := Url} = Opts, WoodyState) ->
% reusing keep-alive connections to dead hosts
case woody_resolver:resolve_url(Url, WoodyState, ResolverOpts) of
{ok, {OldUrl, NewUrl}, ConnectOpts} ->
Headers = add_host_header(OldUrl, make_woody_headers(Context)),
Headers0 = add_host_header(OldUrl, make_woody_headers(Context)),
Headers1 = otel_propagator_text_map:inject(Headers0),
TransportOpts1 = set_defaults(TransportOpts),
TransportOpts2 = set_timeouts(TransportOpts1, Context),
% NOTE
% This is to ensure hackney won't try to resolve original hostname again in
% `set_tls_overrides/2`.
TransportOpts3 = append_connect_opts(TransportOpts2, ConnectOpts),
TransportOpts4 = set_tls_overrides(TransportOpts3, OldUrl),
Result = hackney:request(post, NewUrl, Headers, Buffer, maps:to_list(TransportOpts4)),
Result = hackney:request(post, NewUrl, Headers1, Buffer, maps:to_list(TransportOpts4)),
handle_response(Result, WoodyState);
{error, Reason} ->
Error = {error, {resolve_failed, Reason}},
Expand Down
Loading