Files
zeekay 7cf87b230b node-unified is the node
The module already called itself github.com/luxfi/node while containing no node
in Go: cmd/luxd was twenty-one lines that printed the size of a few types, and
the Go column of the matrix measured a VM plugin. A repo that fetches the thing
it claims to be has not replaced it, so the Go sources move in — 1515 files,
the daemon and everything under it — and the build reaches outside this module
for nothing.

Rust and C++ sit beside it unchanged and are still measured against it by the
differential. That is the point of one repo: the reference implementation and
the two ports are the same checkout, so parity is a thing you can run rather
than a thing you assert.

Verified: builds, and the closure carries no lux-private — checked at build time
rather than believed. The daemon starts twelve chains on a local network
(P X C Q Z A B G K M F, plus D through its plugin) and reports healthy.
2026-09-07 16:15:25 -07:00

75 lines
1.7 KiB
Go

// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package metrics
import (
"bytes"
"context"
"fmt"
"io"
"net/http"
"net/url"
"github.com/luxfi/metric"
)
// cleanlyCloseBody drains and closes an HTTP response body to prevent
// HTTP/2 GOAWAY errors caused by closing bodies with unread data.
func cleanlyCloseBody(body io.ReadCloser) error {
if body == nil {
return nil
}
_, _ = io.Copy(io.Discard, body)
return body.Close()
}
// Client for requesting metrics from a remote Lux Node instance
type Client struct {
uri string
}
// NewClient returns a new Metrics API Client
func NewClient(uri string) *Client {
return &Client{
uri: uri + "/v1/metrics",
}
}
// GetMetrics returns the metrics from the connected node. The metrics are
// returned as a map of metric family name to the metric family.
func (c *Client) GetMetrics(ctx context.Context) (map[string]*metric.MetricFamily, error) {
uri, err := url.Parse(c.uri)
if err != nil {
return nil, err
}
request, err := http.NewRequestWithContext(
ctx,
http.MethodGet,
uri.String(),
bytes.NewReader(nil),
)
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}
resp, err := http.DefaultClient.Do(request)
if err != nil {
return nil, fmt.Errorf("failed to issue request: %w", err)
}
defer cleanlyCloseBody(resp.Body)
// Return an error for any non successful status code
if resp.StatusCode < 200 || resp.StatusCode > 299 {
return nil, fmt.Errorf("received status code: %d", resp.StatusCode)
}
var parser metric.TextParser
metrics, err := parser.TextToMetricFamilies(resp.Body)
if err != nil {
return nil, err
}
return metrics, nil
}