master
go 121 lines 2.28 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 //go:build linux || freebsd || openbsd || netbsd || dragonfly
4
5 package litespeed
6
7 import (
8 "bufio"
9 "bytes"
10 "errors"
11 "os"
12 "path/filepath"
13 "strconv"
14 "strings"
15 )
16
17 const precision = 100
18
19 func (c *Collector) collect() (map[string]int64, error) {
20 if c.checkDir {
21 _, err := os.Stat(c.ReportsDir)
22 if err != nil {
23 return nil, err
24 }
25 c.checkDir = false
26 }
27 reports, err := filepath.Glob(filepath.Join(c.ReportsDir, ".rtreport*"))
28 if err != nil {
29 return nil, err
30 }
31
32 c.Debugf("found %d reports: %v", len(reports), reports)
33
34 if len(reports) == 0 {
35 return nil, errors.New("no reports found")
36 }
37
38 mx := make(map[string]int64)
39
40 for _, report := range reports {
41 if err := c.collectReport(mx, report); err != nil {
42 return nil, err
43 }
44 }
45
46 return mx, nil
47 }
48
49 func (c *Collector) collectReport(mx map[string]int64, filename string) error {
50 bs, err := os.ReadFile(filename)
51 if err != nil {
52 return err
53 }
54
55 sc := bufio.NewScanner(bytes.NewReader(bs))
56
57 var valid bool
58
59 for sc.Scan() {
60 line := sc.Text()
61
62 switch {
63 default:
64 continue
65 case strings.HasPrefix(line, "BPS_IN:"):
66 case strings.HasPrefix(line, "PLAINCONN:"):
67 case strings.HasPrefix(line, "MAXCONN:"):
68 case strings.HasPrefix(line, "REQ_RATE []:"):
69 line = strings.TrimPrefix(line, "REQ_RATE []:")
70 }
71
72 parts := strings.SplitSeq(line, ",")
73
74 for part := range parts {
75 before, after, ok := strings.Cut(part, ":")
76 if !ok {
77 c.Debugf("Skipping metric '%s': missing colon separator", part)
78 continue
79 }
80
81 metric, sVal := strings.TrimSpace(before), strings.TrimSpace(after)
82
83 val, err := strconv.ParseFloat(sVal, 64)
84 if err != nil {
85 c.Debugf("Skipping metric '%s': invalid value", part)
86 continue
87 }
88
89 key := strings.ToLower(metric)
90
91 switch metric {
92 default:
93 continue
94 case "REQ_PER_SEC",
95 "PUB_CACHE_HITS_PER_SEC",
96 "PRIVATE_CACHE_HITS_PER_SEC",
97 "STATIC_HITS_PER_SEC":
98 mx[key] += int64(val * precision)
99 case "BPS_IN",
100 "BPS_OUT",
101 "SSL_BPS_IN",
102 "SSL_BPS_OUT":
103 mx[key] += int64(val) * 8
104 case "REQ_PROCESSING",
105 "PLAINCONN",
106 "AVAILCONN",
107 "SSLCONN",
108 "AVAILSSL":
109 mx[key] += int64(val)
110 }
111 valid = true
112
113 }
114 }
115
116 if !valid {
117 return errors.New("unexpected file: not a litespeed report")
118 }
119
120 return nil
121 }