-module(internal@metric@histogram). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([init_record/2, observe/3, delete_record/2, print/2, new_name/1, new/3]). -export_type([histogram/0, histogram_record/0, histogram_error/0]). -type histogram() :: any(). -type histogram_record() :: {histogram_record, themis@number:number_(), themis@number:number_(), gleam@dict:dict(themis@number:number_(), themis@number:number_())}. -type histogram_error() :: invalid_na_n_label | {number_error, themis@number:comparison_error()} | {metric_error, internal@metric:metric_error()}. -file("/git/Themis/src/internal/metric/histogram.gleam", 58). -spec new_record( internal@metric:metric(histogram(), histogram_record(), gleam@set:set(themis@number:number_())) ) -> histogram_record(). new_record(To) -> Keys = begin _pipe = erlang:element(4, To), _pipe@1 = gleam@set:insert(_pipe, pos_inf), gleam@set:to_list(_pipe@1) end, Values = gleam@list:repeat(themis@number:int(0), erlang:length(Keys)), Buckets = begin _pipe@2 = gleam@list:zip(Keys, Values), maps:from_list(_pipe@2) end, {histogram_record, themis@number:int(0), themis@number:int(0), Buckets}. -file("/git/Themis/src/internal/metric/histogram.gleam", 50). -spec init_record( internal@metric:metric(histogram(), histogram_record(), gleam@set:set(themis@number:number_())), internal@label:label_set() ) -> internal@metric:metric(histogram(), histogram_record(), gleam@set:set(themis@number:number_())). init_record(To, Labels) -> Record = new_record(To), erlang:setelement( 3, To, gleam@dict:insert(erlang:element(3, To), Labels, Record) ). -file("/git/Themis/src/internal/metric/histogram.gleam", 71). -spec observe( internal@metric:metric(histogram(), histogram_record(), gleam@set:set(themis@number:number_())), internal@label:label_set(), themis@number:number_() ) -> internal@metric:metric(histogram(), histogram_record(), gleam@set:set(themis@number:number_())). observe(To, Labels, Value) -> Record = gleam@result:unwrap( gleam_stdlib:map_get(erlang:element(3, To), Labels), new_record(To) ), Updated_buckets_list = (gleam@list:map( begin _pipe = erlang:element(4, Record), maps:to_list(_pipe) end, fun(_use0) -> {Le, Bucket_count} = _use0, case themis@number:compare(Value, Le) of {error, _} -> erlang:error(#{gleam_error => panic, message => <<"found NaN bucket boundary"/utf8>>, module => <<"internal/metric/histogram"/utf8>>, function => <<"observe"/utf8>>, line => 82}); {ok, lt} -> {Le, themis@number:add(Bucket_count, themis@number:int(1))}; {ok, eq} -> {Le, themis@number:add(Bucket_count, themis@number:int(1))}; {ok, gt} -> {Le, Bucket_count} end end )), Updated_buckets = maps:from_list(Updated_buckets_list), New_record = {histogram_record, themis@number:add(erlang:element(2, Record), themis@number:int(1)), themis@number:add(erlang:element(3, Record), Value), Updated_buckets}, erlang:setelement( 3, To, gleam@dict:insert(erlang:element(3, To), Labels, New_record) ). -file("/git/Themis/src/internal/metric/histogram.gleam", 101). -spec delete_record( internal@metric:metric(histogram(), histogram_record(), gleam@set:set(themis@number:number_())), internal@label:label_set() ) -> internal@metric:metric(histogram(), histogram_record(), gleam@set:set(themis@number:number_())). delete_record(From, Labels) -> erlang:setelement( 3, From, gleam@dict:delete(erlang:element(3, From), Labels) ). -file("/git/Themis/src/internal/metric/histogram.gleam", 164). -spec print_bucket( binary(), internal@label:label_set(), themis@number:number_(), themis@number:number_() ) -> binary(). print_bucket(Name, Labels, Le, Count) -> Label_string = begin _pipe = internal@label:add_label( Labels, <<"le"/utf8>>, themis@number:print(Le) ), _pipe@1 = gleam@result:lazy_unwrap( _pipe, fun() -> erlang:error(#{gleam_error => panic, message => <<"`le` could not be added as a label"/utf8>>, module => <<"internal/metric/histogram"/utf8>>, function => <<"print_bucket"/utf8>>, line => 172}) end ), internal@label:print(_pipe@1) end, <<<<<<<<<>/binary, Label_string/binary>>/binary, " "/utf8>>/binary, (themis@number:print(Count))/binary>>/binary, "\n"/utf8>>. -file("/git/Themis/src/internal/metric/histogram.gleam", 126). -spec print_histogram_record( binary(), internal@label:label_set(), histogram_record() ) -> binary(). print_histogram_record(Name, Labels, Record) -> Count_line = <<<<<<<<<>/binary, (internal@label:print(Labels))/binary>>/binary, " "/utf8>>/binary, (themis@number:print(erlang:element(2, Record)))/binary>>/binary, "\n"/utf8>>, Sum_line = <<<<<<<<<>/binary, (internal@label:print(Labels))/binary>>/binary, " "/utf8>>/binary, (themis@number:print(erlang:element(2, Record)))/binary>>/binary, "\n"/utf8>>, Bucket_lines = begin _pipe = erlang:element(4, Record), _pipe@1 = maps:to_list(_pipe), _pipe@2 = gleam@list:sort( _pipe@1, fun(Bucket1, Bucket2) -> {Le1, _} = Bucket1, {Le2, _} = Bucket2, gleam@result:lazy_unwrap( themis@number:compare(Le1, Le2), fun() -> erlang:error(#{gleam_error => panic, message => <<"`le` values comparison failed, one of them is NaN"/utf8>>, module => <<"internal/metric/histogram"/utf8>>, function => <<"print_histogram_record"/utf8>>, line => 152}) end ) end ), gleam@list:map( _pipe@2, fun(Bucket) -> {Le, Count} = Bucket, print_bucket(Name, Labels, Le, Count) end ) end, _pipe@3 = lists:append(Bucket_lines, [Sum_line, Count_line]), _pipe@4 = gleam_stdlib:identity(_pipe@3), unicode:characters_to_binary(_pipe@4). -file("/git/Themis/src/internal/metric/histogram.gleam", 108). -spec print( internal@metric:metric(histogram(), histogram_record(), gleam@set:set(themis@number:number_())), internal@metric:metric_name() ) -> binary(). print(Metric, Name) -> Name@1 = internal@metric:name_to_string(Name), Help = <<<<<<"# HELP "/utf8, Name@1/binary>>/binary, " "/utf8>>/binary, (erlang:element(2, Metric))/binary>>, Type_ = <<<<"# TYPE "/utf8, Name@1/binary>>/binary, " histogram"/utf8>>, _pipe = (gleam@dict:fold( erlang:element(3, Metric), [<<<<<>/binary, Type_/binary>>/binary, "\n"/utf8>>], fun(Current, Labels, Record) -> [<<(print_histogram_record(Name@1, Labels, Record))/binary, "\n"/utf8>> | Current] end )), _pipe@1 = lists:reverse(_pipe), _pipe@2 = gleam_stdlib:identity(_pipe@1), unicode:characters_to_binary(_pipe@2). -file("/git/Themis/src/internal/metric/histogram.gleam", 177). -spec new_name(binary()) -> {ok, internal@metric:metric_name()} | {error, internal@metric:metric_error()}. new_name(Name) -> _pipe = Name, internal@metric:new_name(_pipe, [<<"histogram"/utf8>>]). -file("/git/Themis/src/internal/metric/histogram.gleam", 26). -spec new(binary(), binary(), gleam@set:set(themis@number:number_())) -> {ok, {internal@metric:metric_name(), internal@metric:metric(histogram(), histogram_record(), gleam@set:set(themis@number:number_()))}} | {error, histogram_error()}. new(Name, Description, Buckets) -> R = begin _pipe = Name, _pipe@1 = new_name(_pipe), gleam@result:try_recover( _pipe@1, fun(E) -> {error, {metric_error, E}} end ) end, gleam@result:'try'( R, fun(Name@1) -> R@1 = (gleam@list:any( begin _pipe@2 = Buckets, gleam@set:to_list(_pipe@2) end, fun(Key) -> Key =:= na_n end )), gleam@bool:guard( R@1, {error, invalid_na_n_label}, fun() -> {ok, {Name@1, {metric, Description, maps:new(), Buckets}}} end ) end ).