anchor.diff:      _ = gmetric(both, "Memory used by atoms", "int32", erlang:memory(atom), "Bytes"),
       _ = gmetric(both, "Memory used by binaries", "int32", erlang:memory(binary), "Bytes"),
       _ = gmetric(both, "Memory used by system", "int32", erlang:memory(system), "Bytes"),
  -    DHTNodesMemoryUsage = lists:sum([element(2, erlang:process_info(P, memory))
  -                                    || P <- pid_groups:find_all(dht_node)]),
  -    _ = gmetric(both, "Memory used by dht_nodes", "int32", DHTNodesMemoryUsage, "Bytes"),
  +    ok.
  +
  +% @doc aggregate the number of key-value pairs
  +%      and the amount of memory for this VM
  +-spec send_dht_node_metrics() -> ok.
  +send_dht_node_metrics() ->
  +    DHTNodes = pid_groups:find_all(dht_node),
  +    % Load of DHT Nodes
  +    Pairs = lists:foldl(fun (Pid, Agg) ->
  +                                Agg + get_load(Pid)
  +                        end, 0, DHTNodes),
  +    _ = gmetric(both, "kv pairs", "int32", Pairs, "pairs"),
  +    % Memory Usage of DHT Nodes
  +    MemoryUsage = lists:sum([element(2, erlang:process_info(P, memory))
  +                             || P <- DHTNodes]),
  +    _ = gmetric(both, "Memory used by dht_nodes", "int32", MemoryUsage, "Bytes"),
  +    ok.
  +
  +-spec send_message_metrics() -> ok.
  +send_message_metrics() ->
  +    {Received, Sent, _Time} = comm_logger:dump(),
  +    traverse(received, gb_trees:iterator(Received)),
  +    traverse(sent, gb_trees:iterator(Sent)),
  +    ok.
  +
  +-spec send_rrd_metrics() -> fail | ok.
  +send_rrd_metrics() ->
       % Statistics in RRD (Load, Latency)
  -    RRDMetrics = fetch_rrd_metrics(),
  -    _ = case RRDMetrics of
  -            [] -> ok;
  -            _  ->  _ = [gmetric(both, Metric, Type, Value, Unit) || {Metric, Type, Value, Unit} <- RRDMetrics],
  -                   ok
  +    RRDMetrics =
  +        case pid_groups:pid_of("clients_group", monitor) of
  +            failed -> [];
  +            ClientMonitor ->
  +                case monitor:get_rrds(ClientMonitor, [{api_tx, 'req_list'}]) of
  +                    [{_,_, undefined}] -> [];
  +                    [{_, _, RRD}] ->
  +                        case rrd:dump(RRD) of
  +                            [H | _] ->
  +                                {From_, To_, Value} = H,
  +                                Diff_in_s = timer:now_diff(To_, From_) div 1000000,
  +                                {Sum, _Sum2, Count, _Min, _Max, _Hist} = Value,
  +                                AvgPerS = Count / Diff_in_s,
  +                                Avg = Sum / Count,
  +                                [{both, "tx latency", "float", Avg, "ms"},
  +                                 {both, "transactions/s", "float", AvgPerS, "1/s"}];
  +                            _ -> []
  +                        end
  +                end
           end,
  -    % Local Load
  -    LocalLoad = fetch_local_load(),
  -    _ = [gmetric(both, Metric, Type, Value, Unit) || {Metric, Type, Value, Unit} <- LocalLoad],
  -    % vivaldi statistics
  -    monitor_per_dht_node(fun monitor_vivaldi_errors/2, pid_groups:groups_with(dht_node)),
  -    set_last_active(State).
  +    gmetric(RRDMetrics).
   
  +-spec send_vivaldi_errors() -> ok.
  +send_vivaldi_errors() ->
  +    DHTNodes = lists:sort(pid_groups:groups_with(dht_node)),
  +    lists:foldl(fun (Group, Idx) ->
  +                        _ = send_vivaldi_errors(Group, Idx),
  +                        Idx + 1
  +                end, 0, DHTNodes),
  +    ok.
  +
  +
  +%%%%%%%%%%%%
  +%% Helpers %
  +%%%%%%%%%%%%
  +
  +-spec gmetric(list()) -> ok.
  +gmetric(MetricsList) ->
  +    lists:foreach(fun({Slope, Metric, Type, Value, Unit}) ->
  +                          gmetric(Slope, Metric, Type, Value, Unit)
  +                  end, MetricsList).
  +
  +-spec gmetric(Slope::both | positive, Metric::string(), Type::string(), Value::number(), Unit::string()) -> string().
  +gmetric(Slope, Metric, Type, Value, Unit) ->
  +    Cmd = lists:flatten(io_lib:format("gmetric --slope ~p --name ~p --type ~p --value ~p --units ~p~n",
  +                         [Slope, Metric, Type, Value, Unit])),
  +    Res = os:cmd(Cmd),
  +    ?TRACE("~s: ~s~n", [Cmd, Res]),
  +    Res.
   
   -spec traverse(received | sent, Iter1::term()) -> ok.
   traverse(RcvSnd, Iter1) ->
  
positive.code: -spec on(message(), state()) -> state().
  on({ganglia_trigger}, {LastActive, TriggerOld}) ->
      Trigger = trigger:next(TriggerOld),
      gen_component:post_op(_State = {LastActive, Trigger}, {ganglia_periodic});
  
  on({ganglia_periodic}, State) ->
      % message statistics
      {Received, Sent, _Time} = comm_logger:dump(),
      traverse(received, gb_trees:iterator(Received)),
      traverse(sent, gb_trees:iterator(Sent)),
      % general erlang status information
      _ = gmetric(both, "Erlang Processes", "int32", erlang:system_info(process_count), "Total Number"),
      _ = gmetric(both, "Memory used by Erlang processes", "int32", erlang:memory(processes_used), "Bytes"),
  
negative.code:       traverse(RcvSnd, Iter2)
    end.
  
  -spec send_vivaldi_errors(pid_groups:groupname(), non_neg_integer()) -> ok | string().
  send_vivaldi_errors(Group, Idx) ->
      case pid_groups:pid_of(Group, vivaldi) of
          failed ->
              ok;
  