Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions libbeat/tests/system/beat/beat.py
Original file line number Diff line number Diff line change
Expand Up @@ -495,8 +495,8 @@ def extract_fields(doc_list, name):
if "name" not in field:
continue

# Chain together names
if name != "":
# Chain together names. Names in group `base` are top-level.
if name != "" and name != "base":
newName = name + "." + field["name"]
else:
newName = field["name"]
Expand Down
11 changes: 6 additions & 5 deletions x-pack/auditbeat/module/system/host/_meta/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,18 @@
"module": "system",
"kind": "state"
},
"message": "Ubuntu host ubuntu-bionic (IP: 10.0.2.15) is up for 0 days, 5 hours, 11 minutes",
"service": {
"type": "system"
},
"system": {
"audit": {
"host": {
"architecture": "x86_64",
"boottime": "2018-12-04T12:13:02Z",
"boottime": "2018-12-10T15:48:44Z",
"containerized": false,
"id": "b0d3f38d51bdeefe224737595c03d916",
"hostname": "ubuntu-bionic",
"id": "6f7be6fb33e6c77f057266415c094408",
"ip": [
"10.0.2.15",
"fe80::2d:fdff:fe81:e747",
Expand All @@ -36,17 +38,16 @@
"02:42:83:be:1a:3a",
"02:42:9e:d3:d8:88"
],
"hostname": "ubuntu-bionic",
"os": {
"family": "debian",
"kernel": "4.15.0-39-generic",
"kernel": "4.15.0-42-generic",
"name": "Ubuntu",
"platform": "ubuntu",
"version": "18.04.1 LTS (Bionic Beaver)"
},
"timezone.name": "UTC",
"timezone.offset.sec": 0,
"uptime": 105705490232434
"uptime": 18661357350265
}
}
}
Expand Down
75 changes: 68 additions & 7 deletions x-pack/auditbeat/module/system/host/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import (
"bytes"
"encoding/binary"
"encoding/gob"
"fmt"
"io"
"math"
"net"
"strconv"
"time"
Expand Down Expand Up @@ -41,7 +43,7 @@ const (
type eventAction uint8

const (
eventActionHost eventAction = iota + 1
eventActionHost eventAction = iota
eventActionIDChanged
eventActionReboot
eventActionHostnameChanged
Expand Down Expand Up @@ -123,12 +125,7 @@ func (host *Host) toMapStr() common.MapStr {

var ipStrings []string
for _, addr := range host.addrs {
switch v := addr.(type) {
case *net.IPNet:
ipStrings = append(ipStrings, v.IP.String())
case *net.IPAddr:
ipStrings = append(ipStrings, v.IP.String())
}
ipStrings = append(ipStrings, ipString(addr))
}
mapstr.Put("ip", ipStrings)

Expand All @@ -144,6 +141,17 @@ func (host *Host) toMapStr() common.MapStr {
return mapstr
}

func ipString(addr net.Addr) string {
switch v := addr.(type) {
case *net.IPNet:
return v.IP.String()
case *net.IPAddr:
return v.IP.String()
default:
return ""
}
}

func init() {
mb.Registry.MustAddMetricSet(moduleName, metricsetName, New,
mb.DefaultMetricSet(),
Expand Down Expand Up @@ -317,11 +325,64 @@ func hostEvent(host *Host, eventType string, action eventAction) mb.Event {
"kind": eventType,
"action": action.String(),
},
"message": hostMessage(host, action),
},
MetricSetFields: host.toMapStr(),
}
}

func hostMessage(host *Host, action eventAction) string {
var firstIP string
if len(host.addrs) > 0 {
firstIP = ipString(host.addrs[0])
}

// Hostname + IP of the first non-loopback interface.
hostString := fmt.Sprintf("%v (IP: %v)", host.info.Hostname, firstIP)

var message string
switch action {
case eventActionHost:
message = fmt.Sprintf("%v host %v is up for %v",
host.info.OS.Name, hostString, fmtDuration(host.uptime))
case eventActionIDChanged:
message = fmt.Sprintf("ID of host %v has changed", hostString)
case eventActionReboot:
message = fmt.Sprintf("Host %v restarted", hostString)
case eventActionHostnameChanged:
message = fmt.Sprintf("Hostname changed to %v", hostString)
case eventActionHostChanged:
message = fmt.Sprintf("Host %v changed", hostString)
}

return message
}

func fmtDuration(d time.Duration) string {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functions like this should get some unit tests. Fine with adding them later in this case, but normally we'd expect them with the PR.

const dayMinutes = 60 * 24

remainingMinutes := math.Floor(d.Minutes())
days := math.Floor(remainingMinutes / dayMinutes)

remainingMinutes -= days * dayMinutes
hours := math.Floor(remainingMinutes / 60)

remainingMinutes -= hours * 60
minutes := math.Floor(remainingMinutes)

return fmt.Sprintf("%.f %v, %.f %v, %.f %v",
days, inflect("day", int(days)),
hours, inflect("hour", int(hours)),
minutes, inflect("minute", int(minutes)))
}

func inflect(noun string, count int) string {
if count == 1 {
return noun
}
return noun + "s"
}

func (ms *MetricSet) saveStateToDisk() error {
var buf bytes.Buffer
encoder := gob.NewEncoder(&buf)
Expand Down
20 changes: 12 additions & 8 deletions x-pack/auditbeat/module/system/process/_meta/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,23 @@
"event": {
"action": "existing_process",
"dataset": "process",
"id": "203e3d86-6b94-4e36-b906-930187073b93",
"id": "5795d53b-f7c2-463c-9c04-f316ae876d51",
"module": "system",
"kind": "state"
},
"message": "Process zsh (PID: 2363) is RUNNING",
"process": {
"args": [
"/sbin/init"
"/usr/bin/zsh"
],
"executable": "/lib/systemd/systemd",
"name": "systemd",
"pid": 1,
"ppid": 0,
"start": "2018-12-03T23:49:23.08Z",
"working_directory": "/"
"executable": "/bin/zsh",
"name": "zsh",
"pid": 2363,
"ppid": 2362,
"start": "2018-12-10T16:36:25.21Z",
"working_directory": "/home/elastic"
},
"service": {
"type": "system"
}
}
44 changes: 39 additions & 5 deletions x-pack/auditbeat/module/system/process/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package process

import (
"fmt"
"strconv"
"time"

Expand Down Expand Up @@ -33,12 +34,29 @@ const (

eventTypeState = "state"
eventTypeEvent = "event"
)

type eventAction uint8

eventActionExistingProcess = "existing_process"
eventActionProcessStarted = "process_started"
eventActionProcessStopped = "process_stopped"
const (
eventActionExistingProcess eventAction = iota
eventActionProcessStarted
eventActionProcessStopped
)

func (action eventAction) String() string {
switch action {
case eventActionExistingProcess:
return "existing_process"
case eventActionProcessStarted:
return "process_started"
case eventActionProcessStopped:
return "process_stopped"
default:
return ""
}
}

func init() {
mb.Registry.MustAddMetricSet(moduleName, metricsetName, New,
mb.DefaultMetricSet(),
Expand Down Expand Up @@ -214,18 +232,34 @@ func (ms *MetricSet) reportChanges(report mb.ReporterV2) error {
return nil
}

func processEvent(pInfo *ProcessInfo, eventType string, eventAction string) mb.Event {
func processEvent(pInfo *ProcessInfo, eventType string, action eventAction) mb.Event {
return mb.Event{
RootFields: common.MapStr{
"event": common.MapStr{
"kind": eventType,
"action": eventAction,
"action": action.String(),
},
"process": pInfo.toMapStr(),
"message": processMessage(pInfo, action),
},
}
}

func processMessage(pInfo *ProcessInfo, action eventAction) string {
var actionString string
switch action {
case eventActionProcessStarted:
actionString = "STARTED"
case eventActionProcessStopped:
actionString = "STOPPED"
case eventActionExistingProcess:
actionString = "is RUNNING"
}

return fmt.Sprintf("Process %v (PID: %d) %v",
pInfo.Name, pInfo.PID, actionString)
}

func convertToCacheable(processInfos []*ProcessInfo) []cache.Cacheable {
c := make([]cache.Cacheable, 0, len(processInfos))

Expand Down
5 changes: 4 additions & 1 deletion x-pack/auditbeat/module/system/process/process_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ func TestData(t *testing.T) {
t.Fatal("no events were generated")
}

fullEvent := mbtest.StandardizeEvent(f, events[0], core.AddDatasetToEvent)
// The first process (events[0]) is usually something like systemd,
// the last few are test processes, so we pick something more interesting
// towards the end.
fullEvent := mbtest.StandardizeEvent(f, events[len(events)-8], core.AddDatasetToEvent)
mbtest.WriteEventToDataJSON(t, fullEvent, "")
}

Expand Down
47 changes: 26 additions & 21 deletions x-pack/auditbeat/module/system/socket/_meta/data.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,35 @@
"hostname": "host.example.com",
"name": "host.example.com"
},
"user": {
"name": "vagrant",
"id": 1000
},
"process": {
"pid": 4021,
"name": "lynx"
},
"source": {
"ip": "10.0.2.15",
"port": 33956
},
"destination": {
"port": 443,
"ip": "52.10.168.186"
"ip": "10.0.2.15",
"port": 22
},
"event": {
"kind": "event",
"action": "socket_opened",
"module": "system",
"dataset": "socket"
"action": "existing_socket",
"dataset": "socket",
"id": "6aff69f8-7267-4604-9701-d7b67a7c65bc",
"kind": "state",
"module": "system"
},
"message": "Inbound socket (10.0.2.2:55270 -\u003e 10.0.2.15:22) OPEN by process sshd (PID: 22799) and user root (UID: 0)",
"network": {
"type": "ipv4",
"direction": "outbound"
"direction": "inbound",
"type": "ipv4"
},
"process": {
"name": "sshd",
"pid": 22799
},
"service": {
"type": "system"
},
"source": {
"ip": "10.0.2.2",
"port": 55270
},
"user": {
"id": 0,
"name": "root"
}
}
}
Loading