From 84485643fefbf2027172d8ee66a7571da4d4aafc Mon Sep 17 00:00:00 2001 From: Xiang Li Date: Sat, 14 Feb 2015 19:30:39 -0800 Subject: [PATCH] *: expose wal metrics at /metrics --- etcdserver/etcdhttp/client.go | 3 +++ wal/metrics.go | 33 +++++++++++++++++++++++++++++++++ wal/wal.go | 21 ++++----------------- 3 files changed, 40 insertions(+), 17 deletions(-) create mode 100644 wal/metrics.go diff --git a/etcdserver/etcdhttp/client.go b/etcdserver/etcdhttp/client.go index 2a393d336..a5bc6c484 100644 --- a/etcdserver/etcdhttp/client.go +++ b/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) diff --git a/wal/metrics.go b/wal/metrics.go new file mode 100644 index 000000000..e07d31f4f --- /dev/null +++ b/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) +} diff --git a/wal/wal.go b/wal/wal.go index 644ff0e55..b5e3ac84b 100644 --- a/wal/wal.go +++ b/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() }