<commit_before>-module(estatsd_folsom).
-behaviour(gen_server).
-define(SERVER, ?MODULE).

-define(ALL_METRICS, all_metrics_keys).
-include_lib("folsom/include/folsom.hrl").

%-include_lib("eunit/include/eunit.hrl").

%% ------------------------------------------------------------------
%% API Function Exports
%% ------------------------------------------------------------------

-export([start_link/0, ensure_metric/2]).

%% ------------------------------------------------------------------
%% gen_server Function Exports
%% ------------------------------------------------------------------

-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
         code_change/3]).

%% ------------------------------------------------------------------
%% API Function Definitions
%% ------------------------------------------------------------------

start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

ensure_metric(Key, Type) ->
    {Table, Fun} = table_for_type(Type),
    gen_server:call(?SERVER, {ensure_metric, Key, Type, Table, Fun}).

%% ------------------------------------------------------------------
%% gen_server Function Definitions
%% ------------------------------------------------------------------
init([]) ->
    ets:new(?ALL_METRICS, [set, named_table, public]),
    {ok, undefined}.

handle_call({ensure_metric, Key, Type, Table, Fun}, _From, State) ->
    Status = case ets:member(?ALL_METRICS, {Key, Table}) of
                 true ->
                     already_exists;
                 false ->
                     folsom_metrics:Fun(Key),
                     ets:insert(?ALL_METRICS, {{Key, Table}, true}),
                     error_logger:info_msg("created|~p|~p|~p~n",
                                           [{Key, Table}, Fun, Type]),
                    created
            end,
    {reply, {ok, Status}, State};
handle_call(_Request, _From, State) ->
    {noreply, ok, State}.

handle_cast(_Msg, State) ->
    {noreply, State}.

handle_info(_Msg, State) ->
    {noreply, State}.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.

%% ------------------------------------------------------------------
%% Internal Function Definitions
%% ------------------------------------------------------------------

table_for_type(Type) when Type =:= <<"d">> orelse Type =:= <<"c">> ->
    {?COUNTER_TABLE, new_counter};
table_for_type(Type) when Type =:= <<"ms">> orelse Type =:= <<"h">> ->
    {?HISTOGRAM_TABLE, new_histogram};
table_for_type(<<"e">>) ->
    {?HISTORY_TABLE, new_history};
table_for_type(<<"g">>) ->
    {?GAUGE_TABLE, new_gauge};
table_for_type(<<"m">>) ->
    {?METER_TABLE, new_meter};
table_for_type(BadType) ->
    erlang:error({error, {bad_type, BadType}}).
<commit_msg>Treat "c" type as meter; add "mr" meter_reader support<commit_after>-module(estatsd_folsom).
-behaviour(gen_server).
-define(SERVER, ?MODULE).

-define(ALL_METRICS, all_metrics_keys).
-include_lib("folsom/include/folsom.hrl").

%-include_lib("eunit/include/eunit.hrl").

%% ------------------------------------------------------------------
%% API Function Exports
%% ------------------------------------------------------------------

-export([start_link/0, ensure_metric/2]).

%% ------------------------------------------------------------------
%% gen_server Function Exports
%% ------------------------------------------------------------------

-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
         code_change/3]).

%% ------------------------------------------------------------------
%% API Function Definitions
%% ------------------------------------------------------------------

start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

ensure_metric(Key, Type) ->
    {Table, Fun} = table_for_type(Type),
    gen_server:call(?SERVER, {ensure_metric, Key, Type, Table, Fun}).

%% ------------------------------------------------------------------
%% gen_server Function Definitions
%% ------------------------------------------------------------------
init([]) ->
    ets:new(?ALL_METRICS, [set, named_table, public]),
    {ok, undefined}.

handle_call({ensure_metric, Key, Type, Table, Fun}, _From, State) ->
    Status = case ets:member(?ALL_METRICS, {Key, Table}) of
                 true ->
                     already_exists;
                 false ->
                     folsom_metrics:Fun(Key),
                     ets:insert(?ALL_METRICS, {{Key, Table}, true}),
                     error_logger:info_msg("created|~p|~p|~p~n",
                                           [{Key, Table}, Fun, Type]),
                    created
            end,
    {reply, {ok, Status}, State};
handle_call(_Request, _From, State) ->
    {noreply, ok, State}.

handle_cast(_Msg, State) ->
    {noreply, State}.

handle_info(_Msg, State) ->
    {noreply, State}.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.

%% ------------------------------------------------------------------
%% Internal Function Definitions
%% ------------------------------------------------------------------

table_for_type(Type) when Type =:= <<"d">> orelse Type =:= <<"i">> ->
    {?COUNTER_TABLE, new_counter};
table_for_type(Type) when Type =:= <<"ms">> orelse Type =:= <<"h">> ->
    {?HISTOGRAM_TABLE, new_histogram};
table_for_type(<<"e">>) ->
    {?HISTORY_TABLE, new_history};
table_for_type(<<"g">>) ->
    {?GAUGE_TABLE, new_gauge};
table_for_type(Type) when Type =:= <<"m">> orelse Type =:= <<"c">> ->
    % we treat our current "c" as a meter because it is essentially
    % request count so treating as a meter will give us req/s data.
    {?METER_TABLE, new_meter};
table_for_type(<<"mr">>) ->
    {?METER_READER_TABLE, new_meter_reader};
table_for_type(BadType) ->
    erlang:error({error, {bad_type, BadType}}).

{'fraction_non_alphanumeric': 0.3610595579551206, 'fraction_numerical': 0.0026995107136831447, 'mean_word_length': 1.4176182707993474, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 70, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4022458', 'n_tokens_mistral': 1683, 'n_tokens_neox': 1630, 'n_words': 317}