Browse Source

*: expose wal metrics at /metrics

Xiang Li 11 years ago
parent
commit
84485643fe
3 changed files with 40 additions and 17 deletions
  1. 3 0
      etcdserver/etcdhttp/client.go
  2. 33 0
      wal/metrics.go
  3. 4 17
      wal/wal.go

+ 3 - 0
etcdserver/etcdhttp/client.go

@@ -29,6 +29,7 @@ import (
 	"time"
 
 	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/jonboulle/clockwork"
+	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus"
 	"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
 	etcdErr "github.com/coreos/etcd/error"
 	"github.com/coreos/etcd/etcdserver"
@@ -47,6 +48,7 @@ const (
 	membersPrefix            = "/v2/members"
 	statsPrefix              = "/v2/stats"
 	statsPath                = "/stats"
+	metricsPath              = "/metrics"
 	healthPath               = "/health"
 	versionPath              = "/version"
 )
@@ -84,6 +86,7 @@ func NewClientHandler(server *etcdserver.EtcdServer) http.Handler {
 	mux.HandleFunc(statsPrefix+"/self", sh.serveSelf)
 	mux.HandleFunc(statsPrefix+"/leader", sh.serveLeader)
 	mux.HandleFunc(statsPath, serveStats)
+	mux.Handle(metricsPath, prometheus.Handler())
 	mux.Handle(membersPrefix, mh)
 	mux.Handle(membersPrefix+"/", mh)
 	mux.Handle(deprecatedMachinesPrefix, dmh)

+ 33 - 0
wal/metrics.go

@@ -0,0 +1,33 @@
+// Copyright 2015 CoreOS, 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 wal
+
+import "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus"
+
+var (
+	syncDurations = prometheus.NewSummary(prometheus.SummaryOpts{
+		Name: "wal_fsync_durations_microseconds",
+		Help: "The latency distributions of fsync called by wal.",
+	})
+	lastIndexSaved = prometheus.NewGauge(prometheus.GaugeOpts{
+		Name: "wal_last_index_saved",
+		Help: "The index of the last entry saved by wal",
+	})
+)
+
+func init() {
+	prometheus.MustRegister(syncDurations)
+	prometheus.MustRegister(lastIndexSaved)
+}

+ 4 - 17
wal/wal.go

@@ -25,8 +25,6 @@ import (
 	"reflect"
 	"time"
 
-	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/codahale/metrics"
-	_ "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus"
 	"github.com/coreos/etcd/pkg/fileutil"
 	"github.com/coreos/etcd/pkg/pbutil"
 	"github.com/coreos/etcd/raft"
@@ -52,15 +50,8 @@ var (
 	ErrSnapshotMismatch = errors.New("wal: snapshot mismatch")
 	ErrSnapshotNotFound = errors.New("wal: snapshot not found")
 	crcTable            = crc32.MakeTable(crc32.Castagnoli)
-
-	// metrics
-	syncHdr *metrics.Histogram
 )
 
-func init() {
-	syncHdr = metrics.NewHistogram("wal.syncInMicrosecond", 0, 10*int64(time.Second/time.Microsecond), 3)
-}
-
 // WAL is a logical repersentation of the stable storage.
 // WAL is either in read mode or append mode but not both.
 // A newly created WAL is in append mode, and ready for appending records.
@@ -279,7 +270,7 @@ func (w *WAL) ReadAll() (metadata []byte, state raftpb.HardState, ents []raftpb.
 	// create encoder (chain crc with the decoder), enable appending
 	w.encoder = newEncoder(w.f, w.decoder.lastCRC())
 	w.decoder = nil
-	metrics.Gauge("wal.lastIndexSaved").Set(int64(w.enti))
+	lastIndexSaved.Set(float64(w.enti))
 	return metadata, state, ents, err
 }
 
@@ -330,8 +321,7 @@ func (w *WAL) sync() error {
 	}
 	start := time.Now()
 	err := w.f.Sync()
-	syncHdr.RecordValue(time.Since(start).Nanoseconds() / int64(time.Microsecond))
-	metrics.Counter("wal.syncs").Add()
+	syncDurations.Observe(float64(time.Since(start).Nanoseconds() / int64(time.Microsecond)))
 	return err
 }
 
@@ -377,14 +367,13 @@ func (w *WAL) Close() error {
 }
 
 func (w *WAL) saveEntry(e *raftpb.Entry) error {
-	metrics.Counter("wal.saveEntryOps").Add()
 	b := pbutil.MustMarshal(e)
 	rec := &walpb.Record{Type: entryType, Data: b}
 	if err := w.encoder.encode(rec); err != nil {
 		return err
 	}
 	w.enti = e.Index
-	metrics.Gauge("wal.lastIndexSaved").Set(int64(w.enti))
+	lastIndexSaved.Set(float64(w.enti))
 	return nil
 }
 
@@ -392,7 +381,6 @@ func (w *WAL) saveState(s *raftpb.HardState) error {
 	if raft.IsEmptyHardState(*s) {
 		return nil
 	}
-	metrics.Counter("wal.saveStateOps").Add()
 	w.state = *s
 	b := pbutil.MustMarshal(s)
 	rec := &walpb.Record{Type: stateType, Data: b}
@@ -423,12 +411,11 @@ func (w *WAL) SaveSnapshot(e walpb.Snapshot) error {
 	if err := w.encoder.encode(rec); err != nil {
 		return err
 	}
-	metrics.Counter("wal.saveSnapOps").Add()
 	// update enti only when snapshot is ahead of last index
 	if w.enti < e.Index {
 		w.enti = e.Index
 	}
-	metrics.Gauge("wal.lastIndexSaved").Set(int64(w.enti))
+	lastIndexSaved.Set(float64(w.enti))
 	return w.sync()
 }