Permalink
Browse files

Add 'duration' metric as an extension of histogram

  • Loading branch information...
1 parent 16e0924 commit 295ad8a6271b7e550d9b7323371059aa496ada78 @russelldb russelldb committed May 18, 2012
Showing with 119 additions and 1 deletion.
  1. +1 −0 include/folsom.hrl
  2. +25 −0 src/folsom_ets.erl
  3. +16 −0 src/folsom_metrics.erl
  4. +75 −0 src/folsom_metrics_duration.erl
  5. +2 −1 src/folsom_sup.erl
View
@@ -5,6 +5,7 @@
-define(METER_TABLE, folsom_meters).
-define(METER_READER_TABLE, folsom_meter_readers).
-define(HISTORY_TABLE, folsom_histories).
+-define(DURATION_TABLE, folsom_durations).
-define(DEFAULT_LIMIT, 5).
-define(DEFAULT_SIZE, 1028). % mimic codahale's metrics
View
@@ -138,6 +138,8 @@ get_values(Name, meter) ->
folsom_metrics_meter:get_values(Name);
get_values(Name, meter_reader) ->
folsom_metrics_meter_reader:get_values(Name);
+get_values(Name, duration) ->
+ folsom_metrics_duration:get_values(Name);
get_values(_, Type) ->
{error, Type, unsupported_metric_type}.
@@ -160,6 +162,11 @@ maybe_add_handler(histogram, Name, false) ->
true = folsom_metrics_histogram:new(Name),
true = ets:insert(?FOLSOM_TABLE, {Name, #metric{type = histogram}}),
ok;
+maybe_add_handler(duration, Name, false) ->
+ true = folsom_metrics_histogram:new(Name),
+ true = folsom_metrics_duration:new(Name),
+ true = ets:insert(?FOLSOM_TABLE, {Name, #metric{type = duration}}),
+ ok;
maybe_add_handler(history, Name, false) ->
ok = folsom_metrics_history:new(Name),
true = ets:insert(?FOLSOM_TABLE, {Name, #metric{type = history, history_size = ?DEFAULT_SIZE}}),
@@ -205,6 +212,11 @@ maybe_add_handler(histogram, Name, SampleType, SampleSize, Alpha, false) ->
true = folsom_metrics_histogram:new(Name, SampleType, SampleSize, Alpha),
true = ets:insert(?FOLSOM_TABLE, {Name, #metric{type = histogram}}),
ok;
+maybe_add_handler(duration, Name, SampleType, SampleSize, Alpha, false) ->
+ true = folsom_metrics_histogram:new(Name, SampleType, SampleSize, Alpha),
+ true = folsom_metrics_duration:new(Name),
+ true = ets:insert(?FOLSOM_TABLE, {Name, #metric{type = duration}}),
+ ok;
maybe_add_handler(Type, _, _, _, _, false) ->
{error, Type, unsupported_metric_type};
maybe_add_handler(_, Name, _, _, _, true) ->
@@ -218,6 +230,12 @@ delete_metric(Name, histogram) ->
Metric = folsom_metrics_histogram:get_value(Name),
ok = delete_histogram(Name, Metric),
ok;
+delete_metric(Name, duration) ->
+ Histo = folsom_metrics_histogram:get_value(Name),
+ ok = delete_histogram(Name, Histo),
+ true = ets:delete(?DURATION_TABLE, Name),
+ true = ets:delete(?FOLSOM_TABLE, Name),
+ ok;
delete_metric(Name, counter) ->
true = ets:delete(?COUNTER_TABLE, Name),
true = ets:delete(?FOLSOM_TABLE, Name),
@@ -307,6 +325,13 @@ notify(Name, Value, meter_reader, false) ->
add_handler(meter, Name),
folsom_metrics_meter_reader:mark(Name, Value),
ok;
+notify(Name, Value, duration, true) ->
+ folsom_metrics_duration:update(Name, Value),
+ ok;
+notify(Name, Value, duration, false) ->
+ add_handler(duration, Name),
+ folsom_metrics_duration:update(Name, Value),
+ ok;
notify(_, _, Type, _) ->
{error, Type, unsupported_metric_type}.
View
@@ -35,6 +35,10 @@
new_history/2,
new_meter/1,
new_meter_reader/1,
+ new_duration/1,
+ new_duration/2,
+ new_duration/3,
+ new_duration/4,
delete_metric/1,
notify/1,
notify/2,
@@ -87,6 +91,18 @@ new_meter(Name) ->
new_meter_reader(Name) ->
folsom_ets:add_handler(meter_reader, Name).
+new_duration(Name) ->
+ folsom_metrics:new_duration(Name, ?DEFAULT_SAMPLE_TYPE, ?DEFAULT_SIZE, ?DEFAULT_ALPHA).
+
+new_duration(Name, SampleType) ->
+ folsom_metrics:new_duration(Name, SampleType, ?DEFAULT_SIZE, ?DEFAULT_ALPHA).
+
+new_duration(Name, SampleType, SampleSize) ->
+ folsom_metrics:new_duration(Name, SampleType, SampleSize, ?DEFAULT_ALPHA).
+
+new_duration(Name, SampleType, SampleSize, Alpha) ->
+ folsom_ets:add_handler(duration, Name, SampleType, SampleSize, Alpha).
+
delete_metric(Name) ->
folsom_ets:delete_handler(Name).
@@ -0,0 +1,75 @@
+%% -------------------------------------------------------------------
+%%
+%% Copyright (c) 2007-2012 Basho Technologies, Inc. All Rights Reserved.
+%%
+%% This file is provided to you under the Apache License,
+%% Version 2.0 (the "License"); you may not use this file
+%% except in compliance with the License. You may obtain
+%% a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing,
+%% software distributed under the License is distributed on an
+%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+%% KIND, either express or implied. See the License for the
+%% specific language governing permissions and limitations
+%% under the License.
+%%
+%% -------------------------------------------------------------------
+
+%%%-------------------------------------------------------------------
+%%% File: folsom_metrics_duration.erl
+%%% @author Russell Brown <russelldb@basho.com>
+%%% @doc Tracks the time something takes. If
+%%% you can, use folsom_metrics:histogram_timed_update/2,3,4.
+%%% This is for the case when you can't wrap your timed action
+%%% in a fun. Calling timer_start / timer_end in the correct
+%%% order is the calling code's responsibility.
+%%% @end
+%%%------------------------------------------------------------------
+
+-module(folsom_metrics_duration).
+
+-export([new/1,
+ update/2,
+ get_value/1,
+ get_values/1
+ ]).
+
+-include("folsom.hrl").
+
+new(Name) ->
+ %% {Name, count, start, last}
+ Dur = {Name, 0, undefined, 0},
+ ets:insert(?DURATION_TABLE, Dur).
+
+update(Name, timer_start) ->
+ StartTime = erlang:now(),
+ ets:update_element(?DURATION_TABLE, Name, {3, StartTime});
+update(Name, timer_end) ->
+ EndTime = erlang:now(),
+ case ets:lookup_element(?DURATION_TABLE, Name, 3) of
+ undefined ->
+ ok;
+ StartTime ->
+ %% potential race, but then you're using it wrong
+ ets:update_element(?DURATION_TABLE, Name, {3, undefined}),
+ Duration = timer:now_diff(EndTime, StartTime),
+ ets:update_counter(?DURATION_TABLE, Name, {2, 1}),
+ ets:update_element(?DURATION_TABLE, Name, {4, Duration}),
+ folsom_metrics_histogram:update(Name, Duration)
+ end.
+
+% gets the duration tuple from ets
+get_value(Name) ->
+ [Dur] = ets:lookup(?DURATION_TABLE, Name),
+ Dur.
+
+% pulls the sample out of the record gotten from ets
+% and the duration
+get_values(Name) ->
+ Values = folsom_metrics_histogram:get_values(Name),
+ {Name, Cnt, _Start, Last} = get_value(Name),
+ Stats = bear:get_statistics(Values),
+ [{count, Cnt}, {last, Last} | Stats].
View
@@ -103,7 +103,8 @@ create_tables() ->
{?HISTOGRAM_TABLE, [set, named_table, public, {write_concurrency, true}]},
{?METER_TABLE, [set, named_table, public, {write_concurrency, true}]},
{?METER_READER_TABLE, [set, named_table, public, {write_concurrency, true}]},
- {?HISTORY_TABLE, [set, named_table, public, {write_concurrency, true}]}
+ {?HISTORY_TABLE, [set, named_table, public, {write_concurrency, true}]},
+ {?DURATION_TABLE, [ordered_set, named_table, public, {write_concurrency, true}]}
],
[maybe_create_table(ets:info(Name), Name, Opts) || {Name, Opts} <- Tables],
ok.

0 comments on commit 295ad8a

Please sign in to comment.