feat(emqx_opentelemetry): use one global exporter config for all otel signals
This commit is contained in:
parent
2a3f6b749c
commit
c8e69357cc
|
@ -24,7 +24,7 @@
|
||||||
start(_StartType, _StartArgs) ->
|
start(_StartType, _StartArgs) ->
|
||||||
emqx_otel_config:add_handler(),
|
emqx_otel_config:add_handler(),
|
||||||
ok = emqx_otel_config:add_otel_log_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().
|
emqx_otel_sup:start_link().
|
||||||
|
|
||||||
stop(_State) ->
|
stop(_State) ->
|
||||||
|
|
|
@ -85,30 +85,40 @@ otel_exporter(ExporterConf) ->
|
||||||
|
|
||||||
%% Internal functions
|
%% Internal functions
|
||||||
|
|
||||||
ensure_otel_metrics(#{metrics := MetricsConf}, #{metrics := MetricsConf}) ->
|
ensure_otel_metrics(
|
||||||
|
#{metrics := MetricsConf, exporter := Exporter},
|
||||||
|
#{metrics := MetricsConf, exporter := Exporter}
|
||||||
|
) ->
|
||||||
ok;
|
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:stop_otel(),
|
||||||
emqx_otel_metrics:start_otel(MetricsConf);
|
emqx_otel_metrics:start_otel(Conf);
|
||||||
ensure_otel_metrics(#{metrics := #{enable := false}}, _Old) ->
|
ensure_otel_metrics(#{metrics := #{enable := false}}, _Old) ->
|
||||||
emqx_otel_metrics:stop_otel();
|
emqx_otel_metrics:stop_otel();
|
||||||
ensure_otel_metrics(_, _) ->
|
ensure_otel_metrics(_, _) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
ensure_otel_logs(#{logs := LogsConf}, #{logs := LogsConf}) ->
|
ensure_otel_logs(
|
||||||
|
#{logs := LogsConf, exporter := Exporter},
|
||||||
|
#{logs := LogsConf, exporter := Exporter}
|
||||||
|
) ->
|
||||||
ok;
|
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),
|
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?
|
%% 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);
|
logger:add_handler(?OTEL_LOG_HANDLER_ID, ?OTEL_LOG_HANDLER, HandlerConf);
|
||||||
ensure_otel_logs(#{logs := #{enable := false}}, _OldConf) ->
|
ensure_otel_logs(#{logs := #{enable := false}}, _OldConf) ->
|
||||||
remove_handler_if_present(?OTEL_LOG_HANDLER_ID).
|
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;
|
ok;
|
||||||
ensure_otel_traces(#{traces := #{enable := true} = TracesConf}, _OldConf) ->
|
ensure_otel_traces(#{traces := #{enable := true}} = Conf, _OldConf) ->
|
||||||
emqx_otel_trace:start(TracesConf);
|
_ = emqx_otel_trace:stop(),
|
||||||
|
emqx_otel_trace:start(Conf);
|
||||||
ensure_otel_traces(#{traces := #{enable := false}}, _OldConf) ->
|
ensure_otel_traces(#{traces := #{enable := false}}, _OldConf) ->
|
||||||
emqx_otel_trace:stop().
|
emqx_otel_trace:stop().
|
||||||
|
|
||||||
|
@ -120,14 +130,13 @@ remove_handler_if_present(HandlerId) ->
|
||||||
ok
|
ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
tr_handler_conf(Conf) ->
|
tr_handler_conf(#{logs := LogsConf, exporter := ExporterConf}) ->
|
||||||
#{
|
#{
|
||||||
level := Level,
|
level := Level,
|
||||||
max_queue_size := MaxQueueSize,
|
max_queue_size := MaxQueueSize,
|
||||||
exporting_timeout := ExportingTimeout,
|
exporting_timeout := ExportingTimeout,
|
||||||
scheduled_delay := ScheduledDelay,
|
scheduled_delay := ScheduledDelay
|
||||||
exporter := ExporterConf
|
} = LogsConf,
|
||||||
} = Conf,
|
|
||||||
#{
|
#{
|
||||||
level => Level,
|
level => Level,
|
||||||
config => #{
|
config => #{
|
||||||
|
|
|
@ -65,7 +65,7 @@ handle_info(_Msg, State) ->
|
||||||
terminate(_Reason, _State) ->
|
terminate(_Reason, _State) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
setup(Conf = #{enable := true}) ->
|
setup(Conf = #{metrics := #{enable := true}}) ->
|
||||||
ensure_apps(Conf),
|
ensure_apps(Conf),
|
||||||
create_metric_views();
|
create_metric_views();
|
||||||
setup(_Conf) ->
|
setup(_Conf) ->
|
||||||
|
@ -73,7 +73,10 @@ setup(_Conf) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
ensure_apps(Conf) ->
|
ensure_apps(Conf) ->
|
||||||
#{exporter := #{interval := ExporterInterval} = Exporter} = Conf,
|
#{
|
||||||
|
exporter := Exporter,
|
||||||
|
metrics := #{interval := ExporterInterval}
|
||||||
|
} = Conf,
|
||||||
|
|
||||||
_ = opentelemetry_experimental:stop_default_metrics(),
|
_ = opentelemetry_experimental:stop_default_metrics(),
|
||||||
ok = application:set_env(
|
ok = application:set_env(
|
||||||
|
|
|
@ -30,15 +30,27 @@
|
||||||
upgrade_legacy_metrics(RawConf) ->
|
upgrade_legacy_metrics(RawConf) ->
|
||||||
case RawConf of
|
case RawConf of
|
||||||
#{<<"opentelemetry">> := Otel} ->
|
#{<<"opentelemetry">> := Otel} ->
|
||||||
LegacyMetricsFields = [<<"enable">>, <<"exporter">>],
|
Otel1 =
|
||||||
Otel1 = maps:without(LegacyMetricsFields, Otel),
|
case maps:take(<<"enable">>, Otel) of
|
||||||
Metrics = maps:with(LegacyMetricsFields, Otel),
|
{MetricsEnable, OtelConf} ->
|
||||||
case Metrics =:= #{} of
|
emqx_utils_maps:deep_put(
|
||||||
true ->
|
[<<"metrics">>, <<"enable">>], OtelConf, MetricsEnable
|
||||||
RawConf;
|
);
|
||||||
false ->
|
error ->
|
||||||
RawConf#{<<"opentelemetry">> => Otel1#{<<"metrics">> => Metrics}}
|
Otel
|
||||||
end;
|
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
|
RawConf
|
||||||
end.
|
end.
|
||||||
|
@ -69,6 +81,13 @@ fields("opentelemetry") ->
|
||||||
#{
|
#{
|
||||||
desc => ?DESC(otel_traces)
|
desc => ?DESC(otel_traces)
|
||||||
}
|
}
|
||||||
|
)},
|
||||||
|
{exporter,
|
||||||
|
?HOCON(
|
||||||
|
?R_REF("otel_exporter"),
|
||||||
|
#{
|
||||||
|
desc => ?DESC(otel_exporter)
|
||||||
|
}
|
||||||
)}
|
)}
|
||||||
];
|
];
|
||||||
fields("otel_metrics") ->
|
fields("otel_metrics") ->
|
||||||
|
@ -82,10 +101,15 @@ fields("otel_metrics") ->
|
||||||
desc => ?DESC(enable)
|
desc => ?DESC(enable)
|
||||||
}
|
}
|
||||||
)},
|
)},
|
||||||
{exporter,
|
{interval,
|
||||||
?HOCON(
|
?HOCON(
|
||||||
?R_REF("otel_metrics_exporter"),
|
emqx_schema:timeout_duration_ms(),
|
||||||
#{desc => ?DESC(exporter)}
|
#{
|
||||||
|
aliases => [scheduled_delay],
|
||||||
|
default => <<"10s">>,
|
||||||
|
desc => ?DESC(scheduled_delay),
|
||||||
|
importance => ?IMPORTANCE_HIDDEN
|
||||||
|
}
|
||||||
)}
|
)}
|
||||||
];
|
];
|
||||||
fields("otel_logs") ->
|
fields("otel_logs") ->
|
||||||
|
@ -134,14 +158,6 @@ fields("otel_logs") ->
|
||||||
desc => ?DESC(scheduled_delay),
|
desc => ?DESC(scheduled_delay),
|
||||||
importance => ?IMPORTANCE_HIDDEN
|
importance => ?IMPORTANCE_HIDDEN
|
||||||
}
|
}
|
||||||
)},
|
|
||||||
{exporter,
|
|
||||||
?HOCON(
|
|
||||||
?R_REF("otel_logs_exporter"),
|
|
||||||
#{
|
|
||||||
desc => ?DESC(exporter),
|
|
||||||
importance => ?IMPORTANCE_HIGH
|
|
||||||
}
|
|
||||||
)}
|
)}
|
||||||
];
|
];
|
||||||
fields("otel_traces") ->
|
fields("otel_traces") ->
|
||||||
|
@ -182,14 +198,6 @@ fields("otel_traces") ->
|
||||||
importance => ?IMPORTANCE_HIDDEN
|
importance => ?IMPORTANCE_HIDDEN
|
||||||
}
|
}
|
||||||
)},
|
)},
|
||||||
{exporter,
|
|
||||||
?HOCON(
|
|
||||||
?R_REF("otel_traces_exporter"),
|
|
||||||
#{
|
|
||||||
desc => ?DESC(exporter),
|
|
||||||
importance => ?IMPORTANCE_HIGH
|
|
||||||
}
|
|
||||||
)},
|
|
||||||
{filter,
|
{filter,
|
||||||
?HOCON(
|
?HOCON(
|
||||||
?R_REF("trace_filter"),
|
?R_REF("trace_filter"),
|
||||||
|
@ -199,42 +207,7 @@ fields("otel_traces") ->
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
];
|
];
|
||||||
fields("otel_metrics_exporter") ->
|
fields("otel_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) ->
|
|
||||||
[
|
[
|
||||||
{endpoint,
|
{endpoint,
|
||||||
?HOCON(
|
?HOCON(
|
||||||
|
@ -263,21 +236,29 @@ exporter_fields(OtelSignal) ->
|
||||||
importance => ?IMPORTANCE_LOW
|
importance => ?IMPORTANCE_LOW
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
] ++ exporter_extra_fields(OtelSignal).
|
];
|
||||||
|
fields("ssl_opts") ->
|
||||||
%% Let's keep it in exporter config for metrics, as it is different from
|
Schema = emqx_schema:client_ssl_opts_schema(#{}),
|
||||||
%% scheduled_delay_ms opt used for otel traces and logs
|
lists:keydelete("enable", 1, Schema);
|
||||||
exporter_extra_fields(metrics) ->
|
fields("trace_filter") ->
|
||||||
|
%% More filters can be implemented in future, e.g. topic, clientid
|
||||||
[
|
[
|
||||||
{interval,
|
{trace_all,
|
||||||
?HOCON(
|
?HOCON(
|
||||||
emqx_schema:timeout_duration_ms(),
|
boolean(),
|
||||||
#{
|
#{
|
||||||
default => <<"10s">>,
|
default => false,
|
||||||
required => true,
|
desc => ?DESC(trace_all),
|
||||||
desc => ?DESC(scheduled_delay)
|
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.
|
||||||
|
|
|
@ -41,8 +41,8 @@ init([]) ->
|
||||||
period => 512
|
period => 512
|
||||||
},
|
},
|
||||||
Children =
|
Children =
|
||||||
case emqx_conf:get([opentelemetry, metrics]) of
|
case emqx_conf:get([opentelemetry]) of
|
||||||
#{enable := false} -> [];
|
#{metrics := #{enable := false}} -> [];
|
||||||
#{enable := true} = Conf -> [worker_spec(emqx_otel_metrics, Conf)]
|
#{metrics := #{enable := true}} = Conf -> [worker_spec(emqx_otel_metrics, Conf)]
|
||||||
end,
|
end,
|
||||||
{ok, {SupFlags, Children}}.
|
{ok, {SupFlags, Children}}.
|
||||||
|
|
|
@ -55,26 +55,24 @@ toggle_registered(false = _Enable) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
-spec ensure_traces(map()) -> ok | {error, term()}.
|
-spec ensure_traces(map()) -> ok | {error, term()}.
|
||||||
ensure_traces(#{enable := true} = Conf) ->
|
ensure_traces(#{traces := #{enable := true}} = Conf) ->
|
||||||
start(Conf);
|
start(Conf);
|
||||||
ensure_traces(_Conf) ->
|
ensure_traces(_Conf) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
-spec start(map()) -> ok | {error, term()}.
|
-spec start(map()) -> ok | {error, term()}.
|
||||||
start(Conf) ->
|
start(#{traces := TracesConf, exporter := ExporterConf}) ->
|
||||||
_ = safe_stop_default_tracer(),
|
|
||||||
#{
|
#{
|
||||||
exporter := Exporter,
|
|
||||||
max_queue_size := MaxQueueSize,
|
max_queue_size := MaxQueueSize,
|
||||||
exporting_timeout := ExportingTimeout,
|
exporting_timeout := ExportingTimeout,
|
||||||
scheduled_delay := ScheduledDelay,
|
scheduled_delay := ScheduledDelay,
|
||||||
filter := #{trace_all := TraceAll}
|
filter := #{trace_all := TraceAll}
|
||||||
} = Conf,
|
} = TracesConf,
|
||||||
OtelEnv = [
|
OtelEnv = [
|
||||||
{bsp_scheduled_delay_ms, ScheduledDelay},
|
{bsp_scheduled_delay_ms, ScheduledDelay},
|
||||||
{bsp_exporting_timeout_ms, ExportingTimeout},
|
{bsp_exporting_timeout_ms, ExportingTimeout},
|
||||||
{bsp_max_queue_size, MaxQueueSize},
|
{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),
|
set_trace_all(TraceAll),
|
||||||
ok = application:set_env([{opentelemetry, OtelEnv}]),
|
ok = application:set_env([{opentelemetry, OtelEnv}]),
|
||||||
|
|
|
@ -17,8 +17,8 @@ otel_traces.label: "Open Telemetry Traces"
|
||||||
enable.desc: "Enable or disable Open Telemetry signal."
|
enable.desc: "Enable or disable Open Telemetry signal."
|
||||||
enable.label: "Enable."
|
enable.label: "Enable."
|
||||||
|
|
||||||
exporter.desc: "Open Telemetry Exporter"
|
otel_exporter.desc: "Open Telemetry Exporter"
|
||||||
exporter.label: "Exporter"
|
otel_exporter.label: "Exporter"
|
||||||
|
|
||||||
max_queue_size.desc:
|
max_queue_size.desc:
|
||||||
"""The maximum queue size. After the size is reached Open Telemetry signals are dropped."""
|
"""The maximum queue size. After the size is reached Open Telemetry signals are dropped."""
|
||||||
|
|
Loading…
Reference in New Issue