Added grouped/tagged metrics feature
diff --git a/README.md b/README.md
index 6d60521..25f2a0b 100644
--- a/README.md
+++ b/README.md
@@ -141,6 +141,23 @@
       > folsom_metrics:new_meter_reader(Name).
       > folsom_metrics:notify({Name, Value}).
 
+##### Metrics groups/tags
+
+Certain users might want to group and query metrics monitoring a common task. In order to do so, they can
+tag metrics:
+
+    > folsom_metrics:tag_metric(Name, Tag).
+
+and query a list of tuples `[{Name, Value}]` of all metrics with a given tag:
+
+    > folsom_metrics:get_metrics_value(Tag).
+
+If only a certain type of metrics from a given group is desired, one can specify so:
+
+    > folsom_metrics:get_metrics_value(Tag, Type).
+
+where Type is one of `counter`, `gauge`, `histogram`, `history`, `meter`, `meter_reader`, `duration` or `spiral`.
+
 ##### Erlang VM
 
 folsom also produces Erlang VM statistics.
diff --git a/src/folsom_ets.erl b/src/folsom_ets.erl
index 2e6eb5e..de3b9e5 100644
--- a/src/folsom_ets.erl
+++ b/src/folsom_ets.erl
@@ -29,6 +29,7 @@
          add_handler/3,
          add_handler/4,
          add_handler/5,
+         tag_handler/2,
          delete_handler/1,
          handler_exists/1,
          notify/1,
@@ -39,11 +40,13 @@
          get_handlers_info/0,
          get_info/1,
          get_values/1,
-         get_history_values/2
+         get_history_values/2,
+         get_group_values/1,
+         get_group_values/2
         ]).
 
 -record(metric, {
-          tags = [],
+          tags = sets:new(),
           type,
           history_size
          }).
@@ -66,6 +69,14 @@
 add_handler(Type, Name, SampleType, SampleSize, Alpha) ->
     maybe_add_handler(Type, Name, SampleType, SampleSize, Alpha, handler_exists(Name)).
 
+tag_handler(Name, Tag) ->
+    case handler_exists(Name) of
+        true ->
+            add_tag(Name, Tag);
+        false ->
+            {error, Name, nonexistent_metric}
+    end.
+
 delete_handler(Name) ->
     {_, Info} = get_info(Name),
     ok = delete_metric(Name, proplists:get_value(type, Info)).
@@ -148,6 +159,12 @@
 get_history_values(Name, Count) ->
     folsom_metrics_history:get_events(Name, Count).
 
+get_group_values(Tag) ->
+    [{Name, get_values(Name)} || Name <- get_handlers(), has_tag(Name, Tag)].
+
+get_group_values(Tag, Type) ->
+    [{Name, get_values(Name)} || Name <- get_handlers(), has_tag(Name, Tag), has_type(Name, Type)].
+
 %%%===================================================================
 %%% Internal functions
 %%%===================================================================
@@ -228,6 +245,22 @@
 maybe_add_handler(_, Name, _, _, _, true) ->
     {error, Name, metric_already_exists}.
 
+add_tag(Name, Tag) ->
+    OldMetric = ets:lookup_element(?FOLSOM_TABLE, Name, 2),
+    NewMetric = OldMetric#metric{tags=sets:add_element(Tag, get_tags(Name))},
+    true = ets:update_element(?FOLSOM_TABLE, Name, {2, NewMetric}),
+    ok.
+
+get_tags(Name) ->
+    Metric = ets:lookup_element(?FOLSOM_TABLE, Name, 2),
+    Metric#metric.tags.
+
+has_tag(Name, Tag) ->
+    sets:is_element(Tag, get_tags(Name)).
+
+has_type(Name, Type) ->
+    {Name, [{type, Type}]} =:= get_info(Name).
+
 delete_metric(Name, history) ->
     History = folsom_metrics_history:get_value(Name),
     ok = delete_history(Name, History),
diff --git a/src/folsom_metrics.erl b/src/folsom_metrics.erl
index 7ab858f..73565cb 100644
--- a/src/folsom_metrics.erl
+++ b/src/folsom_metrics.erl
@@ -41,6 +41,7 @@
          new_duration/4,
          new_spiral/1,
          delete_metric/1,
+         tag_metric/2,
          notify/1,
          notify/2,
          notify/3,
@@ -51,6 +52,8 @@
          get_metrics/0,
          metric_exists/1,
          get_metrics_info/0,
+         get_metrics_value/1,
+         get_metrics_value/2,
          get_metric_info/1,
          get_metric_value/1,
          get_histogram_statistics/1,
@@ -112,6 +115,9 @@
 new_spiral(Name) ->
     folsom_ets:add_handler(spiral, Name).
 
+tag_metric(Name, Tag) ->
+    folsom_ets:tag_handler(Name, Tag).
+
 delete_metric(Name) ->
     folsom_ets:delete_handler(Name).
 
@@ -145,6 +151,12 @@
 get_metrics_info() ->
     folsom_ets:get_handlers_info().
 
+get_metrics_value(Tag) ->
+    folsom_ets:get_group_values(Tag).
+
+get_metrics_value(Tag, Type) ->
+    folsom_ets:get_group_values(Tag, Type).
+
 get_metric_info(Name) ->
     [folsom_ets:get_info(Name)].
 
diff --git a/test/folsom_erlang_checks.erl b/test/folsom_erlang_checks.erl
index 6eab9bc..e0c0cfd 100644
--- a/test/folsom_erlang_checks.erl
+++ b/test/folsom_erlang_checks.erl
@@ -29,7 +29,9 @@
 -export([
          create_metrics/0,
          populate_metrics/0,
+         tag_metrics/0,
          check_metrics/0,
+         check_group_metrics/0,
          delete_metrics/0,
          vm_metrics/0,
          counter_metric/2,
@@ -87,6 +89,15 @@
 
     ?debugFmt("~n~nmetrics: ~p~n", [folsom_metrics:get_metrics()]).
 
+tag_metrics() ->
+    Group = "mygroup",
+    ok = folsom_metrics:tag_metric(counter, Group),
+    ok = folsom_metrics:tag_metric(counter2, Group),
+    ok = folsom_metrics:tag_metric(<<"gauge">>, Group),
+    ok = folsom_metrics:tag_metric(meter, Group),
+    ok = folsom_metrics:tag_metric(spiral, Group),
+    ?debugFmt("~n~ntagged metrics: ~p, ~p, ~p, ~p and ~p in group ~p~n", [counter,counter2,<<"gauge">>,meter,spiral,Group]).
+
 populate_metrics() ->
     ok = folsom_metrics:notify({counter, {inc, 1}}),
     ok = folsom_metrics:notify({counter, {dec, 1}}),
@@ -229,6 +240,32 @@
     %% check spiral
     [{count, 100}, {one, 100}] = folsom_metrics:get_metric_value(spiral).
 
+check_group_metrics() ->
+    Metrics = get_metrics_value("mygroup"),
+    5 = length(Metrics),
+    {counter, 0} = lists:keyfind(counter,1,Metrics),
+    {counter2, 0} = lists:keyfind(counter2,1,Metrics),
+    {<<"gauge">>, 2} = lists:keyfind(<<"gauge">>,1,Metrics),
+
+    {meter, Meter} = lists:keyfind(meter,1,Metrics),
+    ok = case proplists:get_value(one, Meter) of
+             Value when Value > 1 ->
+                 ok;
+             _ ->
+                 error
+         end,
+    ok = case proplists:get_value(day, Meter) of
+             Value1 when Value1 > 0.005 ->
+                 ok;
+             _ ->
+                 error
+         end,
+
+    {spiral, [{count, 100}, {one, 100}]} = lists:keyfind(spiral,1,Metrics),
+
+    Counters = get_metrics_value("mygroup",counter),
+    {counter, 0} = lists:keyfind(counter,1,Counters),
+    {counter2, 0} = lists:keyfind(counter2,1,Counters).
 
 delete_metrics() ->
     17 = length(ets:tab2list(?FOLSOM_TABLE)),
diff --git a/test/folsom_tests.erl b/test/folsom_tests.erl
index 04f2d94..389c3f9 100644
--- a/test/folsom_tests.erl
+++ b/test/folsom_tests.erl
@@ -32,6 +32,8 @@
      fun (_) -> folsom:stop() end,
      [{"creating metrics",
        fun folsom_erlang_checks:create_metrics/0},
+      {"tagging metrics",
+       fun folsom_erlang_checks:tag_metrics/0},
       {"populating metrics",
        {timeout, 30, fun folsom_erlang_checks:populate_metrics/0}},
       {"checking metrics",
@@ -40,6 +42,8 @@
        fun () ->
                folsom_erlang_checks:counter_metric(10000, testcounter)
        end},
+      {"checking group metrics",
+       fun folsom_erlang_checks:check_group_metrics/0},
       {"checking erlang vm metrics",
        fun folsom_erlang_checks:vm_metrics/0},
       {"deleting metrics",