*: expose wal metrics at /metrics

release-2.1
Xiang Li 2015-02-14 19:30:39 -08:00 committed by Yicheng Qin
parent fb1a28c65d
commit 84485643fe
3 changed files with 40 additions and 17 deletions

View File

@ -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
wal/metrics.go Normal file
View File

@ -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)
}

View File

@ -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()
}