-module(distribute@log). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/distribute/log.gleam"). -export([with_correlation_id/2, disable_logging/0, enable_logging/0, set_level/1, get_level/0, set_backend/1, generate_correlation_id/0, format_log_entry/1, log/4, debug/2, info/2, warn/2, error/2, debug_with_correlation/3, info_with_correlation/3, warn_with_correlation/3, error_with_correlation/3]). -export_type([dynamic_/0, level/0, log_entry/0, config/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -type dynamic_() :: any(). -type level() :: debug | info | warn | error | off. -type log_entry() :: {log_entry, level(), binary(), list({binary(), binary()}), gleam@option:option(binary()), integer()}. -type config() :: {config, level(), boolean(), boolean()}. -file("src/distribute/log.gleam", 131). ?DOC(" Execute a function with a specific correlation ID\n"). -spec with_correlation_id(binary(), fun(() -> HDS)) -> HDS. with_correlation_id(_, F) -> F(). -file("src/distribute/log.gleam", 195). ?DOC(" Convert int to Level\n"). -spec int_to_level(integer()) -> level(). int_to_level(I) -> case I of 0 -> debug; 1 -> info; 2 -> warn; 3 -> error; _ -> off end. -file("src/distribute/log.gleam", 247). -spec level_to_name(level()) -> binary(). level_to_name(Level) -> case Level of debug -> <<"DEBUG"/utf8>>; info -> <<"INFO"/utf8>>; warn -> <<"WARN"/utf8>>; error -> <<"ERROR"/utf8>>; off -> <<"OFF"/utf8>> end. -file("src/distribute/log.gleam", 299). ?DOC(" Add ANSI colors to log levels\n"). -spec colorize_level(level(), binary()) -> binary(). colorize_level(Level, Text) -> case Level of debug -> <<<<"\x{001b}[36m"/utf8, Text/binary>>/binary, "\x{001b}[0m"/utf8>>; info -> <<<<"\x{001b}[32m"/utf8, Text/binary>>/binary, "\x{001b}[0m"/utf8>>; warn -> <<<<"\x{001b}[33m"/utf8, Text/binary>>/binary, "\x{001b}[0m"/utf8>>; error -> <<<<"\x{001b}[31m"/utf8, Text/binary>>/binary, "\x{001b}[0m"/utf8>>; off -> Text end. -file("src/distribute/log.gleam", 315). ?DOC(" Format metadata as key=value pairs\n"). -spec format_metadata(list({binary(), binary()})) -> binary(). format_metadata(Metadata) -> _pipe = Metadata, _pipe@1 = gleam@list:map( _pipe, fun(Pair) -> <<<<(erlang:element(1, Pair))/binary, "="/utf8>>/binary, (erlang:element(2, Pair))/binary>> end ), gleam@string:join(_pipe@1, <<", "/utf8>>). -file("src/distribute/log.gleam", 326). ?DOC(" Convert level to integer for comparison\n"). -spec level_to_int(level()) -> integer(). level_to_int(Level) -> case Level of debug -> 0; info -> 1; warn -> 2; error -> 3; off -> 4 end. -file("src/distribute/log.gleam", 338). ?DOC(" Get current timestamp (milliseconds since epoch)\n"). -spec get_timestamp() -> integer(). get_timestamp() -> erlang:system_time(1000). -file("src/distribute/log.gleam", 154). -spec fallback_correlation_id() -> binary(). fallback_correlation_id() -> Ts = get_timestamp(), Monotonic = erlang:monotonic_time(1000000), Seed = Monotonic rem 100000, <<<<<<"corr-"/utf8, (erlang:integer_to_binary(Ts))/binary>>/binary, "-"/utf8>>/binary, (erlang:integer_to_binary(Seed))/binary>>. -file("src/distribute/log.gleam", 167). ?DOC(" Disable all logging output (useful for tests)\n"). -spec disable_logging() -> nil. disable_logging() -> persistent_term:put(<<"distribute_log_disabled"/utf8>>, true). -file("src/distribute/log.gleam", 172). ?DOC(" Enable logging output\n"). -spec enable_logging() -> nil. enable_logging() -> persistent_term:put(<<"distribute_log_disabled"/utf8>>, false). -file("src/distribute/log.gleam", 206). ?DOC(" Check if logging is disabled\n"). -spec is_logging_disabled() -> boolean(). is_logging_disabled() -> persistent_term:get(<<"distribute_log_disabled"/utf8>>, false). -file("src/distribute/log.gleam", 184). ?DOC( " Set the minimum log level\n" " Messages below this level will not be logged\n" ). -spec set_level(level()) -> nil. set_level(Level) -> persistent_term:put(<<"distribute_log_level"/utf8>>, level_to_int(Level)). -file("src/distribute/log.gleam", 189). ?DOC(" Get the current minimum log level\n"). -spec get_level() -> level(). get_level() -> Level_int = persistent_term:get(<<"distribute_log_level"/utf8>>, 1), int_to_level(Level_int). -file("src/distribute/log.gleam", 211). ?DOC(" Check if a level should be logged based on current configuration\n"). -spec should_log(level()) -> boolean(). should_log(Level) -> case is_logging_disabled() of true -> false; false -> Current_level = get_level(), case Current_level of off -> false; _ -> level_to_int(Level) >= level_to_int(Current_level) end end. -file("src/distribute/log.gleam", 178). ?DOC( " Set the logging backend implementation used to handle output.\n" " Use \"console\" (default) or \"erlang_logger\".\n" ). -spec set_backend(binary()) -> nil. set_backend(Backend) -> logger_ffi:set_backend(Backend). -file("src/distribute/log.gleam", 138). ?DOC(" Generate a new correlation ID\n"). -spec generate_correlation_id() -> binary(). generate_correlation_id() -> case distribute@settings:is_use_crypto_ids() of true -> Res = crypto_ffi:rand_base64_safe(8), case crypto_ffi:is_ok(Res) of true -> V = erlang:element(2, Res), <<"corr-"/utf8, V/binary>>; false -> fallback_correlation_id() end; false -> fallback_correlation_id() end. -file("src/distribute/log.gleam", 283). ?DOC(" Format log level with optional colors\n"). -spec format_level(level()) -> binary(). format_level(Level) -> Level_str = case Level of debug -> <<"DEBUG"/utf8>>; info -> <<"INFO"/utf8>>; warn -> <<"WARN"/utf8>>; error -> <<"ERROR"/utf8>>; off -> <<"OFF"/utf8>> end, case erlang:element(3, {config, info, true, true}) of true -> colorize_level(Level, Level_str); false -> Level_str end. -file("src/distribute/log.gleam", 258). ?DOC(" Format a log entry as a string\n"). -spec format_log_entry(log_entry()) -> binary(). format_log_entry(Entry) -> {log_entry, Level, Message, Metadata, Correlation_id, Timestamp} = Entry, Level_str = format_level(Level), Timestamp_str = case erlang:element(4, {config, info, true, true}) of true -> <<<<"["/utf8, (erlang:integer_to_binary(Timestamp))/binary>>/binary, "] "/utf8>>; false -> <<""/utf8>> end, Correlation_str = case Correlation_id of {some, Id} -> <<<<"["/utf8, Id/binary>>/binary, "] "/utf8>>; none -> <<""/utf8>> end, Metadata_str = case Metadata of [] -> <<""/utf8>>; _ -> <<" "/utf8, (format_metadata(Metadata))/binary>> end, <<<<<<<<<>/binary, Level_str/binary>>/binary, ": "/utf8>>/binary, Message/binary>>/binary, Metadata_str/binary>>. -file("src/distribute/log.gleam", 229). ?DOC(" Output a log entry to the console\n"). -spec output_log_entry(log_entry()) -> nil. output_log_entry(Entry) -> Formatted = format_log_entry(Entry), {log_entry, Level, _, Metadata, Correlation_id, _} = Entry, Meta_str = case Metadata of [] -> <<""/utf8>>; _ -> format_metadata(Metadata) end, Meta_with_corr = case Correlation_id of {some, Id} -> case string:length(Meta_str) > 0 of true -> <<<<<<"corr="/utf8, Id/binary>>/binary, ","/utf8>>/binary, Meta_str/binary>>; false -> <<"corr="/utf8, Id/binary>> end; none -> Meta_str end, logger_ffi:log( level_to_name(Level), <>, Meta_with_corr ). -file("src/distribute/log.gleam", 110). ?DOC(" Core logging function\n"). -spec log( level(), binary(), list({binary(), binary()}), gleam@option:option(binary()) ) -> nil. log(Level, Message, Metadata, Correlation_id) -> case should_log(Level) of true -> Entry = {log_entry, Level, Message, Metadata, Correlation_id, get_timestamp()}, output_log_entry(Entry); false -> nil end. -file("src/distribute/log.gleam", 54). ?DOC(" Log a debug message\n"). -spec debug(binary(), list({binary(), binary()})) -> nil. debug(Message, Metadata) -> log(debug, Message, Metadata, none). -file("src/distribute/log.gleam", 59). ?DOC(" Log an info message\n"). -spec info(binary(), list({binary(), binary()})) -> nil. info(Message, Metadata) -> log(info, Message, Metadata, none). -file("src/distribute/log.gleam", 64). ?DOC(" Log a warning message\n"). -spec warn(binary(), list({binary(), binary()})) -> nil. warn(Message, Metadata) -> log(warn, Message, Metadata, none). -file("src/distribute/log.gleam", 69). ?DOC(" Log an error message\n"). -spec error(binary(), list({binary(), binary()})) -> nil. error(Message, Metadata) -> log(error, Message, Metadata, none). -file("src/distribute/log.gleam", 74). ?DOC(" Log a debug message with correlation ID\n"). -spec debug_with_correlation(binary(), list({binary(), binary()}), binary()) -> nil. debug_with_correlation(Message, Metadata, Correlation_id) -> log(debug, Message, Metadata, {some, Correlation_id}). -file("src/distribute/log.gleam", 83). ?DOC(" Log an info message with correlation ID\n"). -spec info_with_correlation(binary(), list({binary(), binary()}), binary()) -> nil. info_with_correlation(Message, Metadata, Correlation_id) -> log(info, Message, Metadata, {some, Correlation_id}). -file("src/distribute/log.gleam", 92). ?DOC(" Log a warning message with correlation ID\n"). -spec warn_with_correlation(binary(), list({binary(), binary()}), binary()) -> nil. warn_with_correlation(Message, Metadata, Correlation_id) -> log(warn, Message, Metadata, {some, Correlation_id}). -file("src/distribute/log.gleam", 101). ?DOC(" Log an error message with correlation ID\n"). -spec error_with_correlation(binary(), list({binary(), binary()}), binary()) -> nil. error_with_correlation(Message, Metadata, Correlation_id) -> log(error, Message, Metadata, {some, Correlation_id}).