metric 패키지 추가
This commit is contained in:
108
metric/metric.go
Normal file
108
metric/metric.go
Normal file
@ -0,0 +1,108 @@
|
||||
package metric
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"math"
|
||||
"os"
|
||||
"sync"
|
||||
)
|
||||
|
||||
const (
|
||||
METRIC_HEAD_INLINE = byte(1)
|
||||
METRIC_TAIL_INLINE = byte(2)
|
||||
)
|
||||
|
||||
type MetricType int
|
||||
|
||||
const (
|
||||
MetricCounter = MetricType(1)
|
||||
MetricGuage = MetricType(2)
|
||||
metric_key_size = 8
|
||||
)
|
||||
|
||||
type MetricDescription struct {
|
||||
Key string
|
||||
Type MetricType
|
||||
Name string `json:",omitempty"`
|
||||
Help string `json:",omitempty"`
|
||||
ConstLabels map[string]string `json:",omitempty"`
|
||||
}
|
||||
|
||||
type writeRequest struct {
|
||||
key string
|
||||
val float64
|
||||
}
|
||||
|
||||
type metricCollection struct {
|
||||
writerChan chan *writeRequest
|
||||
}
|
||||
|
||||
var mc = metricCollection{
|
||||
writerChan: make(chan *writeRequest, 100),
|
||||
}
|
||||
|
||||
type MetricWriter func(float64)
|
||||
|
||||
func (mc *metricCollection) metricWriter() {
|
||||
// head + metric_key_size + 8byte + tail + cr = 19
|
||||
var buff [20]byte
|
||||
buff[0] = METRIC_HEAD_INLINE
|
||||
buff[17] = METRIC_TAIL_INLINE
|
||||
buff[18] = '\n'
|
||||
|
||||
for req := range mc.writerChan {
|
||||
copy(buff[1:], []byte(req.key))
|
||||
binary.BigEndian.PutUint64(buff[9:], math.Float64bits(req.val))
|
||||
os.Stdout.Write(buff[:])
|
||||
}
|
||||
}
|
||||
|
||||
var metricWriterFlag sync.Once
|
||||
|
||||
func NewMetric(mt MetricType, name string, help string, constLabel ...string) (writer MetricWriter) {
|
||||
metricWriterFlag.Do(func() {
|
||||
go mc.metricWriter()
|
||||
})
|
||||
|
||||
hash := md5.New()
|
||||
hash.Write([]byte(name))
|
||||
|
||||
var constLabels map[string]string
|
||||
if len(constLabel) > 0 {
|
||||
constLabels = make(map[string]string)
|
||||
for i := 0; i < len(constLabel); i = i + 2 {
|
||||
constLabels[constLabel[i]] = ""
|
||||
hash.Write([]byte(constLabel[i]))
|
||||
}
|
||||
|
||||
for i := 1; i < len(constLabel); i = i + 2 {
|
||||
constLabels[constLabel[i-1]] = constLabel[i]
|
||||
hash.Write([]byte(constLabel[i]))
|
||||
}
|
||||
}
|
||||
|
||||
key := hex.EncodeToString(hash.Sum(nil))[:metric_key_size]
|
||||
temp, _ := json.Marshal(MetricDescription{
|
||||
Key: key,
|
||||
Type: mt,
|
||||
Name: name,
|
||||
Help: help,
|
||||
ConstLabels: constLabels,
|
||||
})
|
||||
|
||||
writer = func(val float64) {
|
||||
mc.writerChan <- &writeRequest{
|
||||
key: key,
|
||||
val: val,
|
||||
}
|
||||
}
|
||||
|
||||
output := append([]byte{METRIC_HEAD_INLINE}, temp...)
|
||||
output = append(output, METRIC_TAIL_INLINE, '\n')
|
||||
os.Stdout.Write(output)
|
||||
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user