diff --git a/Makefile b/Makefile index 86242248..5f110b5b 100644 --- a/Makefile +++ b/Makefile @@ -120,5 +120,8 @@ distclean: clean-build-image test: eunit common-test +dbg: + $(REBAR) ct -v --suite=apps/hellgate/test/hg_invoice_tests_SUITE.erl --group=all_non_destructive_tests --case=payment_big_cascade_success + cover-report: $(REBAR) cover diff --git a/apps/hellgate/src/hellgate.erl b/apps/hellgate/src/hellgate.erl index 17f7577e..b7ad3344 100644 --- a/apps/hellgate/src/hellgate.erl +++ b/apps/hellgate/src/hellgate.erl @@ -134,8 +134,10 @@ ensure_otel_log_handler() -> DelayMs = application:get_env(hellgate, otel_log_scheduled_delay_ms, 1000), TimeoutMs = application:get_env(hellgate, otel_log_exporting_timeout_ms, 300000), LogLevel = application:get_env(hellgate, otel_log_level, info), - HandlerConfig = #{ - report_cb => fun hg_otel_log_filter:format_otp_report_utf8/1, + LoggerHandlerConfig = #{ + level => LogLevel, + filter_default => log, + filters => [{hg_otel_trace_id_bytes, {fun hg_otel_log_filter:filter/2, undefined}}], exporter => {otel_exporter_logs_otlp, #{ protocol => http_protobuf, @@ -145,13 +147,7 @@ ensure_otel_log_handler() -> scheduled_delay_ms => DelayMs, exporting_timeout_ms => TimeoutMs }, - LoggerHandlerConfig = #{ - level => LogLevel, - filter_default => log, - filters => [{hg_otel_trace_id_bytes, {fun hg_otel_log_filter:filter/2, undefined}}], - config => HandlerConfig - }, - case logger:add_handler(otel_logs, hg_otel_log_handler, LoggerHandlerConfig) of + case logger:add_handler(otel_logs, otel_log_handler, LoggerHandlerConfig) of ok -> ok; {error, {already_exist, _}} -> @@ -171,13 +167,8 @@ ensure_otel_log_handler() -> flush_otel_logs() -> case logger:get_handler_config(otel_logs) of {ok, HandlerCfg} -> - Config = maps:get(config, HandlerCfg, #{}), - DelayMs = maps:get( - scheduled_delay_ms, - Config, - maps:get(scheduled_delay_ms, HandlerCfg, 1000) - ), - _ = logger:info("otel_log_handler_flush"), + _ = logger:info("Waiting for OTEL logs exporter to flush"), + DelayMs = maps:get(scheduled_delay_ms, HandlerCfg, 1000), timer:sleep(erlang:min(?FLUSH_MAX_WAIT_MS, DelayMs + ?FLUSH_EXPORT_OVERHEAD_MS)), ok; _ -> diff --git a/apps/hellgate/src/hg_otel_log_filter.erl b/apps/hellgate/src/hg_otel_log_filter.erl index 03018b60..f61aa9e2 100644 --- a/apps/hellgate/src/hg_otel_log_filter.erl +++ b/apps/hellgate/src/hg_otel_log_filter.erl @@ -6,16 +6,10 @@ -module(hg_otel_log_filter). -export([filter/2]). --export([format_otp_report_utf8/1]). -spec filter(logger:log_event(), term()) -> logger:filter_return(). filter(#{meta := Meta} = LogEvent, _FilterConfig) -> - case convert_otel_ids(Meta) of - Meta -> - LogEvent; - Meta1 -> - LogEvent#{meta => Meta1} - end. + LogEvent#{meta := convert_otel_ids(Meta)}. %% Конвертируем hex -> raw bytes только если формат hex (32/16 символов). %% OTLP LogRecord: trace_id=16 bytes, span_id=8 bytes. @@ -30,22 +24,6 @@ convert_otel_ids(#{otel_trace_id := TraceIdHex, otel_span_id := SpanIdHex} = Met convert_otel_ids(Meta) -> Meta. -%% logger:format_otp_report/1 возвращает chardata (часто list()), -%% из-за чего downstream JSON может сериализовать body как массив байт. -%% Явно приводим к UTF-8 binary(), чтобы body в OTel/Loki был строкой. --spec format_otp_report_utf8(logger:report()) -> {unicode:chardata(), list()}. -format_otp_report_utf8(Report) -> - Bin = - try logger:format_otp_report(Report) of - {Format, Args} -> - unicode:characters_to_binary(io_lib:format(Format, Args)) - catch - _:_ -> - %% Не даём report_cb падать: fallback в печатное представление отчёта. - unicode:characters_to_binary(io_lib:format("~tp", [Report])) - end, - {"~ts", [Bin]}. - hex_to_trace_id_bytes(Hex) when is_binary(Hex), byte_size(Hex) =:= 32 -> try <<(binary_to_integer(Hex, 16)):128>> diff --git a/apps/hellgate/src/hg_otel_log_handler.erl b/apps/hellgate/src/hg_otel_log_handler.erl deleted file mode 100644 index 2168620f..00000000 --- a/apps/hellgate/src/hg_otel_log_handler.erl +++ /dev/null @@ -1,48 +0,0 @@ --module(hg_otel_log_handler). - --export([log/2]). --export([adding_handler/1]). --export([removing_handler/1]). --export([changing_config/3]). --export([filter_config/1]). - --spec log(logger:log_event(), map()) -> ok. -log(LogEvent, Config) -> - otel_log_handler:log(LogEvent, Config). - --spec adding_handler(map()) -> {ok, map()} | {error, term()}. -adding_handler(Config) -> - otel_log_handler:adding_handler(merge_module_config(Config)). - --spec removing_handler(map()) -> ok. -removing_handler(Config) -> - otel_log_handler:removing_handler(Config). - --spec changing_config(set | update, map(), map()) -> {ok, map()} | {error, term()}. -changing_config(SetOrUpdate, OldConfig, NewConfig) -> - otel_log_handler:changing_config( - SetOrUpdate, - merge_module_config(OldConfig), - merge_module_config(NewConfig) - ). - --spec filter_config(map()) -> map(). -filter_config(Config) -> - otel_log_handler:filter_config(Config). - -%% Переносим ключи из вложенного config в корневой map для otel_log_handler. -%% Только ключи, которые ожидает otel_log_handler — чтобы случайно не перезаписать -%% верхнеуровневые настройки logger (level, filters, filter_default и т.д.). --define(OTEL_LOG_HANDLER_KEYS, [ - exporter, - report_cb, - max_queue_size, - scheduled_delay_ms, - exporting_timeout_ms -]). - -merge_module_config(#{config := ModuleConfig} = Config) when is_map(ModuleConfig) -> - OtelConfig = maps:with(?OTEL_LOG_HANDLER_KEYS, ModuleConfig), - maps:merge(Config, OtelConfig); -merge_module_config(Config) -> - Config. diff --git a/apps/hellgate/test/hg_invoice_tests_SUITE.erl b/apps/hellgate/test/hg_invoice_tests_SUITE.erl index c0ff2506..3661553f 100644 --- a/apps/hellgate/test/hg_invoice_tests_SUITE.erl +++ b/apps/hellgate/test/hg_invoice_tests_SUITE.erl @@ -499,6 +499,7 @@ groups() -> -spec init_per_suite(config()) -> config(). init_per_suite(C) -> + % ok = logger:set_primary_config(level, debug), % _ = dbg:tracer(), % _ = dbg:p(all, c), % _ = dbg:tpl({'hg_invoice_payment', 'p', '_'}, x), diff --git a/rebar.lock b/rebar.lock index e3f22424..8aeefdce 100644 --- a/rebar.lock +++ b/rebar.lock @@ -91,12 +91,12 @@ 0}, {<<"opentelemetry_experimental">>, {git_subdir,"https://github.com/valitydev/opentelemetry-erlang.git", - {ref,"685389b35fb188166e072c389a487a8e5a9f0804"}, + {ref,"ddf1efb45e3d2f334ff4b78f0d482f2ab9d32428"}, "apps/opentelemetry_experimental"}, 0}, {<<"opentelemetry_exporter">>, {git_subdir,"https://github.com/valitydev/opentelemetry-erlang.git", - {ref,"685389b35fb188166e072c389a487a8e5a9f0804"}, + {ref,"ddf1efb45e3d2f334ff4b78f0d482f2ab9d32428"}, "apps/opentelemetry_exporter"}, 0}, {<<"parse_trans">>,{pkg,<<"parse_trans">>,<<"3.3.1">>},2},