anchor.diff: -%%%-------------------------------------------------------------------
  -%%% File    : riak_stat.erl
  -%%% Author  : Bryan Fink <bryan@basho.com>
  -%%% Description : Stats aggregator for Riak.
  -%%%
  -%%% Created : 10 Nov 2009 by Bryan Fink <bryan@basho.com>
  -%%%-------------------------------------------------------------------
  +%% 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.    
  +
  +%% @doc riak_stat is a long-lived gen_server process for aggregating
  +%%      stats about the Riak node on which it is runing.
  +%%
  +%%      Update each stat with the exported function update/1.  Modify
  +%%      the internal function update/3 to add storage for new stats.
  +%%
  +%%      Get the latest aggregation of stats with the exported function
  +%%      get_stats/0.  Modify the internal function produce_stats/1 to
  +%%      change how stats are represented.
  +%%
  +%%      Current stats:
  +%%<dl><dt>  vnode_gets
  +%%</dt><dd> Total number of gets handled by all vnodes on this node
  +%%          in the last minute.
  +%%</dd><dd> update(vnode_get)
  +%%
  +%%</dd><dt> vnode_puts
  +%%</dt><dd> Total number of puts handled by all vnodes on this node
  +%%          in the last minute.
  +%%</dd><dd> update(vnode_put)
  +%%
  +%%</dd><dt> node_gets
  +%%</dt><dd> Number of gets coordinated by this node in the last
  +%%          minute.
  +%%</dd><dd> update({get_fsm_time, Microseconds})
  +%%
  +%%</dd><dt> node_get_fsm_time_mean
  +%%</dt><dd> Mean time, in microseconds, between when a riak_get_fsm is
  +%%          started and when it sends a reply to the client, for the
  +%%          last minute.
  +%%</dd><dd> update({get_fsm_time, Microseconds})
  +%%
  +%%</dd><dt> node_get_fsm_time_median
  +%%</dt><dd> Median time, in microseconds, between when a riak_get_fsm
  +%%          is started and when it sends a reply to the client, for
  +%%          the last minute.
  +%%</dd><dd> update({get_fsm_time, Microseconds})
  +%%
  +%%</dd><dt> node_get_fsm_time_95
  +%%</dt><dd> Response time, in microseconds, met or beaten by 95% of
  +%%          riak_get_fsm executions.
  +%%</dd><dd> update({get_fsm_time, Microseconds})
  +%%
  +%%</dd><dt> node_get_fsm_time_99
  +%%</dt><dd> Response time, in microseconds, met or beaten by 99% of
  +%%          riak_get_fsm executions.
  +%%</dd><dd> update({get_fsm_time, Microseconds})
  +%%
  +%%</dd><dt> node_get_fsm_time_100
  +%%</dt><dd> Response time, in microseconds, met or beaten by 100% of
  +%%          riak_get_fsm executions.
  +%%</dd><dd> update({get_fsm_time, Microseconds})
  +%%
  +%%</dd><dt> node_puts
  +%%</dt><dd> Number of puts coordinated by this node in the last
  +%%          minute.
  +%%</dd><dd> update({put_fsm_time, Microseconds})
  +%%
  +%%</dd><dt> node_put_fsm_time_mean
  +%%</dt><dd> Mean time, in microseconds, between when a riak_put_fsm is
  +%%          started and when it sends a reply to the client, for the
  +%%          last minute.
  +%%</dd><dd> update({put_fsm_time, Microseconds})
  +%%
  +%%</dd><dt> node_put_fsm_time_median
  +%%</dt><dd> Median time, in microseconds, between when a riak_put_fsm
  +%%          is started and when it sends a reply to the client, for
  +%%          the last minute.
  +%%</dd><dd> update({put_fsm_time, Microseconds})
  +%%
  +%%</dd><dt> node_put_fsm_time_95
  +%%</dt><dd> Response time, in microseconds, met or beaten by 95% of
  +%%          riak_put_fsm executions.
  +%%</dd><dd> update({put_fsm_time, Microseconds})
  +%%
  +%%</dd><dt> node_put_fsm_time_99
  +%%</dt><dd> Response time, in microseconds, met or beaten by 99% of
  +%%          riak_put_fsm executions.
  +%%</dd><dd> update({put_fsm_time, Microseconds})
  +%%
  +%%</dd><dt> node_put_fsm_time_100
  +%%</dt><dd> Response time, in microseconds, met or beaten by 100% of
  +%%          riak_put_fsm executions.
  +%%</dd><dd> update({put_fsm_time, Microseconds})
  +%%
  +%%</dd><dt> cpu_nprocs
  +%%</dt><dd> Value returned by {@link cpu_sup:nprocs/0}.
  +%%
  +%%</dd><dt> cpu_avg1
  +%%</dt><dd> Value returned by {@link cpu_sup:avg1/0}.
  +%%
  +%%</dd><dt> cpu_avg5
  +%%</dt><dd> Value returned by {@link cpu_sup:avg5/0}.
  +%%
  +%%</dd><dt> cpu_avg15
  +%%</dt><dd> Value returned by {@link cpu_sup:avg15/0}.
  +%%
  +%%</dd><dt> mem_total
  +%%</dt><dd> The first element of the tuple returned by
  +%%          {@link memsup:get_memory_data/0}.
  +%%
  +%%</dd><dt> mem_allocated
  +%%</dt><dd> The second element of the tuple returned by
  +%%          {@link memsup:get_memory_data/0}.
  +%%
  +%%</dd><dt> disk
  +%%</dt><dd> Value returned by {@link disksup:get_disk_data/0}.
  +%%</dd></dl>
   -module(riak_stat).
   
   -behaviour(gen_server2).
  
positive.code:      {node_put_fsm_time_99, PutNN},
       {node_put_fsm_time_100, PutH}].
  
  cpu_stats() ->
      [{cpu_nprocs, cpu_sup:nprocs()},
       {cpu_avg1, cpu_sup:avg1()},
       {cpu_avg5, cpu_sup:avg5()},
       {cpu_avg15, cpu_sup:avg15()}].
  
  mem_stats() ->
      {Total, Alloc, _} = memsup:get_memory_data(),
      [{mem_total, Total},
       {mem_allocated, Alloc}].
  
  disk_stats() ->
      [{disk, disksup:get_disk_data()}].
  
negative.code: update(_, _, State) ->
      State.
  
  %% @spec spiral_incr(integer(), integer(), state()) -> state()
  %% @doc Increment the value of a spiraltime structure at a given
  %%      position of the State tuple.
  spiral_incr(Elt, Moment, State) ->
      setelement(Elt, State,
                 spiraltime:incr(1, Moment, element(Elt, State))).
  
  %% @spec slide_incr(integer(), term(), integer(), state()) -> state()
  %% @doc Update a slide structure at a given position in the
  %%      STate tuple.
  slide_incr(Elt, Reading, Moment, State) ->
      setelement(Elt, State,
                 slide:update(element(Elt, State), Reading, Moment)).
  
  %% @spec produce_stats(state()) -> proplist()
  %% @doc Produce a proplist-formatted view of the current aggregation
  %%      of stats.
  produce_stats(State) ->
      Moment = spiraltime:n(),
      lists:append(
  