aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Crute <mike@crute.us>2020-10-13 22:20:55 +0000
committerMike Crute <mike@crute.us>2020-10-13 22:20:55 +0000
commitf8e6b9a6f1896c484de11131e36c4e065541af4b (patch)
treef27f1d320a8d85e3dcf2f8650423bd3223af8929
parent3b035c8fa1f75c4c00e57acc14fb71dfd62e31ee (diff)
downloadprometheus_node_collector-f8e6b9a6f1896c484de11131e36c4e065541af4b.tar.bz2
prometheus_node_collector-f8e6b9a6f1896c484de11131e36c4e065541af4b.tar.xz
prometheus_node_collector-f8e6b9a6f1896c484de11131e36c4e065541af4b.zip
Add conntrack_exec collector for Linux
-rw-r--r--collector/conntrack_exec_linux.go195
1 files changed, 195 insertions, 0 deletions
diff --git a/collector/conntrack_exec_linux.go b/collector/conntrack_exec_linux.go
new file mode 100644
index 0000000..1bce87a
--- /dev/null
+++ b/collector/conntrack_exec_linux.go
@@ -0,0 +1,195 @@
1// Copyright 2015 The Prometheus Authors
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14// +build !noconntrack
15
16package collector
17
18import (
19 "encoding/xml"
20 "os/exec"
21 "strconv"
22 "time"
23
24 "github.com/go-kit/kit/log"
25 "github.com/prometheus/client_golang/prometheus"
26)
27
28type ConntrackStats struct {
29 CollectTime int64
30 Flows []FlowRecord
31}
32
33type FlowRecord struct {
34 L3Proto string
35 L4Proto string
36 SourceAddr string
37 SourcePort int
38 DestAddr string
39 DestPort int
40 PacketsIn int64
41 PacketsOut int64
42 BytesIn int64
43 BytesOut int64
44}
45
46func (m *ConntrackStats) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
47 m.CollectTime = time.Now().Unix()
48
49 rd := struct {
50 Flows []struct {
51 Metas []struct {
52 Direction string `xml:"direction,attr"`
53 Layer3Meta struct {
54 ProtoName string `xml:"protoname,attr"`
55 SourceAddr string `xml:"src"`
56 DestAddr string `xml:"dst"`
57 } `xml:"layer3"`
58 Layer4Meta struct {
59 ProtoName string `xml:"protoname,attr"`
60 SourcePort int `xml:"sport"`
61 DestPort int `xml:"dport"`
62 } `xml:"layer4"`
63 Packets int64 `xml:"counters>packets"`
64 Bytes int64 `xml:"counters>bytes"`
65 } `xml:"meta"`
66 } `xml:"flow"`
67 }{}
68
69 err := d.DecodeElement(&rd, &start)
70 if err != nil {
71 return err
72 }
73
74 for _, f := range rd.Flows {
75 or := FlowRecord{}
76
77 for _, m := range f.Metas {
78 if m.Direction == "original" {
79 or.L3Proto = m.Layer3Meta.ProtoName
80 or.L4Proto = m.Layer4Meta.ProtoName
81 or.SourceAddr = m.Layer3Meta.SourceAddr
82 or.SourcePort = m.Layer4Meta.SourcePort
83 or.DestAddr = m.Layer3Meta.DestAddr
84 or.DestPort = m.Layer4Meta.DestPort
85 or.PacketsIn = m.Packets
86 or.BytesIn = m.Bytes
87 } else if m.Direction == "reply" {
88 or.PacketsOut = m.Packets
89 or.BytesOut = m.Bytes
90 }
91 }
92
93 m.Flows = append(m.Flows, or)
94 }
95
96 return nil
97}
98
99func loadStats(proto string, s *ConntrackStats) error {
100 cmd := exec.Command("/usr/sbin/conntrack", "-L", "-f", proto, "-o", "xml")
101 out, err := cmd.StdoutPipe()
102 if err != nil {
103 return err
104 }
105
106 if err := cmd.Start(); err != nil {
107 return err
108 }
109
110 dec := xml.NewDecoder(out)
111 if err = dec.Decode(s); err != nil {
112 return err
113 }
114
115 if err := cmd.Wait(); err != nil {
116 return err
117 }
118
119 return nil
120}
121
122func init() {
123 registerCollector("conntrack_exec", defaultDisabled, NewConntrackExecCollector)
124}
125
126func NewConntrackExecCollector(logger log.Logger) (Collector, error) {
127 subsystem := "conntrack_exec"
128 labels := []string{"l3", "l4", "saddr", "sport", "daddr", "dport"}
129
130 return &conntrackExecCollector{
131 bytesIn: prometheus.NewDesc(
132 prometheus.BuildFQName(namespace, subsystem, "bytes_in"),
133 "Conntrack bytes in for flow",
134 labels, nil,
135 ),
136 bytesOut: prometheus.NewDesc(
137 prometheus.BuildFQName(namespace, subsystem, "bytes_out"),
138 "Conntrack bytes out for flow",
139 labels, nil,
140 ),
141 packetsIn: prometheus.NewDesc(
142 prometheus.BuildFQName(namespace, subsystem, "packets_in"),
143 "Conntrack packets in for flow",
144 labels, nil,
145 ),
146 packetsOut: prometheus.NewDesc(
147 prometheus.BuildFQName(namespace, subsystem, "packets_out"),
148 "Conntrack packets out for flow",
149 labels, nil,
150 ),
151 }, nil
152}
153
154type conntrackExecCollector struct {
155 bytesIn, bytesOut *prometheus.Desc
156 packetsIn, packetsOut *prometheus.Desc
157 logger log.Logger
158}
159
160func (c *conntrackExecCollector) Update(ch chan<- prometheus.Metric) error {
161 stats := &ConntrackStats{}
162
163 if err := loadStats("ipv4", stats); err != nil {
164 return err
165 }
166
167 if err := loadStats("ipv6", stats); err != nil {
168 return err
169 }
170
171 for _, f := range stats.Flows {
172 ch <- prometheus.MustNewConstMetric(
173 c.bytesIn, prometheus.CounterValue,
174 float64(f.BytesIn),
175 f.L3Proto, f.L4Proto, f.SourceAddr, strconv.Itoa(f.SourcePort), f.DestAddr, strconv.Itoa(f.DestPort),
176 )
177 ch <- prometheus.MustNewConstMetric(
178 c.bytesOut, prometheus.CounterValue,
179 float64(f.BytesOut),
180 f.L3Proto, f.L4Proto, f.SourceAddr, strconv.Itoa(f.SourcePort), f.DestAddr, strconv.Itoa(f.DestPort),
181 )
182 ch <- prometheus.MustNewConstMetric(
183 c.packetsIn, prometheus.CounterValue,
184 float64(f.PacketsIn),
185 f.L3Proto, f.L4Proto, f.SourceAddr, strconv.Itoa(f.SourcePort), f.DestAddr, strconv.Itoa(f.DestPort),
186 )
187 ch <- prometheus.MustNewConstMetric(
188 c.packetsOut, prometheus.CounterValue,
189 float64(f.PacketsOut),
190 f.L3Proto, f.L4Proto, f.SourceAddr, strconv.Itoa(f.SourcePort), f.DestAddr, strconv.Itoa(f.DestPort),
191 )
192 }
193
194 return nil
195}