-
Notifications
You must be signed in to change notification settings - Fork 4.9k
/
Copy pathadd_cloudfoundry_metadata.go
136 lines (117 loc) · 3.34 KB
/
add_cloudfoundry_metadata.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
// or more contributor license agreements. Licensed under the Elastic License;
// you may not use this file except in compliance with the Elastic License.
//go:build !aix
package add_cloudfoundry_metadata
import (
"fmt"
"github.com/gofrs/uuid/v5"
"github.com/elastic/beats/v7/libbeat/beat"
"github.com/elastic/beats/v7/libbeat/processors"
"github.com/elastic/beats/v7/x-pack/libbeat/common/cloudfoundry"
conf "github.com/elastic/elastic-agent-libs/config"
"github.com/elastic/elastic-agent-libs/logp"
"github.com/elastic/elastic-agent-libs/mapstr"
)
const (
processorName = "add_cloudfoundry_metadata"
)
func init() {
processors.RegisterPlugin(processorName, New)
}
type addCloudFoundryMetadata struct {
log *logp.Logger
client cloudfoundry.Client
}
const selector = "add_cloudfoundry_metadata"
// New constructs a new add_cloudfoundry_metadata processor.
func New(cfg *conf.C) (beat.Processor, error) {
var config cloudfoundry.Config
// ShardID is required in cloudfoundry config to consume from the firehose,
// but not for metadata requests, randomly generate one and use it.
config.ShardID = uuid.Must(uuid.NewV4()).String()
if err := cfg.Unpack(&config); err != nil {
return nil, fmt.Errorf("fail to unpack the %v configuration: %w", processorName, err)
}
log := logp.NewLogger(selector)
hub := cloudfoundry.NewHub(&config, "add_cloudfoundry_metadata", log)
client, err := hub.ClientWithCache()
if err != nil {
return nil, fmt.Errorf("%s: creating cloudfoundry client: %w", processorName, err)
}
return &addCloudFoundryMetadata{
log: log,
client: client,
}, nil
}
func (d *addCloudFoundryMetadata) Run(event *beat.Event) (*beat.Event, error) {
if d.client == nil {
return event, nil
}
valI, err := event.GetValue("cloudfoundry.app.id")
if err != nil {
//nolint:nilerr // doesn't have the required cloudfoundry.app.id value to add more information
return event, nil
}
val, _ := valI.(string)
if val == "" {
// wrong type or not set
return event, nil
}
if hasMetadataFields(event) {
// nothing to do, fields already present
return event, nil
}
app, err := d.client.GetAppByGuid(val)
if err != nil {
d.log.Debugf("failed to get application info for GUID(%s): %v", val, err)
return event, nil
}
event.Fields.DeepUpdate(mapstr.M{
"cloudfoundry": mapstr.M{
"app": mapstr.M{
"name": app.Name,
},
"space": mapstr.M{
"id": app.SpaceGuid,
"name": app.SpaceName,
},
"org": mapstr.M{
"id": app.OrgGuid,
"name": app.OrgName,
},
},
})
return event, nil
}
// String returns this processor name.
func (d *addCloudFoundryMetadata) String() string {
return processorName
}
// Close closes the underlying client and releases its resources.
func (d *addCloudFoundryMetadata) Close() error {
if d.client == nil {
return nil
}
err := d.client.Close()
if err != nil {
return fmt.Errorf("closing client: %w", err)
}
return nil
}
var metadataFields = []string{
"cloudfoundry.app.id",
"cloudfoundry.app.name",
"cloudfoundry.space.id",
"cloudfoundry.space.name",
"cloudfoundry.org.id",
"cloudfoundry.org.name",
}
func hasMetadataFields(event *beat.Event) bool {
for _, name := range metadataFields {
if value, err := event.GetValue(name); value == "" || err != nil {
return false
}
}
return true
}