ntp/responder/stats/json.go (78 lines of code) (raw):

/* Copyright (c) Facebook, Inc. and its affiliates. 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 stats implements statistics collection and reporting. It is used by server to report internal statistics, such as number of requests and responses. */ package stats import ( "encoding/json" "fmt" "net/http" "sync/atomic" log "github.com/sirupsen/logrus" ) // JSONStats implements Stat interface // This implementation reports JSON metrics via http interface // This is a passive implementation. Only "Start" needs to be called type JSONStats struct { // keep these aligned to 64-bit for sync/atomic invalidFormat int64 requests int64 responses int64 listeners int64 workers int64 readError int64 announce int64 } // toMap converts struct to a map func (j *JSONStats) toMap() (export map[string]int64) { export = make(map[string]int64) export["invalidformat"] = j.invalidFormat export["requests"] = j.requests export["responses"] = j.responses export["listeners"] = j.listeners export["workers"] = j.workers export["readError"] = j.readError export["announce"] = j.announce return export } // handleRequest is a handler used for all http monitoring requests func (j *JSONStats) handleRequest(w http.ResponseWriter, r *http.Request) { js, err := json.Marshal(j.toMap()) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") if _, err = w.Write(js); err != nil { log.Errorf("Failed to reply: %v", err) } } // Start with launch 303 thrift and report ODS metrics periodically func (j *JSONStats) Start(port int) { http.HandleFunc("/", j.handleRequest) addr := fmt.Sprintf(":%d", port) log.Debugf("Starting http json server on %s", addr) err := http.ListenAndServe(addr, nil) if err != nil { log.Errorf("Failed to start listener: %v", err) } } // IncInvalidFormat atomically add 1 to the counter func (j *JSONStats) IncInvalidFormat() { atomic.AddInt64(&j.invalidFormat, 1) } // IncRequests atomically add 1 to the counter func (j *JSONStats) IncRequests() { atomic.AddInt64(&j.requests, 1) } // IncResponses atomically add 1 to the counter func (j *JSONStats) IncResponses() { atomic.AddInt64(&j.responses, 1) } // IncListeners atomically add 1 to the counter func (j *JSONStats) IncListeners() { atomic.AddInt64(&j.listeners, 1) } // IncWorkers atomically add 1 to the counter func (j *JSONStats) IncWorkers() { atomic.AddInt64(&j.workers, 1) } // IncReadError atomically add 1 to the counter func (j *JSONStats) IncReadError() { atomic.AddInt64(&j.readError, 1) } // DecListeners atomically removes 1 from the counter func (j *JSONStats) DecListeners() { atomic.AddInt64(&j.listeners, -1) } // DecWorkers atomically removes 1 from the counter func (j *JSONStats) DecWorkers() { atomic.AddInt64(&j.workers, -1) } // SetAnnounce atomically sets counter to 1 func (j *JSONStats) SetAnnounce() { atomic.StoreInt64(&j.announce, 1) } // ResetAnnounce atomically sets counter to 0 func (j *JSONStats) ResetAnnounce() { atomic.StoreInt64(&j.announce, 0) }