diff --git a/apps/emqx_opentelemetry/src/emqx_otel_app.erl b/apps/emqx_opentelemetry/src/emqx_otel_app.erl index 8231e089f..014785c6d 100644 --- a/apps/emqx_opentelemetry/src/emqx_otel_app.erl +++ b/apps/emqx_opentelemetry/src/emqx_otel_app.erl @@ -24,7 +24,7 @@ start(_StartType, _StartArgs) -> emqx_otel_config:add_handler(), ok = emqx_otel_config:add_otel_log_handler(), - ok = emqx_otel_trace:ensure_traces(emqx:get_config([opentelemetry, traces])), + ok = emqx_otel_trace:ensure_traces(emqx:get_config([opentelemetry])), emqx_otel_sup:start_link(). stop(_State) -> diff --git a/apps/emqx_opentelemetry/src/emqx_otel_config.erl b/apps/emqx_opentelemetry/src/emqx_otel_config.erl index f9ad6ca31..0d2f9988b 100644 --- a/apps/emqx_opentelemetry/src/emqx_otel_config.erl +++ b/apps/emqx_opentelemetry/src/emqx_otel_config.erl @@ -85,30 +85,40 @@ otel_exporter(ExporterConf) -> %% Internal functions -ensure_otel_metrics(#{metrics := MetricsConf}, #{metrics := MetricsConf}) -> +ensure_otel_metrics( + #{metrics := MetricsConf, exporter := Exporter}, + #{metrics := MetricsConf, exporter := Exporter} +) -> ok; -ensure_otel_metrics(#{metrics := #{enable := true} = MetricsConf}, _Old) -> +ensure_otel_metrics(#{metrics := #{enable := true}} = Conf, _Old) -> _ = emqx_otel_metrics:stop_otel(), - emqx_otel_metrics:start_otel(MetricsConf); + emqx_otel_metrics:start_otel(Conf); ensure_otel_metrics(#{metrics := #{enable := false}}, _Old) -> emqx_otel_metrics:stop_otel(); ensure_otel_metrics(_, _) -> ok. -ensure_otel_logs(#{logs := LogsConf}, #{logs := LogsConf}) -> +ensure_otel_logs( + #{logs := LogsConf, exporter := Exporter}, + #{logs := LogsConf, exporter := Exporter} +) -> ok; -ensure_otel_logs(#{logs := #{enable := true} = LogsConf}, _OldConf) -> +ensure_otel_logs(#{logs := #{enable := true}} = Conf, _OldConf) -> ok = remove_handler_if_present(?OTEL_LOG_HANDLER_ID), - HandlerConf = tr_handler_conf(LogsConf), + HandlerConf = tr_handler_conf(Conf), %% NOTE: should primary logger level be updated if it's higher than otel log level? logger:add_handler(?OTEL_LOG_HANDLER_ID, ?OTEL_LOG_HANDLER, HandlerConf); ensure_otel_logs(#{logs := #{enable := false}}, _OldConf) -> remove_handler_if_present(?OTEL_LOG_HANDLER_ID). -ensure_otel_traces(#{traces := TracesConf}, #{traces := TracesConf}) -> +ensure_otel_traces( + #{traces := TracesConf, exporter := Exporter}, + #{traces := TracesConf, exporter := Exporter} +) -> ok; -ensure_otel_traces(#{traces := #{enable := true} = TracesConf}, _OldConf) -> - emqx_otel_trace:start(TracesConf); +ensure_otel_traces(#{traces := #{enable := true}} = Conf, _OldConf) -> + _ = emqx_otel_trace:stop(), + emqx_otel_trace:start(Conf); ensure_otel_traces(#{traces := #{enable := false}}, _OldConf) -> emqx_otel_trace:stop(). @@ -120,14 +130,13 @@ remove_handler_if_present(HandlerId) -> ok end. -tr_handler_conf(Conf) -> +tr_handler_conf(#{logs := LogsConf, exporter := ExporterConf}) -> #{ level := Level, max_queue_size := MaxQueueSize, exporting_timeout := ExportingTimeout, - scheduled_delay := ScheduledDelay, - exporter := ExporterConf - } = Conf, + scheduled_delay := ScheduledDelay + } = LogsConf, #{ level => Level, config => #{ diff --git a/apps/emqx_opentelemetry/src/emqx_otel_metrics.erl b/apps/emqx_opentelemetry/src/emqx_otel_metrics.erl index 1d70a800a..6e16e79d4 100644 --- a/apps/emqx_opentelemetry/src/emqx_otel_metrics.erl +++ b/apps/emqx_opentelemetry/src/emqx_otel_metrics.erl @@ -65,7 +65,7 @@ handle_info(_Msg, State) -> terminate(_Reason, _State) -> ok. -setup(Conf = #{enable := true}) -> +setup(Conf = #{metrics := #{enable := true}}) -> ensure_apps(Conf), create_metric_views(); setup(_Conf) -> @@ -73,7 +73,10 @@ setup(_Conf) -> ok. ensure_apps(Conf) -> - #{exporter := #{interval := ExporterInterval} = Exporter} = Conf, + #{ + exporter := Exporter, + metrics := #{interval := ExporterInterval} + } = Conf, _ = opentelemetry_experimental:stop_default_metrics(), ok = application:set_env( diff --git a/apps/emqx_opentelemetry/src/emqx_otel_schema.erl b/apps/emqx_opentelemetry/src/emqx_otel_schema.erl index 6359f88a5..bcd0b8dcf 100644 --- a/apps/emqx_opentelemetry/src/emqx_otel_schema.erl +++ b/apps/emqx_opentelemetry/src/emqx_otel_schema.erl @@ -30,15 +30,27 @@ upgrade_legacy_metrics(RawConf) -> case RawConf of #{<<"opentelemetry">> := Otel} -> - LegacyMetricsFields = [<<"enable">>, <<"exporter">>], - Otel1 = maps:without(LegacyMetricsFields, Otel), - Metrics = maps:with(LegacyMetricsFields, Otel), - case Metrics =:= #{} of - true -> - RawConf; - false -> - RawConf#{<<"opentelemetry">> => Otel1#{<<"metrics">> => Metrics}} - end; + Otel1 = + case maps:take(<<"enable">>, Otel) of + {MetricsEnable, OtelConf} -> + emqx_utils_maps:deep_put( + [<<"metrics">>, <<"enable">>], OtelConf, MetricsEnable + ); + error -> + Otel + end, + Otel2 = + case Otel1 of + #{<<"exporter">> := #{<<"interval">> := Interval} = Exporter} -> + emqx_utils_maps:deep_put( + [<<"metrics">>, <<"interval">>], + Otel1#{<<"exporter">> => maps:remove(<<"interval">>, Exporter)}, + Interval + ); + _ -> + Otel1 + end, + RawConf#{<<"opentelemetry">> => Otel2}; _ -> RawConf end. @@ -69,6 +81,13 @@ fields("opentelemetry") -> #{ desc => ?DESC(otel_traces) } + )}, + {exporter, + ?HOCON( + ?R_REF("otel_exporter"), + #{ + desc => ?DESC(otel_exporter) + } )} ]; fields("otel_metrics") -> @@ -82,10 +101,15 @@ fields("otel_metrics") -> desc => ?DESC(enable) } )}, - {exporter, + {interval, ?HOCON( - ?R_REF("otel_metrics_exporter"), - #{desc => ?DESC(exporter)} + emqx_schema:timeout_duration_ms(), + #{ + aliases => [scheduled_delay], + default => <<"10s">>, + desc => ?DESC(scheduled_delay), + importance => ?IMPORTANCE_HIDDEN + } )} ]; fields("otel_logs") -> @@ -134,14 +158,6 @@ fields("otel_logs") -> desc => ?DESC(scheduled_delay), importance => ?IMPORTANCE_HIDDEN } - )}, - {exporter, - ?HOCON( - ?R_REF("otel_logs_exporter"), - #{ - desc => ?DESC(exporter), - importance => ?IMPORTANCE_HIGH - } )} ]; fields("otel_traces") -> @@ -182,14 +198,6 @@ fields("otel_traces") -> importance => ?IMPORTANCE_HIDDEN } )}, - {exporter, - ?HOCON( - ?R_REF("otel_traces_exporter"), - #{ - desc => ?DESC(exporter), - importance => ?IMPORTANCE_HIGH - } - )}, {filter, ?HOCON( ?R_REF("trace_filter"), @@ -199,42 +207,7 @@ fields("otel_traces") -> } )} ]; -fields("otel_metrics_exporter") -> - exporter_fields(metrics); -fields("otel_logs_exporter") -> - exporter_fields(logs); -fields("ssl_opts") -> - Schema = emqx_schema:client_ssl_opts_schema(#{}), - lists:keydelete("enable", 1, Schema); -fields("otel_traces_exporter") -> - exporter_fields(traces); -fields("trace_filter") -> - %% More filters can be implemented in future, e.g. topic, clientid - [ - {trace_all, - ?HOCON( - boolean(), - #{ - default => false, - desc => ?DESC(trace_all), - importance => ?IMPORTANCE_MEDIUM - } - )} - ]. - -desc("opentelemetry") -> ?DESC(opentelemetry); -desc("exporter") -> ?DESC(exporter); -desc("otel_logs_exporter") -> ?DESC(exporter); -desc("otel_metrics_exporter") -> ?DESC(exporter); -desc("otel_traces_exporter") -> ?DESC(exporter); -desc("otel_logs") -> ?DESC(otel_logs); -desc("otel_metrics") -> ?DESC(otel_metrics); -desc("otel_traces") -> ?DESC(otel_traces); -desc("ssl_opts") -> ?DESC(exporter_ssl); -desc("trace_filter") -> ?DESC(trace_filter); -desc(_) -> undefined. - -exporter_fields(OtelSignal) -> +fields("otel_exporter") -> [ {endpoint, ?HOCON( @@ -263,21 +236,29 @@ exporter_fields(OtelSignal) -> importance => ?IMPORTANCE_LOW } )} - ] ++ exporter_extra_fields(OtelSignal). - -%% Let's keep it in exporter config for metrics, as it is different from -%% scheduled_delay_ms opt used for otel traces and logs -exporter_extra_fields(metrics) -> + ]; +fields("ssl_opts") -> + Schema = emqx_schema:client_ssl_opts_schema(#{}), + lists:keydelete("enable", 1, Schema); +fields("trace_filter") -> + %% More filters can be implemented in future, e.g. topic, clientid [ - {interval, + {trace_all, ?HOCON( - emqx_schema:timeout_duration_ms(), + boolean(), #{ - default => <<"10s">>, - required => true, - desc => ?DESC(scheduled_delay) + default => false, + desc => ?DESC(trace_all), + importance => ?IMPORTANCE_MEDIUM } )} - ]; -exporter_extra_fields(_OtelSignal) -> - []. + ]. + +desc("opentelemetry") -> ?DESC(opentelemetry); +desc("otel_exporter") -> ?DESC(otel_exporter); +desc("otel_logs") -> ?DESC(otel_logs); +desc("otel_metrics") -> ?DESC(otel_metrics); +desc("otel_traces") -> ?DESC(otel_traces); +desc("ssl_opts") -> ?DESC(exporter_ssl); +desc("trace_filter") -> ?DESC(trace_filter); +desc(_) -> undefined. diff --git a/apps/emqx_opentelemetry/src/emqx_otel_sup.erl b/apps/emqx_opentelemetry/src/emqx_otel_sup.erl index a823b2239..9d8165b21 100644 --- a/apps/emqx_opentelemetry/src/emqx_otel_sup.erl +++ b/apps/emqx_opentelemetry/src/emqx_otel_sup.erl @@ -41,8 +41,8 @@ init([]) -> period => 512 }, Children = - case emqx_conf:get([opentelemetry, metrics]) of - #{enable := false} -> []; - #{enable := true} = Conf -> [worker_spec(emqx_otel_metrics, Conf)] + case emqx_conf:get([opentelemetry]) of + #{metrics := #{enable := false}} -> []; + #{metrics := #{enable := true}} = Conf -> [worker_spec(emqx_otel_metrics, Conf)] end, {ok, {SupFlags, Children}}. diff --git a/apps/emqx_opentelemetry/src/emqx_otel_trace.erl b/apps/emqx_opentelemetry/src/emqx_otel_trace.erl index e6bfd4749..061c3e983 100644 --- a/apps/emqx_opentelemetry/src/emqx_otel_trace.erl +++ b/apps/emqx_opentelemetry/src/emqx_otel_trace.erl @@ -55,26 +55,24 @@ toggle_registered(false = _Enable) -> ok. -spec ensure_traces(map()) -> ok | {error, term()}. -ensure_traces(#{enable := true} = Conf) -> +ensure_traces(#{traces := #{enable := true}} = Conf) -> start(Conf); ensure_traces(_Conf) -> ok. -spec start(map()) -> ok | {error, term()}. -start(Conf) -> - _ = safe_stop_default_tracer(), +start(#{traces := TracesConf, exporter := ExporterConf}) -> #{ - exporter := Exporter, max_queue_size := MaxQueueSize, exporting_timeout := ExportingTimeout, scheduled_delay := ScheduledDelay, filter := #{trace_all := TraceAll} - } = Conf, + } = TracesConf, OtelEnv = [ {bsp_scheduled_delay_ms, ScheduledDelay}, {bsp_exporting_timeout_ms, ExportingTimeout}, {bsp_max_queue_size, MaxQueueSize}, - {traces_exporter, emqx_otel_config:otel_exporter(Exporter)} + {traces_exporter, emqx_otel_config:otel_exporter(ExporterConf)} ], set_trace_all(TraceAll), ok = application:set_env([{opentelemetry, OtelEnv}]), diff --git a/rel/i18n/emqx_otel_schema.hocon b/rel/i18n/emqx_otel_schema.hocon index 0a41874b9..eca20b457 100644 --- a/rel/i18n/emqx_otel_schema.hocon +++ b/rel/i18n/emqx_otel_schema.hocon @@ -17,8 +17,8 @@ otel_traces.label: "Open Telemetry Traces" enable.desc: "Enable or disable Open Telemetry signal." enable.label: "Enable." -exporter.desc: "Open Telemetry Exporter" -exporter.label: "Exporter" +otel_exporter.desc: "Open Telemetry Exporter" +otel_exporter.label: "Exporter" max_queue_size.desc: """The maximum queue size. After the size is reached Open Telemetry signals are dropped."""