-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathplugin.go
147 lines (130 loc) · 4.68 KB
/
plugin.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
136
137
138
139
140
141
142
143
144
145
146
147
package plugin
import (
"fmt"
"time"
"github.com/robfig/cron/v3"
"github.com/vincenzopalazzo/glightning/glightning"
"github.com/LNOpenMetrics/go-lnmetrics.reporter/internal/db"
"github.com/LNOpenMetrics/go-lnmetrics.reporter/pkg/graphql"
"github.com/LNOpenMetrics/lnmetrics.utils/log"
)
type MetricsPlugin struct {
Plugin *glightning.Plugin
Metrics map[int]Metric
Rpc *glightning.Lightning
Cron *cron.Cron
Server *graphql.Client
Storage db.PluginDatabase
WithProxy bool
}
func (plugin *MetricsPlugin) HendlerRPCMessage(event *glightning.RpcCommandEvent) error {
command := event.Cmd
switch command.MethodName {
case "stop":
// Share to all the metrics, so we need a global method that iterate over the metrics map
params := make(map[string]interface{})
params["timestamp"] = time.Now()
msg := Msg{"stop", params}
for _, metric := range plugin.Metrics {
go plugin.callOnStopOnMetrics(metric, &msg)
}
plugin.Cron.Stop()
log.GetInstance().Info("Close command received")
default:
return nil
}
return nil
}
func (plugin *MetricsPlugin) RegisterMetrics(id int, metric Metric) error {
_, ok := plugin.Metrics[id]
if ok {
log.GetInstance().Error(fmt.Sprintf("Metrics with is %d already registered.", id))
return fmt.Errorf("Metrics with is %d already registered.", id)
}
plugin.Metrics[id] = metric
return nil
}
func (plugin *MetricsPlugin) RegisterMethods() error {
method := NewMetricPlugin(plugin)
rpcMethod := glightning.NewRpcMethod(method, "Show diagnostic node")
rpcMethod.LongDesc = "Show the diagnostic data of the lightning network node"
rpcMethod.Category = "metrics"
if err := plugin.Plugin.RegisterMethod(rpcMethod); err != nil {
return err
}
infoMethod := NewPluginRpcMethod(plugin)
infoRpcMethod := glightning.NewRpcMethod(infoMethod, "Show go-lnmetrics.reporter info")
infoRpcMethod.Category = "metrics"
infoRpcMethod.LongDesc = "Return a map where the key is the id of the method and the value is the payload of the metric. The metrics_id is a string that conatins the id divided by a comma. An example is \"diagnostic \"1,2,3\"\""
if err := plugin.Plugin.RegisterMethod(infoRpcMethod); err != nil {
return err
}
return nil
}
//nolint
func (plugin *MetricsPlugin) callUpdateOnMetric(metric Metric, msg *Msg) {
if err := metric.UpdateWithMsg(msg, plugin.Rpc); err != nil {
log.GetInstance().Error(fmt.Sprintf("Error during update metrics event: %s", err))
}
}
// Call on stop operation on the node when the caller are shoutdown it self.
func (plugin *MetricsPlugin) callOnStopOnMetrics(metric Metric, msg *Msg) {
err := metric.OnStop(msg, plugin.Rpc)
if err != nil {
log.GetInstance().Error(err)
}
}
// Update the metrics without any information received by the caller
func (plugin *MetricsPlugin) callUpdateOnMetricNoMsg(metric Metric) {
log.GetInstance().Debug("Calling Update on metrics")
err := metric.Update(plugin.Rpc)
if err != nil {
log.GetInstance().Error(fmt.Sprintf("Error %s", err))
}
}
func (plugin *MetricsPlugin) updateAndUploadMetric(metric Metric) {
log.GetInstance().Info("Calling update and upload metric")
plugin.callUpdateOnMetricNoMsg(metric)
if err := metric.UploadOnRepo(plugin.Server, plugin.Rpc); err != nil {
log.GetInstance().Error(fmt.Sprintf("Error %s", err))
}
}
// Register internal recurrent methods
func (plugin *MetricsPlugin) RegisterRecurrentEvt(after string) {
log.GetInstance().Info(fmt.Sprintf("Register recurrent event each %s", after))
plugin.Cron = cron.New()
// FIXME: Discover what is the first value
_, err := plugin.Cron.AddFunc(after, func() {
log.GetInstance().Info("Update and Uploading metrics")
for _, metric := range plugin.Metrics {
go plugin.updateAndUploadMetric(metric)
}
})
if err != nil {
log.GetInstance().Error(fmt.Sprintf("Error during registering recurrent event: %s", err))
}
}
func (plugin *MetricsPlugin) RegisterOneTimeEvt(after string) {
log.GetInstance().Info(fmt.Sprintf("Register one time event after %s", after))
duration, err := time.ParseDuration(after)
if err != nil {
log.GetInstance().Error(fmt.Sprintf("Error in the on time evt: %s", err))
return
}
time.AfterFunc(duration, func() {
log.GetInstance().Debug("Calling on time function function")
// TODO: Should C-Lightning send a on init event like notification?
for _, metric := range plugin.Metrics {
go func(instance *MetricsPlugin, metric Metric) {
err := metric.OnInit(instance.Rpc)
if err != nil {
log.GetInstance().Error(fmt.Sprintf("Error during on init call: %s", err))
}
// Init on server.
if err := metric.InitOnRepo(instance.Server, instance.Rpc); err != nil {
log.GetInstance().Error(fmt.Sprintf("Error: %s", err))
}
}(plugin, metric)
}
})
}