-
Notifications
You must be signed in to change notification settings - Fork 1
/
prometheus.go
135 lines (124 loc) · 5.21 KB
/
prometheus.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Copyright 2023 Blink Labs Software
//
// 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 main
import (
"context"
"encoding/json"
"fmt"
"net/http"
"strings"
dto "github.com/prometheus/client_model/go"
"github.com/prometheus/common/expfmt"
)
// Track current epoch
var currentEpoch uint32 = 0
func setCurrentEpoch() {
if promMetrics != nil {
currentEpoch = uint32(promMetrics.EpochNum)
}
}
var promMetrics *PromMetrics
type PromMetrics struct {
BlockNum uint64 `json:"cardano_node_metrics_blockNum_int"`
EpochNum uint64 `json:"cardano_node_metrics_epoch_int"`
SlotInEpoch uint64 `json:"cardano_node_metrics_slotInEpoch_int"`
SlotNum uint64 `json:"cardano_node_metrics_slotNum_int"`
Density float64 `json:"cardano_node_metrics_density_real"`
TxProcessed uint64 `json:"cardano_node_metrics_txsProcessedNum_int"`
MempoolTx uint64 `json:"cardano_node_metrics_txsInMempool_int"`
MempoolBytes uint64 `json:"cardano_node_metrics_mempoolBytes_int"`
KesPeriod uint64 `json:"cardano_node_metrics_currentKESPeriod_int"`
RemainingKesPeriods uint64 `json:"cardano_node_metrics_remainingKESPeriods_int"`
IsLeader uint64 `json:"cardano_node_metrics_Forge_node_is_leader_int"`
Adopted uint64 `json:"cardano_node_metrics_Forge_adopted_int"`
DidntAdopt uint64 `json:"cardano_node_metrics_Forge_didnt_adopt_int"`
AboutToLead uint64 `json:"cardano_node_metrics_Forge_forge_about_to_lead_int"`
MissedSlots uint64 `json:"cardano_node_metrics_slotsMissedNum_int"`
MemLive uint64 `json:"cardano_node_metrics_RTS_gcLiveBytes_int"`
MemHeap uint64 `json:"cardano_node_metrics_RTS_gcHeapBytes_int"`
GcMinor uint64 `json:"cardano_node_metrics_RTS_gcMinorNum_int"`
GcMajor uint64 `json:"cardano_node_metrics_RTS_gcMajorNum_int"`
Forks uint64 `json:"cardano_node_metrics_forks_int"`
BlockDelay float64 `json:"cardano_node_metrics_blockfetchclient_blockdelay_s"`
BlocksServed uint64 `json:"cardano_node_metrics_served_block_count_int"`
BlocksLate uint64 `json:"cardano_node_metrics_blockfetchclient_lateblocks"`
BlocksW1s float64 `json:"cardano_node_metrics_blockfetchclient_blockdelay_cdfOne"`
BlocksW3s float64 `json:"cardano_node_metrics_blockfetchclient_blockdelay_cdfThree"`
BlocksW5s float64 `json:"cardano_node_metrics_blockfetchclient_blockdelay_cdfFive"`
PeersCold uint64 `json:"cardano_node_metrics_peerSelection_cold"`
PeersWarm uint64 `json:"cardano_node_metrics_peerSelection_warm"`
PeersHot uint64 `json:"cardano_node_metrics_peerSelection_hot"`
ConnIncoming uint64 `json:"cardano_node_metrics_connectionManager_incomingConns"`
ConnOutgoing uint64 `json:"cardano_node_metrics_connectionManager_outgoingConns"`
ConnUniDir uint64 `json:"cardano_node_metrics_connectionManager_unidirectionalConns"`
ConnBiDir uint64 `json:"cardano_node_metrics_connectionManager_duplexConns"`
ConnDuplex uint64 `json:"cardano_node_metrics_connectionManager_prunableConns"`
}
// Gets metrics from prometheus and return a PromMetrics instance
func getPromMetrics(ctx context.Context) (*PromMetrics, error) {
var metrics *PromMetrics
var respBodyBytes []byte
respBodyBytes, statusCode, err := getNodeMetrics(ctx)
if err != nil {
failCount++
return metrics, fmt.Errorf("Failed getNodeMetrics: %s\n", err)
}
if statusCode != http.StatusOK {
failCount++
return metrics, fmt.Errorf("Failed HTTP: %d\n", statusCode)
}
b, err := prom2json(respBodyBytes)
if err != nil {
failCount++
return metrics, fmt.Errorf("Failed prom2json: %s\n", err)
}
if err := json.Unmarshal(b, &metrics); err != nil {
failCount++
return metrics, fmt.Errorf("Failed JSON unmarshal: %s\n", err)
}
failCount = 0
return metrics, nil
}
// Converts a prometheus http response byte array into a JSON byte array
func prom2json(prom []byte) ([]byte, error) {
// {"name": 0}
out := make(map[string]interface{})
b := []byte{}
parser := &expfmt.TextParser{}
families, err := parser.TextToMetricFamilies(
strings.NewReader(string(prom)),
)
if err != nil {
return b, err
}
for _, val := range families {
for _, m := range val.GetMetric() {
switch val.GetType() {
case dto.MetricType_COUNTER:
out[val.GetName()] = m.GetCounter().GetValue()
case dto.MetricType_GAUGE:
out[val.GetName()] = m.GetGauge().GetValue()
case dto.MetricType_UNTYPED:
out[val.GetName()] = m.GetUntyped().GetValue()
default:
return b, err
}
}
}
b, err = json.MarshalIndent(out, "", " ")
if err != nil {
return b, err
}
return b, nil
}