You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ja...@apache.org on 2009/02/26 18:28:25 UTC

svn commit: r748217 - in /couchdb/trunk: share/www/script/test/stats.js src/couchdb/couch_db.erl src/couchdb/couch_httpd_db.erl src/couchdb/couch_stats.hrl src/couchdb/couch_stats_aggregator.erl

Author: jan
Date: Thu Feb 26 17:28:25 2009
New Revision: 748217

URL: http://svn.apache.org/viewvc?rev=748217&view=rev
Log:
- add descriptions to metrics
- move document_* metrics to couch_db module and merge them into database_* metrics

Modified:
    couchdb/trunk/share/www/script/test/stats.js
    couchdb/trunk/src/couchdb/couch_db.erl
    couchdb/trunk/src/couchdb/couch_httpd_db.erl
    couchdb/trunk/src/couchdb/couch_stats.hrl
    couchdb/trunk/src/couchdb/couch_stats_aggregator.erl

Modified: couchdb/trunk/share/www/script/test/stats.js
URL: http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/stats.js?rev=748217&r1=748216&r2=748217&view=diff
==============================================================================
--- couchdb/trunk/share/www/script/test/stats.js (original)
+++ couchdb/trunk/share/www/script/test/stats.js Thu Feb 26 17:28:25 2009
@@ -86,40 +86,40 @@
    }
  };
  
- var document_read_count_tests = {
-   'should increase read document counter when a document is read': function(name) {
+ var database_read_count_tests = {
+   'should increase database reads counter when a document is read': function(name) {
      var db = new CouchDB("test_suite_db");
      db.deleteDb();
      db.createDb();
      db.save({"_id":"test"});
 
-     var reads = requestStatsTest("httpd", "document_reads").current;
+     var reads = requestStatsTest("couchdb", "database_reads").current;
      db.open("test");
-     var new_reads = requestStatsTest("httpd", "document_reads").current;
+     var new_reads = requestStatsTest("couchdb", "database_reads").current;
 
      TEquals(reads + 1 , new_reads, name);
    },
-   'should not increase read document counter when a non-document is read': function(name) {
+   'should not increase database read counter when a non-document is read': function(name) {
      var db = new CouchDB("test_suite_db");
      db.deleteDb();
      db.createDb();
      db.save({"_id":"test"});
 
-     var reads = requestStatsTest("httpd", "document_reads").current;
+     var reads = requestStatsTest("couchdb", "database_reads").current;
      CouchDB.request("GET", "/");
-     var new_reads = requestStatsTest("httpd", "document_reads").current;
+     var new_reads = requestStatsTest("couchdb", "database_reads").current;
 
      TEquals(reads, new_reads, name);
    },
-   'should increase read document counter when a document\'s revisions are read': function(name) {
+   'should increase database read counter when a document\'s revisions are read': function(name) {
      var db = new CouchDB("test_suite_db");
      db.deleteDb();
      db.createDb();
      db.save({"_id":"test"});
 
-     var reads = requestStatsTest("httpd", "document_reads").current;
+     var reads = requestStatsTest("couchdb", "database_reads").current;
      db.open("test", {"open_revs":"all"});
-     var new_reads = requestStatsTest("httpd", "document_reads").current;
+     var new_reads = requestStatsTest("couchdb", "database_reads").current;
 
      TEquals(reads + 1 , new_reads, name);
    }
@@ -208,18 +208,18 @@
  };
 
  var document_write_count_tests = {
-   'should increment counter for document creates': function(name) {
+   'should increment database changes counter for document creates': function(name) {
      var db = new CouchDB("test_suite_db");
      db.deleteDb();
      db.createDb();
 
-     var creates = requestStatsTest("httpd", "document_creates").current;
+     var creates = requestStatsTest("couchdb", "database_changes").current;
      db.save({"a":"1"});
-     var new_creates = requestStatsTest("httpd", "document_creates").current;
+     var new_creates = requestStatsTest("couchdb", "database_changes").current;
 
      TEquals(creates + 1, new_creates, name);
    },
-   'should not increment counter for document creates when updating a doc': function(name) {
+   'should increment database changes counter for document updates': function(name) {
      var db = new CouchDB("test_suite_db");
      db.deleteDb();
      db.createDb();
@@ -227,38 +227,13 @@
      var doc = {"_id":"test"};
      db.save(doc);
      
-     var creates = requestStatsTest("httpd", "document_creates").current;
+     var updates = requestStatsTest("couchdb", "database_changes").current;
      db.save(doc);
-     var new_creates = requestStatsTest("httpd", "document_creates").current;
-
-     TEquals(creates, new_creates, name);
-   },
-   'should increment counter for document updates': function(name) {
-     var db = new CouchDB("test_suite_db");
-     db.deleteDb();
-     db.createDb();
-
-     var doc = {"_id":"test"};
-     db.save(doc);
-     
-     var updates = requestStatsTest("httpd", "document_updates").current;
-     db.save(doc);
-     var new_updates = requestStatsTest("httpd", "document_updates").current;
+     var new_updates = requestStatsTest("couchdb", "database_changes").current;
 
      TEquals(updates + 1, new_updates, name);
    },
-   'should not increment counter for document updates when creating a document': function(name) {
-     var db = new CouchDB("test_suite_db");
-     db.deleteDb();
-     db.createDb();
-
-     var updates = requestStatsTest("httpd", "document_updates").current;
-     db.save({"a":"1"});
-     var new_updates = requestStatsTest("httpd", "document_updates").current;
-
-     TEquals(updates, new_updates, name);
-   },
-   'should increment counter for document deletes': function(name) {
+   'should increment database changes counter for document deletes': function(name) {
      var db = new CouchDB("test_suite_db");
      db.deleteDb();
      db.createDb();
@@ -266,13 +241,13 @@
      var doc = {"_id":"test"};
      db.save(doc);
      
-     var deletes = requestStatsTest("httpd", "document_deletes").current;
+     var deletes = requestStatsTest("couchdb", "database_changes").current;
      db.deleteDoc(doc);
-     var new_deletes = requestStatsTest("httpd", "document_deletes").current;
+     var new_deletes = requestStatsTest("couchdb", "database_changes").current;
 
      TEquals(deletes + 1, new_deletes, name);
    },
-   'should increment the copy counter': function(name) {
+   'should increment database changes counter for document copies': function(name) {
      var db = new CouchDB("test_suite_db");
      db.deleteDb();
      db.createDb();
@@ -280,15 +255,15 @@
      var doc = {"_id":"test"};
      db.save(doc);
 
-     var copies = requestStatsTest("httpd", "document_copies").current;
+     var copies = requestStatsTest("couchdb", "database_changes").current;
      CouchDB.request("COPY", "/test_suite_db/test", {
        headers: {"Destination":"copy_of_test"}
      });
-     var new_copies = requestStatsTest("httpd", "document_copies").current;
+     var new_copies = requestStatsTest("couchdb", "database_changes").current;
 
      TEquals(copies + 1, new_copies, name);
    },
-   'should increment the move counter': function(name) {
+   'should increment database changes counter for document moves': function(name) {
      var db = new CouchDB("test_suite_db");
      db.deleteDb();
      db.createDb();
@@ -296,11 +271,11 @@
      var doc = {"_id":"test"};
      db.save(doc);
 
-     var moves = requestStatsTest("httpd", "document_moves").current;
+     var moves = requestStatsTest("couchdb", "database_changes").current;
      CouchDB.request("MOVE", "/test_suite_db/test?rev=" + doc._rev, {
        headers: {"Destination":"move_of_test"}
      });
-     var new_moves = requestStatsTest("httpd", "document_moves").current;
+     var new_moves = requestStatsTest("couchdb", "database_changes").current;
 
      TEquals(moves + 1, new_moves, name);
    },
@@ -318,31 +293,31 @@
 
      TEquals(bulks + 1, new_bulks, name);
    },
-   'should increment counter for document creates using POST': function(name) {
+   'should increment database changes counter for document creates using POST': function(name) {
      var db = new CouchDB("test_suite_db");
      db.deleteDb();
      db.createDb();
 
-     var creates = requestStatsTest("httpd", "document_creates").current;
+     var creates = requestStatsTest("couchdb", "database_changes").current;
      CouchDB.request("POST", "/test_suite_db", {body:'{"a":"1"}'});
-     var new_creates = requestStatsTest("httpd", "document_creates").current;
+     var new_creates = requestStatsTest("couchdb", "database_changes").current;
 
      TEquals(creates + 1, new_creates, name);
    },
-   'should increment document create counter when adding attachment': function(name) {
+   'should increment database changes counter when adding attachment': function(name) {
      var db = new CouchDB("test_suite_db");
      db.deleteDb();
      db.createDb();
 
-     var creates = requestStatsTest("httpd", "document_creates").current;
+     var creates = requestStatsTest("couchdb", "database_changes").current;
      CouchDB.request("PUT", "/test_suite_db/bin_doc2/foo2.txt", {
            body:"This is no base64 encoded text",
            headers:{"Content-Type": "text/plain;charset=utf-8"}
      });
-     var new_creates = requestStatsTest("httpd", "document_creates").current;
+     var new_creates = requestStatsTest("couchdb", "database_changes").current;
      TEquals(creates + 1, new_creates, name);
    },
-   'should increment document update counter when adding attachment to existing doc': function(name) {
+   'should increment database changes counter when adding attachment to existing doc': function(name) {
      var db = new CouchDB("test_suite_db");
      db.deleteDb();
      db.createDb();
@@ -350,12 +325,12 @@
      var doc = {_id:"test"};
      db.save(doc);
 
-     var updates = requestStatsTest("httpd", "document_updates").current;
+     var updates = requestStatsTest("couchdb", "database_changes").current;
      CouchDB.request("PUT", "/test_suite_db/test/foo2.txt?rev=" + doc._rev, {
            body:"This is no base64 encoded text",
            headers:{"Content-Type": "text/plain;charset=utf-8"}
      });
-     var new_updates = requestStatsTest("httpd", "document_updates").current;
+     var new_updates = requestStatsTest("couchdb", "database_changes").current;
      TEquals(updates + 1, new_updates, name);
    }
 
@@ -428,7 +403,7 @@
    var tests = [
      open_databases_tests,
      request_count_tests, 
-     document_read_count_tests, 
+     database_read_count_tests, 
      view_read_count_tests, 
      http_requests_by_method_tests,
      document_write_count_tests,

Modified: couchdb/trunk/src/couchdb/couch_db.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_db.erl?rev=748217&r1=748216&r2=748217&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_db.erl (original)
+++ couchdb/trunk/src/couchdb/couch_db.erl Thu Feb 26 17:28:25 2009
@@ -92,6 +92,7 @@
     open_doc(Db, IdOrDocInfo, []).
 
 open_doc(Db, Id, Options) ->
+    couch_stats_collector:increment({couchdb, database_reads}),
     case open_doc_int(Db, Id, Options) of
     {ok, #doc{deleted=true}=Doc} ->
         case lists:member(deleted, Options) of
@@ -105,6 +106,7 @@
     end.
 
 open_doc_revs(Db, Id, Revs, Options) ->
+    couch_stats_collector:increment({couchdb, database_reads}),
     [Result] = open_doc_revs_int(Db, [{Id, Revs}], Options),
     Result.
 
@@ -284,6 +286,7 @@
     update_docs(#db{update_pid=UpdatePid}=Db, Docs, Options, true).
 
 update_docs(Db, Docs, Options, false) ->
+    couch_stats_collector:increment({couchdb, database_changes}),
     DocBuckets = group_alike_docs(Docs),
     Ids = [Id || [#doc{id=Id}|_] <- DocBuckets],
     
@@ -320,7 +323,9 @@
     write_and_commit(Db, DocBuckets2, Options);
     
 update_docs(Db, Docs, Options, true) ->
-        % go ahead and generate the new revision ids for the documents.
+    couch_stats_collector:increment({couchdb, database_changes}),
+
+    % go ahead and generate the new revision ids for the documents.
     Docs2 = lists:map(
         fun(#doc{id=Id,revs=Revs}=Doc) ->
             case Id of

Modified: couchdb/trunk/src/couchdb/couch_httpd_db.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd_db.erl?rev=748217&r1=748216&r2=748217&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_httpd_db.erl (original)
+++ couchdb/trunk/src/couchdb/couch_httpd_db.erl Thu Feb 26 17:28:25 2009
@@ -80,7 +80,7 @@
     Doc = couch_doc:from_json_obj(couch_httpd:json_body(Req)),
     DocId = couch_util:new_uuid(),
     {ok, NewRev} = couch_db:update_doc(Db, Doc#doc{id=DocId, revs=[]}, []),
-    couch_stats_collector:increment({httpd, document_creates}),
+    % couch_stats_collector:increment({httpd, document_creates}),
     DocUrl = absolute_uri(Req, 
         binary_to_list(<<"/",DbName/binary,"/",DocId/binary>>)),
     send_json(Req, 201, [{"Location", DocUrl}], {[
@@ -379,7 +379,7 @@
         couch_httpd:send_error(Req, 409, <<"missing_rev">>,
             <<"Document rev/etag must be specified to delete">>);
     RevToDelete ->
-        couch_stats_collector:increment({httpd, document_deletes}),
+        % couch_stats_collector:increment({httpd, document_deletes}),
         {ok, NewRev} = couch_db:delete_doc(Db, DocId, [RevToDelete]),
         send_json(Req, 200, {[
             {ok, true},
@@ -394,7 +394,7 @@
         open_revs = Revs,
         options = Options
     } = parse_doc_query(Req),
-    couch_stats_collector:increment({httpd, document_reads}),
+    % couch_stats_collector:increment({httpd, document_reads}),
     case Revs of
     [] ->
         Doc = couch_doc_open(Db, DocId, Rev, Options),
@@ -471,10 +471,10 @@
     end,
     case extract_header_rev(Req, ExplicitRev) of
     missing_rev ->
-        couch_stats_collector:increment({httpd, document_creates}),
+        % couch_stats_collector:increment({httpd, document_creates}),
         Revs = [];
     Rev ->
-        couch_stats_collector:increment({httpd, document_updates}),
+        % couch_stats_collector:increment({httpd, document_updates}),
         Revs = [Rev]
     end,
     {ok, NewRev} = couch_db:update_doc(Db, Doc#doc{id=DocId, revs=Revs}, Options),
@@ -498,7 +498,7 @@
 
     % save new doc
     {ok, NewTargetRev} = couch_db:update_doc(Db, Doc#doc{id=TargetDocId, revs=TargetRev}, []),
-    couch_stats_collector:increment({httpd, document_copies}),
+    % couch_stats_collector:increment({httpd, document_copies}),
 
     send_json(Req, 201, [{"Etag", "\"" ++ binary_to_list(NewTargetRev) ++ "\""}], {[
         {ok, true},
@@ -525,7 +525,7 @@
         #doc{id=SourceDocId, revs=[SourceRev], deleted=true}
         ],
     {ok, ResultRevs} = couch_db:update_docs(Db, Docs, []),
-    couch_stats_collector:increment({httpd, document_moves}),
+    % couch_stats_collector:increment({httpd, document_moves}),
     
     DocResults = lists:zipwith(
         fun(FDoc, NewRev) ->
@@ -629,10 +629,10 @@
 
     Doc = case extract_header_rev(Req, couch_httpd:qs_value(Req, "rev")) of
         missing_rev -> % make the new doc
-            couch_stats_collector:increment({httpd, document_creates}),
+            % couch_stats_collector:increment({httpd, document_creates}),
             #doc{id=DocId};
         Rev ->
-            couch_stats_collector:increment({httpd, document_updates}),
+            % couch_stats_collector:increment({httpd, document_updates}),
             case couch_db:open_doc_revs(Db, DocId, [Rev], []) of
             {ok, [{ok, Doc0}]}  -> Doc0#doc{revs=[Rev]};
             {ok, [Error]}       -> throw(Error)

Modified: couchdb/trunk/src/couchdb/couch_stats.hrl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_stats.hrl?rev=748217&r1=748216&r2=748217&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_stats.hrl (original)
+++ couchdb/trunk/src/couchdb/couch_stats.hrl Thu Feb 26 17:28:25 2009
@@ -11,11 +11,12 @@
 % the License.
 
 -record(aggregates, {
-    min=0,
-    max=0,
-    mean=0.0,
+    min = 0,
+    max = 0,
+    mean = 0.0,
     variance = 0.0,
-    stddev=0.0,
-    count=0,
-    last=0
+    stddev = 0.0,
+    count = 0,
+    last = 0,
+    description
 }).

Modified: couchdb/trunk/src/couchdb/couch_stats_aggregator.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_stats_aggregator.erl?rev=748217&r1=748216&r2=748217&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_stats_aggregator.erl (original)
+++ couchdb/trunk/src/couchdb/couch_stats_aggregator.erl Thu Feb 26 17:28:25 2009
@@ -23,7 +23,8 @@
          time_passed/0, clear_aggregates/1]).
 
 -record(state, {
-    aggregates = []
+    aggregates = [],
+    descriptions = []
 }).
 
 -define(COLLECTOR, couch_stats_collector).
@@ -61,6 +62,7 @@
 init(_) ->
     ets:new(?MODULE, [named_table, set, protected]),
     init_timers(),
+    init_descriptions(),
     {ok, #state{}}.
 
 handle_call({get, Key}, _, State) ->
@@ -141,8 +143,8 @@
     end, Stats),
     #state{aggregates=NewStats}.
 
-%% default Time is 0, which is when CouchDB started
 get_aggregate(Key, State) ->
+    %% default Time is 0, which is when CouchDB started
     get_aggregate(Key, State, '0').
 get_aggregate(Key, #state{aggregates=StatsList}, Time) ->
     Aggregates = case proplists:lookup(Key, StatsList) of
@@ -151,11 +153,17 @@
         {Key, Stats} ->
             case proplists:lookup(Time, Stats) of
                 none -> #aggregates{}; % empty record again
-                {Time, Stat} -> Stat
+                {Time, Stat} -> Stat#aggregates{description=get_description(Key)}
             end
     end,
     Aggregates.
 
+get_description(Key) ->
+    case ets:lookup(?MODULE, Key) of
+        [] -> <<"No description yet.">>;
+        [{_Key, Description}] -> Description
+    end.
+
 %% updates all aggregates for Key
 update_aggregates_loop(Key, Values, State, CounterType) ->
     #state{aggregates=AllStats} = State,
@@ -193,7 +201,9 @@
 
     % put the newly calculated aggregates into State and delete the previous
     % entry
-    #state{aggregates=[{Key, NewStats} | proplists:delete(Key, AllStats)]}.
+    #state{
+        aggregates=[{Key, NewStats} | proplists:delete(Key, AllStats)]
+    }.
 
 % does the actual updating of the aggregate record
 update_aggregates(Value, Stat, CounterType) ->
@@ -241,7 +251,7 @@
     end.
 
 
-aggregate_to_json_term(#aggregates{min=Min,max=Max,mean=Mean,stddev=Stddev,count=Count,last=Last}) ->
+aggregate_to_json_term(#aggregates{min=Min,max=Max,mean=Mean,stddev=Stddev,count=Count,last=Last,description=Description}) ->
     {[
         % current is redundant, but reads nicer in JSON
         {current, Last},
@@ -250,7 +260,8 @@
         {min, Min},
         {max, Max},
         {stddev, Stddev},
-        {resolution, 1}
+        {resolution, 1},
+        {description, Description}
     ]}.
 
 get_stats(Key, State) ->
@@ -275,6 +286,49 @@
           {[{LastMod, {lists:sort(LastVals)}} | LastRestMods]}
     end.
 
+
+init_descriptions() ->
+
+    % ets is probably overkill here, but I didn't manage to keep the 
+    % descriptions in the gen_server state. Which means there is probably
+    % a bug in one of the handle_call() functions most likely the one that
+    % handles the time_passed message. But don't tell anyone, the math is
+    % correct :) -- Jan
+
+    % please keep this in alphabetical order
+    ets:insert(?MODULE, {{couchdb, database_changes}, <<"Number of times a database was changed">>}),
+    ets:insert(?MODULE, {{couchdb, database_reads}, <<"Number of times a document was read from a database">>}),
+    ets:insert(?MODULE, {{couchdb, open_databases}, <<"Number of open databases">>}),
+    ets:insert(?MODULE, {{couchdb, request_time}, <<"Length of a request inside CouchDB without Mochiweb">>}),
+
+    ets:insert(?MODULE, {{http_status_codes, '200'}, <<"Number of HTTP 200 OK responses">>}),
+    ets:insert(?MODULE, {{http_status_codes, '201'}, <<"Number of HTTP 201 Created responses">>}),
+    ets:insert(?MODULE, {{http_status_codes, '202'}, <<"Number of HTTP 202 Accepted responses">>}),
+    ets:insert(?MODULE, {{http_status_codes, '301'}, <<"Number of HTTP 301 Moved Permanently responses">>}),
+    ets:insert(?MODULE, {{http_status_codes, '304'}, <<"Number of HTTP 304 Not Modified responses">>}),
+    ets:insert(?MODULE, {{http_status_codes, '400'}, <<"Number of HTTP 400 Bad Request responses">>}),
+    ets:insert(?MODULE, {{http_status_codes, '401'}, <<"Number of HTTP 401 Unauthorized responses">>}),
+    ets:insert(?MODULE, {{http_status_codes, '403'}, <<"Number of HTTP 403 Forbidden responses">>}),
+    ets:insert(?MODULE, {{http_status_codes, '404'}, <<"Number of HTTP 404 Not Found responses">>}),
+    ets:insert(?MODULE, {{http_status_codes, '405'}, <<"Number of HTTP 405 Method Not Allowed responses">>}),
+    ets:insert(?MODULE, {{http_status_codes, '409'}, <<"Number of HTTP 409 Conflict responses">>}),
+    ets:insert(?MODULE, {{http_status_codes, '412'}, <<"Number of HTTP 412 Precondition Failed responses">>}),
+    ets:insert(?MODULE, {{http_status_codes, '500'}, <<"Number of HTTP 500 Internal Server Error responses">>}),
+
+    ets:insert(?MODULE, {{httpd, bulk_requests}, <<"Number of bulk requests">>}),
+    ets:insert(?MODULE, {{httpd, copy_requests}, <<"Number of HTTP COPY requests">>}),
+    ets:insert(?MODULE, {{httpd, delete_requests}, <<"Number of HTTP DELETE requests">>}),
+    ets:insert(?MODULE, {{httpd, get_requests}, <<"Number of HTTP GET requests">>}),
+    ets:insert(?MODULE, {{httpd, head_requests}, <<"Number of HTTP HEAD requests">>}),
+    ets:insert(?MODULE, {{httpd, move_requests}, <<"Number of HTTP MOVE requests">>}),
+    ets:insert(?MODULE, {{httpd, post_requests}, <<"Number of HTTP POST requests">>}),
+    ets:insert(?MODULE, {{httpd, requests}, <<"Number of HTTP requests">>}),
+    ets:insert(?MODULE, {{httpd, temporary_view_reads}, <<"Number of temporary view reads">>}),
+    ets:insert(?MODULE, {{httpd, view_reads}, <<"Number of view reads">>}),
+    ets:insert(?MODULE, {{httpd, put_requests}, <<"Number of HTTP PUT requests">>}).
+    % please keep this in alphabetical order
+
+
 % Timer
 
 init_timers() ->