diff --git a/index/firestorm/firestorm.go b/index/firestorm/firestorm.go index 4ffd9f3b..a88ec777 100644 --- a/index/firestorm/firestorm.go +++ b/index/firestorm/firestorm.go @@ -75,6 +75,10 @@ func (f *Firestorm) Open() (err error) { return } + if ss, ok := f.store.(store.KVStoreStats); ok { + f.stats.kvStats = ss.Stats() + } + // start a reader var kvreader store.KVReader kvreader, err = f.store.Reader() diff --git a/index/firestorm/stats.go b/index/firestorm/stats.go index 4f3eae87..ceac5611 100644 --- a/index/firestorm/stats.go +++ b/index/firestorm/stats.go @@ -18,6 +18,7 @@ type indexStat struct { f *Firestorm updates, deletes, batches, errors uint64 analysisTime, indexTime uint64 + kvStats json.Marshaler } func (i *indexStat) MarshalJSON() ([]byte, error) { @@ -29,5 +30,8 @@ func (i *indexStat) MarshalJSON() ([]byte, error) { m["analysis_time"] = atomic.LoadUint64(&i.analysisTime) m["index_time"] = atomic.LoadUint64(&i.indexTime) m["lookup_queue_len"] = len(i.f.lookuper.workChan) + if i.kvStats != nil { + m["kv"] = i.kvStats + } return json.Marshal(m) } diff --git a/index/store/boltdb/stats.go b/index/store/boltdb/stats.go new file mode 100644 index 00000000..cfaf71a8 --- /dev/null +++ b/index/store/boltdb/stats.go @@ -0,0 +1,21 @@ +// Copyright (c) 2014 Couchbase, Inc. +// Licensed 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. + +package boltdb + +import "encoding/json" + +type stats struct { + s *Store +} + +func (s *stats) MarshalJSON() ([]byte, error) { + bs := s.s.db.Stats() + return json.Marshal(bs) +} diff --git a/index/store/boltdb/store.go b/index/store/boltdb/store.go index b8eff256..26f320ff 100644 --- a/index/store/boltdb/store.go +++ b/index/store/boltdb/store.go @@ -18,6 +18,7 @@ package boltdb import ( + "encoding/json" "fmt" "github.com/blevesearch/bleve/index/store" @@ -95,6 +96,12 @@ func (bs *Store) Writer() (store.KVWriter, error) { }, nil } +func (bs *Store) Stats() json.Marshaler { + return &stats{ + s: bs, + } +} + func init() { registry.RegisterKVStore(Name, New) } diff --git a/index/store/kvstore.go b/index/store/kvstore.go index 776a5f25..7222af4f 100644 --- a/index/store/kvstore.go +++ b/index/store/kvstore.go @@ -9,6 +9,8 @@ package store +import "encoding/json" + // KVStore is an abstraction for working with KV stores type KVStore interface { @@ -154,3 +156,10 @@ type KVBatch interface { // Close frees resources Close() error } + +// KVStoreStats is an optional interface that KVStores can implement +// if they're able to report any useful stats +type KVStoreStats interface { + // Stats returns a JSON serializable object representing stats for this KVStore + Stats() json.Marshaler +} diff --git a/index/store/metrics/store.go b/index/store/metrics/store.go index c97c7829..012d6775 100644 --- a/index/store/metrics/store.go +++ b/index/store/metrics/store.go @@ -213,6 +213,20 @@ func (s *Store) WriteJSON(w io.Writer) (err error) { return } + // see if the underlying implementation has its own stats + if o, ok := s.o.(store.KVStoreStats); ok { + storeStats := o.Stats() + var storeBytes []byte + storeBytes, err = json.Marshal(storeStats) + if err != nil { + return + } + _, err = fmt.Fprintf(w, `, "store": %s`, string(storeBytes)) + if err != nil { + return + } + } + _, err = w.Write([]byte(`}`)) if err != nil { return diff --git a/index/upside_down/stats.go b/index/upside_down/stats.go index e447b28b..61cace27 100644 --- a/index/upside_down/stats.go +++ b/index/upside_down/stats.go @@ -17,6 +17,7 @@ import ( type indexStat struct { updates, deletes, batches, errors uint64 analysisTime, indexTime uint64 + kvStats json.Marshaler } func (i *indexStat) MarshalJSON() ([]byte, error) { @@ -27,5 +28,8 @@ func (i *indexStat) MarshalJSON() ([]byte, error) { m["errors"] = atomic.LoadUint64(&i.errors) m["analysis_time"] = atomic.LoadUint64(&i.analysisTime) m["index_time"] = atomic.LoadUint64(&i.indexTime) + if i.kvStats != nil { + m["kv"] = i.kvStats + } return json.Marshal(m) } diff --git a/index/upside_down/upside_down.go b/index/upside_down/upside_down.go index a9ae07e6..fbe61974 100644 --- a/index/upside_down/upside_down.go +++ b/index/upside_down/upside_down.go @@ -310,6 +310,10 @@ func (udc *UpsideDownCouch) Open() (err error) { return } + if ss, ok := udc.store.(store.KVStoreStats); ok { + udc.stats.kvStats = ss.Stats() + } + // start a reader to look at the index var kvreader store.KVReader kvreader, err = udc.store.Reader()