*: expose wal metrics at /metrics
parent
fb1a28c65d
commit
84485643fe
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
21
wal/wal.go
21
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()
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue