%%%------------------------------------------------------------------- %%% @doc barrel_docdb application module %%% %%% Starts and stops the barrel_docdb application. %%% @end %%%------------------------------------------------------------------- -module(barrel_docdb_app). -behaviour(application). %% Application callbacks -export([start/2, stop/1]). %%==================================================================== %% Application callbacks %%==================================================================== %% @doc Start the barrel_docdb application -spec start(application:start_type(), term()) -> {ok, pid()} | {error, term()}. start(_StartType, _StartArgs) -> %% Install instrument logger filter for trace context enrichment ok = instrument_logger:install(), %% Configure observability exporters ok = configure_tracing(), ok = configure_metrics(), ok = configure_logging(), logger:info("Starting barrel_docdb application"), barrel_docdb_sup:start_link(). %% @doc Stop the barrel_docdb application -spec stop(term()) -> ok. stop(_State) -> logger:info("Stopping barrel_docdb application"), %% Shutdown all exporters _ = instrument_exporter:shutdown(), _ = instrument_metrics_exporter:shutdown(), _ = instrument_log_exporter:shutdown(), %% Uninstall instrument logger filter instrument_logger:uninstall(), ok. %%==================================================================== %% Internal functions %%==================================================================== %% @doc Configure tracing based on application environment. %% %% Configuration options: %% - {tracing, enabled} - Enable/disable tracing (default: true) %% - {tracing, exporter} - console | otlp | {module, Config} (default: none) %% - {tracing, otlp_endpoint} - OTLP endpoint URL (for otlp exporter) %% %% Example sys.config: %% ``` %% {barrel_docdb, [ %% {tracing, [ %% {enabled, true}, %% {exporter, console} %% or otlp or none %% ]} %% ]} %% ''' -spec configure_tracing() -> ok. configure_tracing() -> TracingConfig = application:get_env(barrel_docdb, tracing, []), Enabled = proplists:get_value(enabled, TracingConfig, true), case Enabled of true -> configure_exporter(TracingConfig); false -> %% Disable tracing globally for zero overhead instrument_config:set_tracing_enabled(false), logger:info("Tracing disabled globally"), ok end. %% @doc Configure the span exporter based on configuration. configure_exporter(TracingConfig) -> Exporter = proplists:get_value(exporter, TracingConfig, none), case Exporter of none -> ok; console -> Format = proplists:get_value(console_format, TracingConfig, text), _ = instrument_exporter:register(instrument_exporter_console:new(#{ format => Format })), logger:info("Tracing enabled with console exporter"), ok; otlp -> Endpoint = proplists:get_value(otlp_endpoint, TracingConfig, "http://localhost:4318"), _ = instrument_exporter:register(instrument_exporter_otlp:new(#{ endpoint => Endpoint })), logger:info("Tracing enabled with OTLP exporter, endpoint: ~s", [Endpoint]), ok; {Module, Config} when is_atom(Module), is_map(Config) -> _ = instrument_exporter:register(#{module => Module, config => Config}), logger:info("Tracing enabled with custom exporter: ~p", [Module]), ok; _ -> logger:warning("Unknown tracing exporter configuration: ~p", [Exporter]), ok end. %% @doc Configure metrics exporter based on application environment. %% %% Configuration options: %% - {metrics, exporter} - none | console | otlp (default: none) %% - {metrics, otlp_endpoint} - OTLP endpoint URL %% - {metrics, otlp_headers} - Additional HTTP headers %% - {metrics, otlp_compression} - none | gzip %% - {metrics, export_interval} - Export interval in ms (default: 60000) -spec configure_metrics() -> ok. configure_metrics() -> MetricsConfig = application:get_env(barrel_docdb, metrics, []), Exporter = proplists:get_value(exporter, MetricsConfig, none), case Exporter of none -> ok; console -> _ = instrument_metrics_exporter:register( instrument_metrics_exporter_console:new(#{})), logger:info("Metrics exporter enabled: console"), ok; otlp -> Endpoint = proplists:get_value(otlp_endpoint, MetricsConfig, "http://localhost:4318"), Headers = proplists:get_value(otlp_headers, MetricsConfig, #{}), Compression = proplists:get_value(otlp_compression, MetricsConfig, none), _ = instrument_metrics_exporter:register( instrument_metrics_exporter_otlp:new(#{ endpoint => Endpoint, headers => Headers, compression => Compression })), logger:info("Metrics exporter enabled: OTLP (~s)", [Endpoint]), ok; {Module, Config} when is_atom(Module), is_map(Config) -> _ = instrument_metrics_exporter:register(#{module => Module, config => Config}), logger:info("Metrics exporter enabled: ~p", [Module]), ok; _ -> logger:warning("Unknown metrics exporter configuration: ~p", [Exporter]), ok end. %% @doc Configure logging exporter based on application environment. %% %% Configuration options: %% - {logging, exporter} - none | console | file | otlp (default: none) %% - {logging, file_path} - Log file path (for file exporter) %% - {logging, file_format} - text | json (default: text) %% - {logging, file_max_size} - Max file size in bytes (default: 10MB, 0 = unlimited) %% - {logging, file_max_files} - Number of rotated files (default: 5) %% - {logging, file_compress} - Compress rotated files (default: false) %% - {logging, otlp_endpoint} - OTLP endpoint URL %% - {logging, otlp_headers} - Additional HTTP headers %% - {logging, otlp_compression} - none | gzip -spec configure_logging() -> ok. configure_logging() -> LoggingConfig = application:get_env(barrel_docdb, logging, []), Exporter = proplists:get_value(exporter, LoggingConfig, none), case Exporter of none -> ok; console -> _ = instrument_log_exporter:register( instrument_log_exporter_console:new(#{})), logger:info("Log exporter enabled: console"), ok; file -> Path = proplists:get_value(file_path, LoggingConfig, "/var/log/barrel.log"), Format = proplists:get_value(file_format, LoggingConfig, text), MaxSize = proplists:get_value(file_max_size, LoggingConfig, 10485760), MaxFiles = proplists:get_value(file_max_files, LoggingConfig, 5), Compress = proplists:get_value(file_compress, LoggingConfig, false), _ = instrument_log_exporter:register( instrument_log_exporter_file:new(#{ path => Path, format => Format, max_size => MaxSize, max_files => MaxFiles, compress => Compress })), logger:info("Log exporter enabled: file (~s)", [Path]), ok; otlp -> Endpoint = proplists:get_value(otlp_endpoint, LoggingConfig, "http://localhost:4318"), Headers = proplists:get_value(otlp_headers, LoggingConfig, #{}), Compression = proplists:get_value(otlp_compression, LoggingConfig, none), _ = instrument_log_exporter:register( instrument_log_exporter_otlp:new(#{ endpoint => Endpoint, headers => Headers, compression => Compression })), logger:info("Log exporter enabled: OTLP (~s)", [Endpoint]), ok; {Module, Config} when is_atom(Module), is_map(Config) -> _ = instrument_log_exporter:register(#{module => Module, config => Config}), logger:info("Log exporter enabled: ~p", [Module]), ok; _ -> logger:warning("Unknown logging exporter configuration: ~p", [Exporter]), ok end.