<commit_before>-module(prometheus_text_format).
-export([content_type/0,
         format/0,
         format/1,
         registry_collect_callback/3,
         collector_metrics_callback/5]).

-ifdef(TEST).
-export([escape_metric_help/1,
         escape_label_value/1]).
-endif.

-include("prometheus.hrl").

-behaviour(prometheus_format).

content_type() ->
  <<"text/plain; version=0.0.4">>.

format() ->
  format(default).

format(Registry) ->
  {ok, Fd} = ram_file:open("", [write,read,binary]),
  prometheus_registry:collect(Registry, fun (_, Collector) ->
                                            registry_collect_callback(Fd, Registry, Collector)
                                        end),
  file:write(Fd, io_lib:format("\n", [])),
  {ok, Size} = ram_file:get_size(Fd),
  {ok, Str} = file:pread(Fd, 0, Size),
  ok = file:close(Fd),
  Str.

emit_mf_prologue(Fd, Type, Name, Help) ->
  file:write(Fd, io_lib:format("# TYPE ~s ~s\n# HELP ~s ~s\n", [Name, Type, Name, escape_metric_help(Help)])).

registry_collect_callback(Fd, Registry, Collector) ->
  Collector:collect_mf(
    fun (Type, MFName, Labels, Help, MFData) ->
        emit_mf_prologue(Fd, Type, MFName, Help),
        Collector:collect_metrics(MFName,
                                  fun (Series, Value) ->
                                      case Series of
                                        {Name, LabelValues} ->
                                          collector_metrics_callback(Fd, Name, Labels, LabelValues, Value);
                                        {Name, NewLabels, LabelValues} ->
                                          collector_metrics_callback(Fd, Name, Labels ++ NewLabels, LabelValues, Value);
                                        LabelValues ->
                                          collector_metrics_callback(Fd, MFName, Labels, LabelValues, Value)
                                      end
                                  end,
                                  MFData)
    end,
    Registry).

labels_string(Labels, LabelValues) ->
  case length(Labels) of
    0 ->
      "";
    _ ->
      LabelsPList = lists:zip(Labels, LabelValues),
      "{" ++ string:join(lists:map(fun ({Label, Value1}) ->
                                       io_lib:format("~s=\"~s\"", [Label, escape_label_value(Value1)])
                                   end,
                                   LabelsPList),
                         ",") ++ "}"
  end.


collector_metrics_callback(Fd, Name, Labels, LabelValues, '') ->
  LString = labels_string(Labels, LabelValues),
  file:write(Fd, io_lib:format("~s" ++ LString ++ " NaN\n", [Name]));
collector_metrics_callback(Fd, Name, Labels, LabelValues, undefined) ->
  LString = labels_string(Labels, LabelValues),
  file:write(Fd, io_lib:format("~s" ++ LString ++ " NaN\n", [Name]));
collector_metrics_callback(Fd, Name, Labels, LabelValues, Value) ->
  LString = labels_string(Labels, LabelValues),
  file:write(Fd, io_lib:format("~s" ++ LString ++ " ~p\n", [Name, Value])).

escape_metric_help(Help) ->
  sub(sub(Help, "\\", "\\\\\\\\"), "\n", "\\\\n").

escape_label_value(LValue) when is_list(LValue)->
  sub(sub(sub(LValue, "\\", "\\\\\\\\"), "\n", "\\\\n"), "\"", "\\\\\"");
escape_label_value('+Inf') ->
  "+Inf";
escape_label_value(LValue) ->
  escape_label_value(io_lib:format("~p", [LValue])).

sub(Str, Old, New) when is_atom(Str) ->
  sub(atom_to_list(Str), Old, New);
sub(Str,Old,New) ->
  RegExp = "\\Q"++Old++"\\E",
  re:replace(Str,RegExp,New,[global, {return, list}]).
<commit_msg>convert binary label values to lists<commit_after>-module(prometheus_text_format).
-export([content_type/0,
         format/0,
         format/1,
         registry_collect_callback/3,
         collector_metrics_callback/5]).

-ifdef(TEST).
-export([escape_metric_help/1,
         escape_label_value/1]).
-endif.

-include("prometheus.hrl").

-behaviour(prometheus_format).

content_type() ->
  <<"text/plain; version=0.0.4">>.

format() ->
  format(default).

format(Registry) ->
  {ok, Fd} = ram_file:open("", [write,read,binary]),
  prometheus_registry:collect(Registry, fun (_, Collector) ->
                                            registry_collect_callback(Fd, Registry, Collector)
                                        end),
  file:write(Fd, io_lib:format("\n", [])),
  {ok, Size} = ram_file:get_size(Fd),
  {ok, Str} = file:pread(Fd, 0, Size),
  ok = file:close(Fd),
  Str.

emit_mf_prologue(Fd, Type, Name, Help) ->
  file:write(Fd, io_lib:format("# TYPE ~s ~s\n# HELP ~s ~s\n", [Name, Type, Name, escape_metric_help(Help)])).

registry_collect_callback(Fd, Registry, Collector) ->
  Collector:collect_mf(
    fun (Type, MFName, Labels, Help, MFData) ->
        emit_mf_prologue(Fd, Type, MFName, Help),
        Collector:collect_metrics(MFName,
                                  fun (Series, Value) ->
                                      case Series of
                                        {Name, LabelValues} ->
                                          collector_metrics_callback(Fd, Name, Labels, LabelValues, Value);
                                        {Name, NewLabels, LabelValues} ->
                                          collector_metrics_callback(Fd, Name, Labels ++ NewLabels, LabelValues, Value);
                                        LabelValues ->
                                          collector_metrics_callback(Fd, MFName, Labels, LabelValues, Value)
                                      end
                                  end,
                                  MFData)
    end,
    Registry).

labels_string(Labels, LabelValues) ->
  case length(Labels) of
    0 ->
      "";
    _ ->
      LabelsPList = lists:zip(Labels, LabelValues),
      "{" ++ string:join(lists:map(fun ({Label, Value1}) ->
                                       io_lib:format("~s=\"~s\"", [Label, escape_label_value(Value1)])
                                   end,
                                   LabelsPList),
                         ",") ++ "}"
  end.


collector_metrics_callback(Fd, Name, Labels, LabelValues, '') ->
  LString = labels_string(Labels, LabelValues),
  file:write(Fd, io_lib:format("~s" ++ LString ++ " NaN\n", [Name]));
collector_metrics_callback(Fd, Name, Labels, LabelValues, undefined) ->
  LString = labels_string(Labels, LabelValues),
  file:write(Fd, io_lib:format("~s" ++ LString ++ " NaN\n", [Name]));
collector_metrics_callback(Fd, Name, Labels, LabelValues, Value) ->
  LString = labels_string(Labels, LabelValues),
  file:write(Fd, io_lib:format("~s" ++ LString ++ " ~p\n", [Name, Value])).

escape_metric_help(Help) ->
  sub(sub(Help, "\\", "\\\\\\\\"), "\n", "\\\\n").

escape_label_value(LValue) when is_list(LValue)->
  sub(sub(sub(LValue, "\\", "\\\\\\\\"), "\n", "\\\\n"), "\"", "\\\\\"");
escape_label_value(LValue) when is_binary(LValue) ->
  escape_label_value(binary_to_list(LValue));
escape_label_value('+Inf') ->
  "+Inf";
escape_label_value(LValue) ->
  escape_label_value(io_lib:format("~p", [LValue])).


sub(Str, Old, New) when is_atom(Str) ->
  sub(atom_to_list(Str), Old, New);
sub(Str,Old,New) ->
  RegExp = "\\Q"++Old++"\\E",
  re:replace(Str,RegExp,New,[global, {return, list}]).

{'fraction_non_alphanumeric': 0.1634041371650701, 'fraction_numerical': 0.003887269193391642, 'mean_word_length': 2.074690567648314, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 56, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 42, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6873386', 'n_tokens_mistral': 2317, 'n_tokens_neox': 2229, 'n_words': 393}