@@ -5,21 +5,26 @@ import (
5
5
"reflect"
6
6
"regexp"
7
7
"strings"
8
+ "sync"
8
9
9
10
"github.com/prometheus/client_golang/prometheus"
10
11
11
12
"github.com/c9s/bbgo/pkg/fixedpoint"
12
- "github.com/c9s/bbgo/pkg/types"
13
13
)
14
14
15
15
var matchFirstCapRE = regexp .MustCompile ("(.)([A-Z][a-z]+)" )
16
16
var matchAllCap = regexp .MustCompile ("([a-z0-9])([A-Z])" )
17
17
18
18
var dynamicStrategyConfigMetrics = map [string ]* prometheus.GaugeVec {}
19
+ var dynamicStrategyConfigMetricsMutex sync.Mutex
19
20
20
- func getOrCreateMetric (id , fieldName string ) (* prometheus.GaugeVec , error ) {
21
+ func getOrCreateMetric (id , fieldName string ) (* prometheus.GaugeVec , string , error ) {
21
22
metricName := id + "_config_" + fieldName
23
+
24
+ dynamicStrategyConfigMetricsMutex .Lock ()
22
25
metric , ok := dynamicStrategyConfigMetrics [metricName ]
26
+ defer dynamicStrategyConfigMetricsMutex .Unlock ()
27
+
23
28
if ! ok {
24
29
metric = prometheus .NewGaugeVec (
25
30
prometheus.GaugeOpts {
@@ -30,11 +35,13 @@ func getOrCreateMetric(id, fieldName string) (*prometheus.GaugeVec, error) {
30
35
)
31
36
32
37
if err := prometheus .Register (metric ); err != nil {
33
- return nil , fmt .Errorf ("unable to register metrics on field %+v, error: %+v" , fieldName , err )
38
+ return nil , "" , fmt .Errorf ("unable to register metrics on field %+v, error: %+v" , fieldName , err )
34
39
}
40
+
41
+ dynamicStrategyConfigMetrics [metricName ] = metric
35
42
}
36
43
37
- return metric , nil
44
+ return metric , metricName , nil
38
45
}
39
46
40
47
func toSnakeCase (input string ) string {
@@ -74,15 +81,31 @@ func castToFloat64(valInf any) (float64, bool) {
74
81
return val , true
75
82
}
76
83
77
- func InitializeConfigMetrics (id , instanceId string , s types.StrategyID ) error {
78
- tv := reflect .TypeOf (s ).Elem ()
79
- sv := reflect .Indirect (reflect .ValueOf (s ))
84
+ func InitializeConfigMetrics (id , instanceId string , st any ) error {
85
+ _ , err := initializeConfigMetricsWithFieldPrefix (id , instanceId , "" , st )
86
+ return err
87
+ }
88
+
89
+ func initializeConfigMetricsWithFieldPrefix (id , instanceId , fieldPrefix string , st any ) ([]string , error ) {
90
+ var metricNames []string
91
+ tv := reflect .TypeOf (st ).Elem ()
92
+
93
+ vv := reflect .ValueOf (st )
94
+ if vv .IsNil () {
95
+ return nil , nil
96
+ }
97
+
98
+ sv := reflect .Indirect (vv )
80
99
81
100
symbolField := sv .FieldByName ("Symbol" )
82
101
hasSymbolField := symbolField .IsValid ()
83
102
84
103
for i := 0 ; i < tv .NumField (); i ++ {
85
104
field := tv .Field (i )
105
+ if ! field .IsExported () {
106
+ continue
107
+ }
108
+
86
109
jsonTag := field .Tag .Get ("json" )
87
110
if jsonTag == "" {
88
111
continue
@@ -93,7 +116,16 @@ func InitializeConfigMetrics(id, instanceId string, s types.StrategyID) error {
93
116
continue
94
117
}
95
118
96
- fieldName := toSnakeCase (tagAttrs [0 ])
119
+ fieldName := fieldPrefix + toSnakeCase (tagAttrs [0 ])
120
+ if field .Type .Kind () == reflect .Pointer && field .Type .Elem ().Kind () == reflect .Struct {
121
+ subMetricNames , err := initializeConfigMetricsWithFieldPrefix (id , instanceId , fieldName + "_" , sv .Field (i ).Interface ())
122
+ if err != nil {
123
+ return nil , err
124
+ }
125
+
126
+ metricNames = append (metricNames , subMetricNames ... )
127
+ continue
128
+ }
97
129
98
130
val := 0.0
99
131
valInf := sv .Field (i ).Interface ()
@@ -107,17 +139,19 @@ func InitializeConfigMetrics(id, instanceId string, s types.StrategyID) error {
107
139
symbol = symbolField .String ()
108
140
}
109
141
110
- metric , err := getOrCreateMetric (id , fieldName )
142
+ metric , metricName , err := getOrCreateMetric (id , fieldName )
111
143
if err != nil {
112
- return err
144
+ return nil , err
113
145
}
114
146
115
147
metric .With (prometheus.Labels {
116
148
"strategy_type" : id ,
117
149
"strategy_id" : instanceId ,
118
150
"symbol" : symbol ,
119
151
}).Set (val )
152
+
153
+ metricNames = append (metricNames , metricName )
120
154
}
121
155
122
- return nil
156
+ return metricNames , nil
123
157
}
0 commit comments