Skip to content

Commit 3ab08d1

Browse files
andrewkrohtsg
authored andcommitted
Add system socket MetricSet
The system.socket metricset reports an event for each new TCP socket that it sees. It does this by polling the kernel to get a dump of all sockets. So using a short polling interval with this metricset is important to not miss short lived connections. The metricset reports the process that has the socket open. It does this by associating the socket's inode to the process that has a file descriptor open pointing to the socket's inode. It reads /proc and /proc/<pid>/fd just prior to polling the kernel to get all sockets. A reverse lookup can be performed by the metricset on the remote IP and the returned hostname will be added to the event and cached. The is disabled by default and can be enabled through the configuration. If a hostname is found then the eTLD+1 (effective top-level domain plus one level) value will also be added to the event. For the IP address fields the index template for Elasticsearch 5.x uses the ip field type. But for Elasticsearch 2.x it uses string because the ip field type in 2.x does not support IPv6 addresses.
1 parent cc71542 commit 3ab08d1

29 files changed

+1479
-1
lines changed

CHANGELOG.asciidoc

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ https://github.com/elastic/beats/compare/v5.1.1...master[Check the HEAD diff]
5757
- Add a couchbase module with metricsets for node, cluster and bucket. {pull}3081[3081]
5858
- Export number of cores for cpu module. {pull}3192[3192]
5959
- Experimental Prometheus module. {pull}3202[3202]
60+
- Add system socket module that reports all TCP sockets. {pull}3246[3246]
6061

6162
*Packetbeat*
6263

libbeat/scripts/generate_template.py

+12
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,18 @@ def fill_field_properties(args, field, defaults, path):
205205
"ignore_above": 1024
206206
}
207207

208+
elif field["type"] == "ip":
209+
if args.es2x:
210+
properties[field["name"]] = {
211+
"type": "string",
212+
"index": "not_analyzed",
213+
"ignore_above": 1024
214+
}
215+
else:
216+
properties[field["name"]] = {
217+
"type": "ip"
218+
}
219+
208220
elif field["type"] in ["geo_point", "date", "long", "integer",
209221
"double", "float", "half_float", "scaled_float",
210222
"boolean"]:

metricbeat/_meta/beat.full.yml

+8
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ metricbeat.modules:
3939

4040
# Per process stats
4141
- process
42+
43+
# Sockets and connection info (linux only)
44+
#- socket
4245
enabled: true
4346
period: 10s
4447
processes: ['.*']
@@ -49,6 +52,11 @@ metricbeat.modules:
4952
# EXPERIMENTAL: cgroups can be enabled for the process metricset.
5053
#cgroups: false
5154

55+
# Configure reverse DNS lookup on remote IP addresses in the socket metricset.
56+
#socket.reverse_lookup.enabled: false
57+
#socket.reverse_lookup.success_ttl: 60s
58+
#socket.reverse_lookup.failure_ttl: 60s
59+
5260
#------------------------------- Apache Module -------------------------------
5361
#- module: apache
5462
#metricsets: ["status"]

metricbeat/_meta/beat.yml

+3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ metricbeat.modules:
3939

4040
# Per process stats
4141
- process
42+
43+
# Sockets (linux only)
44+
#- socket
4245
enabled: true
4346
period: 10s
4447
processes: ['.*']

metricbeat/docs/fields.asciidoc

+142
Original file line numberDiff line numberDiff line change
@@ -6206,6 +6206,148 @@ type: long
62066206
Total number of I/O operations performed on all devices by processes in the cgroup as seen by the throttling policy.
62076207
62086208
6209+
[float]
6210+
== socket Fields
6211+
6212+
TCP sockets that are active.
6213+
6214+
6215+
6216+
[float]
6217+
=== system.socket.direction
6218+
6219+
type: keyword
6220+
6221+
example: incoming
6222+
6223+
How the socket was initiated. Possible values are incoming, outgoing, or listening.
6224+
6225+
6226+
[float]
6227+
=== system.socket.family
6228+
6229+
type: keyword
6230+
6231+
example: ipv4
6232+
6233+
Address family.
6234+
6235+
6236+
[float]
6237+
=== system.socket.local.ip
6238+
6239+
type: ip
6240+
6241+
example: 192.0.2.1 or 2001:0DB8:ABED:8536::1
6242+
6243+
Local IP address. This can be an IPv4 or IPv6 address.
6244+
6245+
6246+
[float]
6247+
=== system.socket.local.port
6248+
6249+
type: long
6250+
6251+
example: 22
6252+
6253+
Local port.
6254+
6255+
6256+
[float]
6257+
=== system.socket.remote.ip
6258+
6259+
type: ip
6260+
6261+
example: 192.0.2.1 or 2001:0DB8:ABED:8536::1
6262+
6263+
Remote IP address. This can be an IPv4 or IPv6 address
6264+
6265+
6266+
[float]
6267+
=== system.socket.remote.port
6268+
6269+
type: long
6270+
6271+
example: 22
6272+
6273+
Remote port.
6274+
6275+
6276+
[float]
6277+
=== system.socket.remote.host
6278+
6279+
type: keyword
6280+
6281+
example: 76-211-117-36.nw.example.com.
6282+
6283+
PTR record associated with the remote IP. It is obtained via reverse IP lookup.
6284+
6285+
6286+
[float]
6287+
=== system.socket.remote.etld_plus_one
6288+
6289+
type: keyword
6290+
6291+
example: example.com.
6292+
6293+
The effective top-level domain (eTLD) of the remote host plus one more label. For example, the eTLD+1 for "foo.bar.golang.org." is "golang.org.". The data for determining the eTLD comes from an embedded copy of the data from http://publicsuffix.org.
6294+
6295+
6296+
[float]
6297+
=== system.socket.remote.host_error
6298+
6299+
type: keyword
6300+
6301+
Error describing the cause of the reverse lookup failure.
6302+
6303+
6304+
[float]
6305+
=== system.socket.process.pid
6306+
6307+
type: long
6308+
6309+
ID of the process that opened the socket.
6310+
6311+
6312+
[float]
6313+
=== system.socket.process.command
6314+
6315+
type: keyword
6316+
6317+
Name of the command (limited to 20 chars by the OS).
6318+
6319+
6320+
[float]
6321+
=== system.socket.process.cmdline
6322+
6323+
type: keyword
6324+
6325+
6326+
6327+
[float]
6328+
=== system.socket.process.exe
6329+
6330+
type: keyword
6331+
6332+
Absolute path to the executable.
6333+
6334+
6335+
[float]
6336+
=== system.socket.user.id
6337+
6338+
type: long
6339+
6340+
UID of the user running the process.
6341+
6342+
6343+
[float]
6344+
=== system.socket.user.name
6345+
6346+
type: keyword
6347+
6348+
Name of the user running the process.
6349+
6350+
62096351
[[exported-fields-zookeeper]]
62106352
== ZooKeeper Fields
62116353

metricbeat/docs/modules/system.asciidoc

+7
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ metricbeat.modules:
9393
9494
# Per process stats
9595
- process
96+
97+
# Sockets (linux only)
98+
#- socket
9699
enabled: true
97100
period: 10s
98101
processes: ['.*']
@@ -121,6 +124,8 @@ The following metricsets are available:
121124

122125
* <<metricbeat-metricset-system-process,process>>
123126

127+
* <<metricbeat-metricset-system-socket,socket>>
128+
124129
include::system/core.asciidoc[]
125130

126131
include::system/cpu.asciidoc[]
@@ -139,3 +144,5 @@ include::system/network.asciidoc[]
139144

140145
include::system/process.asciidoc[]
141146

147+
include::system/socket.asciidoc[]
148+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
////
2+
This file is generated! See scripts/docs_collector.py
3+
////
4+
5+
[[metricbeat-metricset-system-socket]]
6+
include::../../../module/system/socket/_meta/docs.asciidoc[]
7+
8+
9+
==== Fields
10+
11+
For a description of each field in the metricset, see the
12+
<<exported-fields-system,exported fields>> section.
13+
14+
Here is an example document generated by this metricset:
15+
16+
[source,json]
17+
----
18+
include::../../../module/system/socket/_meta/data.json[]
19+
----

metricbeat/include/list.go

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import (
5252
_ "github.com/elastic/beats/metricbeat/module/system/memory"
5353
_ "github.com/elastic/beats/metricbeat/module/system/network"
5454
_ "github.com/elastic/beats/metricbeat/module/system/process"
55+
_ "github.com/elastic/beats/metricbeat/module/system/socket"
5556
_ "github.com/elastic/beats/metricbeat/module/zookeeper"
5657
_ "github.com/elastic/beats/metricbeat/module/zookeeper/mntr"
5758
)

metricbeat/mb/testing/data_generator.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package testing
33
import (
44
"encoding/json"
55
"flag"
6+
"fmt"
67
"io/ioutil"
78
"os"
89
"testing"
@@ -33,15 +34,18 @@ func WriteEvent(f mb.EventFetcher, t *testing.T) error {
3334
}
3435

3536
func WriteEvents(f mb.EventsFetcher, t *testing.T) error {
36-
3737
if !*dataFlag {
3838
t.Skip("Skip data generation tests")
3939
}
40+
4041
events, err := f.Fetch()
4142
if err != nil {
4243
return err
4344
}
4445

46+
if len(events) == 0 {
47+
return fmt.Errorf("no events were generated")
48+
}
4549
return createEvent(events[0], f)
4650
}
4751

metricbeat/metricbeat.full.yml

+8
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ metricbeat.modules:
3939

4040
# Per process stats
4141
- process
42+
43+
# Sockets and connection info (linux only)
44+
#- socket
4245
enabled: true
4346
period: 10s
4447
processes: ['.*']
@@ -49,6 +52,11 @@ metricbeat.modules:
4952
# EXPERIMENTAL: cgroups can be enabled for the process metricset.
5053
#cgroups: false
5154

55+
# Configure reverse DNS lookup on remote IP addresses in the socket metricset.
56+
#socket.reverse_lookup.enabled: false
57+
#socket.reverse_lookup.success_ttl: 60s
58+
#socket.reverse_lookup.failure_ttl: 60s
59+
5260
#------------------------------- Apache Module -------------------------------
5361
#- module: apache
5462
#metricsets: ["status"]

0 commit comments

Comments
 (0)