diff --git a/client/client.go b/client/client.go index bc32fa1..6f92c50 100644 --- a/client/client.go +++ b/client/client.go @@ -23,6 +23,7 @@ import ( "unsafe" "repositories.action2quare.com/ayo/gocommon/logger" + "repositories.action2quare.com/ayo/gocommon/metric" "repositories.action2quare.com/ayo/houston/shared" "repositories.action2quare.com/ayo/houston/shared/protos" @@ -93,19 +94,20 @@ func (pm *procmeta) setState(s protos.ProcessState) { } type houstonClient struct { - childProcs []*procmeta - extraMetrics unsafe.Pointer // map[string]float32 - deploys map[string][]*protos.VersionAndArgs - shutdownFunc context.CancelFunc - ctx context.Context - operationChan chan *protos.OperationQueryResponse - exitChan chan *exec.Cmd - clientChan chan *grpc.ClientConn - timestamp string - wg sync.WaitGroup - config clientConfig - version string - standalone bool + childProcs []*procmeta + extraMetrics unsafe.Pointer // map[string]float32 + deploys map[string][]*protos.VersionAndArgs + shutdownFunc context.CancelFunc + ctx context.Context + operationChan chan *protos.OperationQueryResponse + exitChan chan *exec.Cmd + clientChan chan *grpc.ClientConn + timestamp string + wg sync.WaitGroup + config clientConfig + version string + standalone bool + metricExporter metric.Exporter } func unmarshal[T any](val *T, src map[string]string) { @@ -258,13 +260,14 @@ func NewClient(standalone bool) (HoustonClient, error) { } hc := &houstonClient{ - config: clientConfig, - clientChan: make(chan *grpc.ClientConn), - extraMetrics: unsafe.Pointer(&map[string]float32{}), - deploys: deploys, - timestamp: exefi.ModTime().String(), - version: string(ver), - standalone: standalone, + config: clientConfig, + clientChan: make(chan *grpc.ClientConn), + extraMetrics: unsafe.Pointer(&map[string]float32{}), + deploys: deploys, + timestamp: exefi.ModTime().String(), + version: string(ver), + standalone: standalone, + metricExporter: metric.NewPrometheusExport(clientConfig.MetricNamespace), } ctx, cancel := context.WithCancel(context.Background()) diff --git a/client/custom_exporter.go b/client/custom_exporter.go deleted file mode 100644 index 68441f7..0000000 --- a/client/custom_exporter.go +++ /dev/null @@ -1,85 +0,0 @@ -package client - -import ( - "math" - _ "net/http/pprof" - "sync/atomic" - "unsafe" - - "github.com/prometheus/client_golang/prometheus" - "repositories.action2quare.com/ayo/gocommon/metric" -) - -type metricDesc struct { - *prometheus.Desc - val *uint64 - valueType prometheus.ValueType -} - -type exporterForPrometheus struct { - metricPtr unsafe.Pointer // []metricDesc -} - -func newExporterForPrometheus() *exporterForPrometheus { - return &exporterForPrometheus{ - metricPtr: unsafe.Pointer(new([]metricDesc)), - } -} - -type metricValueAccessor struct { - ptr *uint64 -} - -func (va *metricValueAccessor) set(val float64) { - atomic.StoreUint64(va.ptr, math.Float64bits(val)) -} - -func convertValueType(in metric.MetricType) prometheus.ValueType { - switch in { - case metric.MetricCounter: - return prometheus.CounterValue - - case metric.MetricGuage: - return prometheus.GaugeValue - } - - return prometheus.UntypedValue -} - -func (e *exporterForPrometheus) registMetric(namespace string, desc metric.MetricDescription) metricValueAccessor { - ptr := atomic.LoadPointer(&e.metricPtr) - container := *(*[]metricDesc)(ptr) - - newcont := make([]metricDesc, len(container)+1) - copy(newcont, container) - - newval := new(uint64) - newcont[len(container)] = metricDesc{ - Desc: prometheus.NewDesc(prometheus.BuildFQName(namespace, "", desc.Name), desc.Help, nil, desc.ConstLabels), - val: newval, - valueType: convertValueType(desc.Type), - } - - atomic.StorePointer(&e.metricPtr, unsafe.Pointer(&newcont)) - return metricValueAccessor{ - ptr: newval, - } -} - -func (e *exporterForPrometheus) Describe(ch chan<- *prometheus.Desc) { - ptr := atomic.LoadPointer(&e.metricPtr) - container := *(*[]metricDesc)(ptr) - - for _, v := range container { - ch <- v.Desc - } -} - -func (e *exporterForPrometheus) Collect(ch chan<- prometheus.Metric) { - ptr := atomic.LoadPointer(&e.metricPtr) - container := *(*[]metricDesc)(ptr) - - for _, v := range container { - ch <- prometheus.MustNewConstMetric(v.Desc, v.valueType, math.Float64frombits(atomic.LoadUint64(v.val))) - } -} diff --git a/client/operation.go b/client/operation.go index 0996521..e030857 100644 --- a/client/operation.go +++ b/client/operation.go @@ -4,12 +4,10 @@ import ( "archive/zip" "bufio" "context" - "encoding/binary" "encoding/json" "errors" "fmt" "io" - "math" "net/http" "os" "os/exec" @@ -20,7 +18,6 @@ import ( "syscall" "time" - "github.com/prometheus/client_golang/prometheus" "repositories.action2quare.com/ayo/gocommon/logger" "repositories.action2quare.com/ayo/gocommon/metric" "repositories.action2quare.com/ayo/houston/shared" @@ -233,8 +230,6 @@ func (hc *houstonClient) launch(meta *procmeta) error { readingMetric := false var metricBuffer []byte - metricValues := make(map[string]metricValueAccessor) - defer func() { logger.Println("stdReader is terminated :", meta.name) if meta.isState(protos.ProcessState_Running) { @@ -273,27 +268,10 @@ func (hc *houstonClient) launch(meta *procmeta) error { continue } - if _, registered := metricValues[metric.Key]; !registered { - exporter := newExporterForPrometheus() - accessor := exporter.registMetric(hc.config.MetricNamespace, metric) - - if err := prometheus.Register(exporter); err != nil { - logger.Println("prometheus.Register error :", err) - } else { - metricValues[metric.Key] = accessor - logger.Println("metric registered :", metric) - } - } + hc.metricExporter.RegisterMetric(&metric) } else { - keybytes := metricBuffer[:8] - valbits := binary.LittleEndian.Uint64(metricBuffer[8:]) - val := math.Float64frombits(valbits) - - if accessor, ok := metricValues[string(keybytes)]; ok { - accessor.set(val) - } else { - logger.Println("metric set but unregistered :", string(keybytes)) - } + key, val := metric.ReadMetricValue(metricBuffer) + hc.metricExporter.UpdateMetric(key, val) } metricBuffer = metricBuffer[:0] diff --git a/go.mod b/go.mod index 41943b4..ba9d7ea 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( golang.org/x/text v0.10.0 google.golang.org/grpc v1.56.0 google.golang.org/protobuf v1.31.0 - repositories.action2quare.com/ayo/gocommon v0.0.0-20231127145009-2c0211678122 + repositories.action2quare.com/ayo/gocommon v0.0.0-20231128132952-e5a5240f96d8 ) require ( diff --git a/go.sum b/go.sum index 1ac531f..8c2173b 100644 --- a/go.sum +++ b/go.sum @@ -120,5 +120,5 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM= howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g= -repositories.action2quare.com/ayo/gocommon v0.0.0-20231127145009-2c0211678122 h1:pbROgLih1x7ooXNrKBO7sPK6bOW5bzuMHQY8DKWkRbc= -repositories.action2quare.com/ayo/gocommon v0.0.0-20231127145009-2c0211678122/go.mod h1:XvklTTSvQX5uviivGBcZo8eIL+mV94W2e4uBBXcT5JY= +repositories.action2quare.com/ayo/gocommon v0.0.0-20231128132952-e5a5240f96d8 h1:GbvfiscAV/gquGzC9bJ3RTNtezLcdfGOv+9JmAZYQVc= +repositories.action2quare.com/ayo/gocommon v0.0.0-20231128132952-e5a5240f96d8/go.mod h1:XvklTTSvQX5uviivGBcZo8eIL+mV94W2e4uBBXcT5JY=