Skip to content

Commit 040aacb

Browse files
authored
Add current trunkgroup limit and cps metrics (#6)
Prviously only trunkgroups with active useage would appear in the metrics. This change adds two new metrics that track the current configuration even if there's no traffic. closes [ch-3334]
1 parent ba2dc37 commit 040aacb

File tree

4 files changed

+187
-9
lines changed

4 files changed

+187
-9
lines changed

collector.go

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ import (
2828
"time"
2929
"unicode"
3030

31+
"github.com/magna5/sansay_exporter/models"
32+
3133
"github.com/go-kit/kit/log"
3234
"github.com/go-kit/kit/log/level"
3335
"github.com/hooklift/gowsdl/soap"
@@ -149,7 +151,7 @@ func (c collector) Describe(ch chan<- *prometheus.Desc) {
149151

150152
// Collect implements Prometheus.Collector.
151153
func (c collector) Collect(ch chan<- prometheus.Metric) {
152-
paths := []string{"realtime", "resource", "media_server"}
154+
paths := []string{"stats/realtime", "stats/resource", "stats/media_server", "download/resource"}
153155
var wg sync.WaitGroup
154156
var err error
155157
start := time.Now()
@@ -168,6 +170,9 @@ func (c collector) Collect(ch chan<- prometheus.Metric) {
168170
case XBMediaServerRealTimeStatList:
169171
err = nil
170172
c.processMediaCollection(ch, obj)
173+
case models.XBResourceList:
174+
err = nil
175+
c.processXBResourceList(ch, obj)
171176
case error:
172177
err = obj
173178
default:
@@ -208,6 +213,17 @@ func (c collector) processMediaCollection(ch chan<- prometheus.Metric, media XBM
208213
}
209214
}
210215

216+
// processXBResourceList creates the metrics for the resource configurations.
217+
func (c collector) processXBResourceList(ch chan<- prometheus.Metric, resources models.XBResourceList) {
218+
labels := []string{"trunkgroup", "alias"}
219+
var labelValues []string
220+
for _, resource := range resources.XBResource {
221+
labelValues = []string{resource.TrunkId, resource.Name}
222+
addLabeledMetric(ch, "config_trunk_sessions_max", resource.Capacity, labels, labelValues)
223+
addLabeledMetric(ch, "config_trunk_cps_max", resource.CpsLimit, labels, labelValues)
224+
}
225+
}
226+
211227
func (c collector) processCollection(ch chan<- prometheus.Metric, sansay Sansay) {
212228
for _, table := range sansay.Database.Table {
213229
var direction string
@@ -278,6 +294,7 @@ func ScrapeTarget(c collector, path string, result chan<- interface{}, wg *sync.
278294
var obj interface{}
279295
var sansay Sansay
280296
var media XBMediaServerRealTimeStatList
297+
var resourceList models.XBResourceList
281298
var body []byte
282299
var err error
283300

@@ -299,12 +316,15 @@ func ScrapeTarget(c collector, path string, result chan<- interface{}, wg *sync.
299316
if strings.HasSuffix(path, "media_server") {
300317
err = xml.Unmarshal(body, &media)
301318
obj = media
319+
} else if strings.HasSuffix(path, "download/resource") {
320+
err = xml.Unmarshal(body, &resourceList)
321+
obj = resourceList
302322
} else {
303323
err = xml.Unmarshal(body, &sansay)
304324
obj = sansay
305325
}
306326
if err != nil {
307-
level.Error(logger).Log("msg", "Error parsing XML", "err", err)
327+
level.Error(logger).Log("msg", "Error parsing XML", "path", path, "err", err)
308328
result <- err
309329
wg.Done()
310330
return
@@ -366,23 +386,50 @@ func callRestAPI(c collector, path string) ([]byte, error) {
366386

367387
// callSoapAPI makes a SOAP call to the Sansay SBC -- used for older OS versions
368388
func callSoapAPI(c collector, path string) ([]byte, error) {
389+
var err error
390+
var response []byte
391+
var statName string
392+
393+
// Determine the stat name by splitting the path
394+
paths := strings.Split(path, "/")
395+
if len(paths) == 1 {
396+
statName = paths[0]
397+
} else {
398+
statName = paths[len(paths)-1]
399+
}
400+
369401
target := fmt.Sprintf("%s%s", c.target, "/SSConfig/SansayWS")
370402
if !strings.HasPrefix(target, "http://") && !strings.HasPrefix(target, "https://") {
371403
target = "http://" + target
372404
}
373405
client := soap.NewClient(target, soap.WithTLS(&tls.Config{InsecureSkipVerify: true}))
374406
service := NewSansayWS(client)
375-
params := &RealTimeStatsParams{
376-
Username: c.username,
377-
Password: c.password,
378-
StatName: path,
407+
if strings.HasSuffix(path, "download/resource") {
408+
params := &DownloadParams{
409+
Username: c.username,
410+
Password: c.password,
411+
Page: 0,
412+
Table: "resource",
413+
}
414+
415+
if reply, err := service.DoDownloadXmlFile(params); err == nil {
416+
response = []byte(reply.Xmlfile)
417+
}
418+
} else {
419+
params := &RealTimeStatsParams{
420+
Username: c.username,
421+
Password: c.password,
422+
StatName: statName,
423+
}
424+
if reply, err := service.DoRealTimeStats(params); err == nil {
425+
response = []byte(reply.Xmlfile)
426+
}
379427
}
380-
reply, err := service.DoRealTimeStats(params)
381428
if err != nil {
382429
level.Error(c.logger).Log("msg", "Error calling SOAP API", "err", err)
383430
return nil, err
384431
}
385-
return []byte(reply.Xmlfile), nil
432+
return response, nil
386433
}
387434

388435
func addMetric(ch chan<- prometheus.Metric, name string, value string) error {

go.sum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
1414
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
1515
github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=
1616
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
17+
github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo=
1718
github.com/go-logfmt/logfmt v0.3.0 h1:8HUsc87TaSWLKwrnumgC8/YconD2fJQsRJAsWaPg2ic=
1819
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
1920
github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=

main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import (
3232
"gopkg.in/alecthomas/kingpin.v2"
3333
)
3434

35-
const targetPath = "/SSConfig/webresources/stats/"
35+
const targetPath = "/SSConfig/webresources/"
3636

3737
var Version = "dev"
3838

models/xbresource.go

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package models
2+
3+
import "encoding/xml"
4+
5+
// XBResourceList represents the DownloadXML data for a resource
6+
type XBResourceList struct {
7+
XMLName xml.Name `xml:"XBResourceList"`
8+
Text string `xml:",chardata"`
9+
XBResource []struct {
10+
Text string `xml:",chardata"`
11+
Protocol string `xml:"protocol"`
12+
TypeSIPgw struct {
13+
Text string `xml:",chardata"`
14+
PortAddress string `xml:"portAddress"`
15+
ServiceState string `xml:"serviceState"`
16+
Direction string `xml:"direction"`
17+
NAT string `xml:"NAT"`
18+
AllowDirectMedia string `xml:"allowDirectMedia"`
19+
SipProfileIndex string `xml:"sipProfileIndex"`
20+
OptionPoll string `xml:"optionPoll"`
21+
AuthorizedRPS string `xml:"authorizedRPS"`
22+
UnauthorizedRPS string `xml:"unauthorizedRPS"`
23+
} `xml:"typeSIPgw"`
24+
Name string `xml:"name"`
25+
CompanyName string `xml:"companyName"`
26+
TrunkId string `xml:"trunkId"`
27+
SgId string `xml:"sgId"`
28+
Capacity string `xml:"capacity"`
29+
CpsLimit string `xml:"cpsLimit"`
30+
Node struct {
31+
Text string `xml:",chardata"`
32+
Fqdn string `xml:"fqdn"`
33+
Netmask string `xml:"netmask"`
34+
Capacity string `xml:"capacity"`
35+
CpsLimit string `xml:"cpsLimit"`
36+
CacProfileId string `xml:"cacProfileId"`
37+
} `xml:"node"`
38+
Rtid string `xml:"rtid"`
39+
Ingress1 struct {
40+
Text string `xml:",chardata"`
41+
Match string `xml:"match"`
42+
Action1 string `xml:"action1"`
43+
Digits1 string `xml:"digits1"`
44+
Action2 string `xml:"action2"`
45+
Digits2 string `xml:"digits2"`
46+
} `xml:"ingress1"`
47+
Ingress2 struct {
48+
Text string `xml:",chardata"`
49+
Match string `xml:"match"`
50+
Action1 string `xml:"action1"`
51+
Digits1 string `xml:"digits1"`
52+
Action2 string `xml:"action2"`
53+
Digits2 string `xml:"digits2"`
54+
} `xml:"ingress2"`
55+
Egress1 struct {
56+
Text string `xml:",chardata"`
57+
Match string `xml:"match"`
58+
Action1 string `xml:"action1"`
59+
Digits1 string `xml:"digits1"`
60+
Action2 string `xml:"action2"`
61+
Digits2 string `xml:"digits2"`
62+
} `xml:"egress1"`
63+
Egress2 struct {
64+
Text string `xml:",chardata"`
65+
Match string `xml:"match"`
66+
Action1 string `xml:"action1"`
67+
Digits1 string `xml:"digits1"`
68+
Action2 string `xml:"action2"`
69+
Digits2 string `xml:"digits2"`
70+
} `xml:"egress2"`
71+
OutboundANI string `xml:"outboundANI"`
72+
TechPrefix string `xml:"techPrefix"`
73+
RnIngress1 struct {
74+
Text string `xml:",chardata"`
75+
Match string `xml:"match"`
76+
Action1 string `xml:"action1"`
77+
Digits1 string `xml:"digits1"`
78+
Action2 string `xml:"action2"`
79+
Digits2 string `xml:"digits2"`
80+
} `xml:"rnIngress1"`
81+
RnIngress2 struct {
82+
Text string `xml:",chardata"`
83+
Match string `xml:"match"`
84+
Action1 string `xml:"action1"`
85+
Digits1 string `xml:"digits1"`
86+
Action2 string `xml:"action2"`
87+
Digits2 string `xml:"digits2"`
88+
} `xml:"rnIngress2"`
89+
RnEgress1 struct {
90+
Text string `xml:",chardata"`
91+
Match string `xml:"match"`
92+
Action1 string `xml:"action1"`
93+
Digits1 string `xml:"digits1"`
94+
Action2 string `xml:"action2"`
95+
Digits2 string `xml:"digits2"`
96+
} `xml:"rnEgress1"`
97+
RnEgress2 struct {
98+
Text string `xml:",chardata"`
99+
Match string `xml:"match"`
100+
Action1 string `xml:"action1"`
101+
Digits1 string `xml:"digits1"`
102+
Action2 string `xml:"action2"`
103+
Digits2 string `xml:"digits2"`
104+
} `xml:"rnEgress2"`
105+
CodecPolicy string `xml:"codecPolicy"`
106+
GroupPolicy string `xml:"groupPolicy"`
107+
Dtid string `xml:"dtid"`
108+
T38 string `xml:"t38"`
109+
Rfc2833 string `xml:"rfc2833"`
110+
PayloadType string `xml:"payloadType"`
111+
Tos string `xml:"tos"`
112+
SvcPortIndex string `xml:"svcPortIndex"`
113+
RadiusAuthGrpIndex string `xml:"radiusAuthGrpIndex"`
114+
RadiusAcctGrpIndex string `xml:"radiusAcctGrpIndex"`
115+
LnpGrpIndex string `xml:"lnpGrpIndex"`
116+
TeleblockGrpIndex string `xml:"teleblockGrpIndex"`
117+
CnamGrpIndex string `xml:"cnamGrpIndex"`
118+
ErsGrpIndex string `xml:"ersGrpIndex"`
119+
MaxCallDuration string `xml:"maxCallDuration"`
120+
MinCallDuration string `xml:"minCallDuration"`
121+
NoAnswerTimeout string `xml:"noAnswerTimeout"`
122+
NoRingTimeout string `xml:"noRingTimeout"`
123+
CauseCodeProfile string `xml:"causeCodeProfile"`
124+
StopRouteProfile string `xml:"stopRouteProfile"`
125+
PaiAction string `xml:"paiAction"`
126+
PaiString string `xml:"paiString"`
127+
InheritedGenericHeader string `xml:"inheritedGenericHeader"`
128+
OutSMCProfileId string `xml:"outSMCProfileId"`
129+
} `xml:"XBResource"`
130+
}

0 commit comments

Comments
 (0)