Skip to content

Commit f9f06fd

Browse files
committed
Merge branch 'hotfix/filtering'
2 parents d0be75c + d867e79 commit f9f06fd

6 files changed

Lines changed: 128 additions & 24 deletions

File tree

README.md

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# cloudfoundry-sumologic-nozzle
2-
2+
===============================
33
This Nozzle aggregates all the events from the _Firehose_ feature in Cloud Foundry towards Sumo Logic
44

55
### Options of use
@@ -11,6 +11,7 @@ Flags: (See run command, in this document, for syntax of flags)
1111
--help Show context-sensitive help (also try --help-long and --help-man).
1212
--api-endpoint= CF API Endpoint
1313
--sumo-endpoint= SUMO-ENDPOINT Complete URL for the endpoint, copied from the Sumo Logic HTTP Source configuration
14+
--doppler-endpoint= Overwrite default doppler endpoint return by /v2/info
1415
--subscription-id="firehose" Cloud Foundry ID for the subscription.
1516
--cloudfoundry-user= Cloud Foundry User
1617
--cloudfoundry-password= Cloud Foundry Password
@@ -67,17 +68,18 @@ in this case, Only the events that contains a _**job:diego-cell**_ field OR a _*
6768

6869
* **Case 4**:
6970
**Include-Only filter**=job:diego_cell,source_type:other
70-
**Exclude-Always filter**=source_type:other,origin:rep
71+
**Exclude-Always filter**=source_type:app,origin:rep
7172
In this case, all the events that contains a _**job:diego-cell**_ field OR a _**source-type:other**_ field will be sent to Sumo Logic
7273
**AND also**
73-
All the events that contains a _**source-type:other**_ field OR an _**origin:rep**_ field will be not sent to Sumo Logic
74+
All the events that contains a _**source-type:other**_ field OR an _**origin:app**_ field will be not sent to Sumo Logic.
75+
76+
**IMPORTANT**: **Exclude filter _overrides_ Include filter** . This way if one or more of the App's logs fields **match both filters** (contains a _Include-Only filter_ field and a _Exclude-Always_ filter), this log will be **NOT** sent to Sumo Logic.
7477

75-
If an event **share both filters** (contains a _Include-Only filter_ field and a _Exclude-Always_ filter field), Only the _**Include-Only**_ filter will be considered.
7678

7779
The correct way of using those flags will be something like this:
7880

7981
```
80-
godep go run main.go --sumo-endpoint=https://sumo-endpoint --api-endpoint=https://api.endpoint --skip-ssl-validation --cloudfoundry-user=some_user --cloudfoundry-password=some_password --sumo-post-minimum-delay=200ms --log-events-batch-size=200 --events=LogMessage, ValueMetric --include-only-matching-filter=job:diego_cell,source_type:app --exclude-always-matching-filter=source_type:other,unit:count
82+
godep go run main.go --sumo-endpoint=https://sumo-endpoint --api-endpoint=https://api.endpoint --skip-ssl-validation --cloudfoundry-user=some_user --cloudfoundry-password=some_password --sumo-post-minimum-delay=200ms --log-events-batch-size=200 --events=LogMessage, ValueMetric --include-only-matching-filter=job:diego_cell,source_type:app --exclude-always-matching-filter=source_type:other,unit:count
8183
```
8284

8385

@@ -89,27 +91,28 @@ The tile configuration is handled in the 'tile.yml' file. (If you want to modify
8991

9092
#### Steps to run as this Nozzle as a tile in PCF:
9193

92-
##### Step 1 - Install the tile-generator python package
93-
94+
##### Step 1 - Install the tile-generator python package
9495
* Follow the Official Pivotal Instructions: http://docs.pivotal.io/tiledev/tile-generator.html#how-to
9596
(only until half of the _step 3_, DON'T DO 'tile init', only cd into the 'cloudfoundry-sumologic-nozzle' folder)
9697

97-
##### Step 2 - Check the tile file
98+
##### Step 2 - Check the tile file
99+
98100
* If you want to add more settings to the tile or remove some. Check the Official Pivotal Documentation for more options http://docs.pivotal.io/tiledev/tile-generator.html#define
99101

100-
##### Step 3 - Prepare your code:
102+
##### Step 3 - Prepare your code:
103+
101104
* Zip your entire code and place the zip file into the root directory of the project for which you wish to create a tile. For this tile use this command: (you should do this in a new terminal window)
102105

103106
```
104107
zip -r sumo-logic-nozzle.zip bitbucket-pipelines.yml caching/ ci/ eventQueue/ eventRouting/ events/ firehoseclient/ glide.yaml glide.lock Godeps/ LICENSE logging/ main.go manifest.yml event.db Procfile sumoCFFirehose/ utils/ vendor/
105108
```
106-
##### Step 4 - Build tile file
109+
##### Step 4 - Build tile file
107110
* go to the 'tile-generator' terminal window and run
108111
109112
```
110113
$ tile build
111114
```
112-
##### Step 4 - Install the tile in Pivotal Cloud Foundry
115+
##### Step 5 - Install the tile in Pivotal Cloud Foundry
113116
* Login with proper credentials into the OPS Manager and import the .pivotal file created above and wait.
114117
* Then add it to the Installation Dashboard to configure it. You should able to configure the settings created in the tile file.
115118
* Update the changes and you should start to see some logs in the Sumo Logic Endpoint defined.
@@ -134,6 +137,7 @@ $ cf push cloudfoundry-sumologic-nozzle --no-start
134137
```
135138
$ cf set-env cloudfoundry-sumologic-nozzle API_ENDPOINT https://api.[your cf system domain]
136139
$ cf set-env cloudfoundry-sumologic-nozzle SUMO_ENDPOINT https://sumo-endpoint
140+
$ cf set-env cloudfoundry-sumologic-nozzle DOPPLER_ENDPOINT: wss://doppler.bosh-lite.com:443
137141
$ cf set-env cloudfoundry-sumologic-nozzle FIREHOSE_SUBSCRIPTION_ID cloudfoundry-sumologic-nozzle
138142
$ cf set-env cloudfoundry-sumologic-nozzle CLOUDFOUNDRY_USER [your doppler.firehose enabled user]
139143
$ cf set-env cloudfoundry-sumologic-nozzle CLOUDFOUNDRY_PASSWORD [your doppler.firehose enabled user password]

main.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ import (
1818
)
1919

2020
var (
21-
apiEndpoint = kingpin.Flag("api-endpoint", "URL to CF API Endpoint").OverrideDefaultFromEnvar("API_ENDPOINT").String()
22-
sumoEndpoint = kingpin.Flag("sumo-endpoint", "SUMO-ENDPOINT Complete URL for the endpoint, copied from the Sumo Logic HTTP Source configuration").OverrideDefaultFromEnvar("SUMO_ENDPOINT").String()
23-
//dopplerEndpoint = kingpin.Flag("doppler-endpoint", "Overwrite default doppler endpoint return by /v2/info").OverrideDefaultFromEnvar("DOPPLER_ENDPOINT").String()
21+
apiEndpoint = kingpin.Flag("api-endpoint", "URL to CF API Endpoint").OverrideDefaultFromEnvar("API_ENDPOINT").String()
22+
sumoEndpoint = kingpin.Flag("sumo-endpoint", "SUMO-ENDPOINT Complete URL for the endpoint, copied from the Sumo Logic HTTP Source configuration").OverrideDefaultFromEnvar("SUMO_ENDPOINT").String()
23+
dopplerEndpoint = kingpin.Flag("doppler-endpoint", "Overwrite default doppler endpoint return by /v2/info").OverrideDefaultFromEnvar("DOPPLER_ENDPOINT").String()
2424
subscriptionId = kingpin.Flag("subscription-id", "Cloud Foundry ID for the subscription.").Default("firehose").OverrideDefaultFromEnvar("FIREHOSE_SUBSCRIPTION_ID").String()
2525
user = kingpin.Flag("cloudfoundry-user", "Cloud Foundry User").OverrideDefaultFromEnvar("CLOUDFOUNDRY_USER").String() //user created in CF, authorized to connect the firehose
2626
password = kingpin.Flag("cloudfoundry-password", "Cloud Foundry Password").OverrideDefaultFromEnvar("CLOUDFOUNDRY_PASSWORD").String()
@@ -54,7 +54,6 @@ func main() {
5454
logging.Info.Println("Set Configurations:")
5555
logging.Info.Println("CF API Endpoint: " + *apiEndpoint)
5656
logging.Info.Println("Sumo Logic Endpoint: " + *sumoEndpoint)
57-
//logging.Info.Println("Cloud foundry Doppler Endpoint: " + *dopplerEndpoint) //TODO
5857
logging.Info.Println("Cloud Foundry Nozzle Subscription ID: " + *subscriptionId)
5958
logging.Info.Println("Cloud Foundry User: " + *user)
6059
logging.Info.Println("Events Selected: " + *wantedEvents)
@@ -86,6 +85,11 @@ func main() {
8685
logging.Error.Fatal("Error setting up CF Client: ", errCfClient)
8786
os.Exit(1)
8887
}
88+
if len(*dopplerEndpoint) > 0 {
89+
cfClient.Endpoint.DopplerEndpoint = *dopplerEndpoint
90+
}
91+
logging.Info.Printf("Using %s as doppler endpoint", cfClient.Endpoint.DopplerEndpoint)
92+
8993
//Creating Caching
9094
var cachingClient caching.Caching
9195
if caching.IsNeeded(*wantedEvents) {

manifest.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ applications:
33
env:
44
API_ENDPOINT: https://api.some_api
55
SUMO_ENDPOINT: https://some_endpoint
6+
DOPPLER_ENDPOINT: wss://doppler.bosh-lite.com:443
67
FIREHOSE_SUBSCRIPTION_ID: cloudfoundry-sumologic-nozzle
78
CLOUDFOUNDRY_USER: firehose_user_authorized
89
CLOUDFOUNDRY_PASSWORD: password_firehose_user_authorized
9-
EVENTS: LogMessage
10+
EVENTS: LogMessage,ValueMetric,Error,ContainerMetric
1011
SKIP_SSL_VALIDATION: false
1112
NOZZLE_POLLING_PERIOD: 15s
1213
LOG_EVENTS_BATCHSIZE: 200

sumoCFFirehose/sumoLogicAppender.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,11 @@ func WantedEvent(event string, includeOnlyMatchingFilter string, excludeAlwaysMa
119119
subsliceExclude := ParseCustomInput(excludeAlwaysMatchingFilter)
120120
for key, value := range subsliceInclude {
121121
if strings.Contains(event, "\""+key+"\":\""+value+"\"") {
122+
for key, value := range subsliceExclude {
123+
if strings.Contains(event, "\""+key+"\":\""+value+"\"") {
124+
return false
125+
}
126+
}
122127
return true
123128
}
124129
}
@@ -127,7 +132,7 @@ func WantedEvent(event string, includeOnlyMatchingFilter string, excludeAlwaysMa
127132
return false
128133
}
129134
}
130-
return false
135+
return true
131136
} else if includeOnlyMatchingFilter != "" {
132137
subslice := ParseCustomInput(includeOnlyMatchingFilter)
133138
for key, value := range subslice {

sumoCFFirehose/sumoLogicAppender_test.go

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ func TestSendExcludeAlwaysFilter(t *testing.T) {
188188
excludeAlwaysFilter := "source_type:other,cf_app_id:7833dc75-4484-409c-9b74-90b6454906c6"
189189
assert.False(t, WantedEvent(buf.String(), "", excludeAlwaysFilter), "This Event should be excluded")
190190
}
191-
func TestSendIncludeOnlyAlwaysFilter(t *testing.T) {
191+
func TestSendIncludeExcludeFilterOverride(t *testing.T) {
192192
eventToExclude := Event{
193193
Fields: map[string]interface{}{
194194
"message_type": "OUT",
@@ -215,8 +215,99 @@ func TestSendIncludeOnlyAlwaysFilter(t *testing.T) {
215215
buf.Write(msg)
216216
includeOnlyFilter := "job:diego_cell,source_type:other"
217217
excludeAlwaysFilter := "source_type:other,cf_app_id:7833dc75-4484-409c-9b74-90b6454906c6"
218+
assert.False(t, WantedEvent(buf.String(), includeOnlyFilter, excludeAlwaysFilter), "This Event should be not included, override filter")
219+
}
220+
221+
func TestSendIncludeExcludeFilterAppMatchIncluded(t *testing.T) {
222+
eventToExclude := Event{
223+
Fields: map[string]interface{}{
224+
"message_type": "OUT",
225+
"source_instance": 0,
226+
"deployment": "cf",
227+
"ip": "10.193.166.47",
228+
"job": "diego_cell",
229+
"job_index": "c62aebe5-16b8-43f5-a589-1267e09b9537",
230+
"cf_ignored_app": "false",
231+
"timestamp": "2017-01-10 17:31:02.662133274 -0300 CLST",
232+
"source_type": "APP",
233+
"origin": "rep",
234+
"cf_app_id": "7833dc75-4484-409c-9b74-90b6454906c6",
235+
},
236+
Msg: "Triggering 'app usage events fetcher'",
237+
Type: "LogMessage",
238+
}
239+
message, err := json.Marshal(eventToExclude)
240+
var msg []byte
241+
if err == nil {
242+
msg = message
243+
}
244+
buf := new(bytes.Buffer)
245+
buf.Write(msg)
246+
includeOnlyFilter := "job:diego_cell,source_type:other"
247+
excludeAlwaysFilter := "source_type:other,origin:router"
218248
assert.True(t, WantedEvent(buf.String(), includeOnlyFilter, excludeAlwaysFilter), "This Event should be included")
219249
}
250+
251+
func TestSendIncludeExcludeFilterAppMatchExcluded(t *testing.T) {
252+
eventToExclude := Event{
253+
Fields: map[string]interface{}{
254+
"message_type": "OUT",
255+
"source_instance": 0,
256+
"deployment": "cf",
257+
"ip": "10.193.166.47",
258+
"job": "diego_cell",
259+
"job_index": "c62aebe5-16b8-43f5-a589-1267e09b9537",
260+
"cf_ignored_app": "false",
261+
"timestamp": "2017-01-10 17:31:02.662133274 -0300 CLST",
262+
"source_type": "APP",
263+
"origin": "rep",
264+
"cf_app_id": "7833dc75-4484-409c-9b74-90b6454906c6",
265+
},
266+
Msg: "Triggering 'app usage events fetcher'",
267+
Type: "LogMessage",
268+
}
269+
message, err := json.Marshal(eventToExclude)
270+
var msg []byte
271+
if err == nil {
272+
msg = message
273+
}
274+
buf := new(bytes.Buffer)
275+
buf.Write(msg)
276+
includeOnlyFilter := "job:dedicated-node,source_type:other"
277+
excludeAlwaysFilter := "source_type:other,origin:rep"
278+
assert.False(t, WantedEvent(buf.String(), includeOnlyFilter, excludeAlwaysFilter), "This Event should not be included")
279+
}
280+
281+
func TestSendIncludeExcludeFilterAppNotMatchAnyFilter(t *testing.T) {
282+
eventToExclude := Event{
283+
Fields: map[string]interface{}{
284+
"message_type": "OUT",
285+
"source_instance": 0,
286+
"deployment": "cf",
287+
"ip": "10.193.166.47",
288+
"job": "diego_cell",
289+
"job_index": "c62aebe5-16b8-43f5-a589-1267e09b9537",
290+
"cf_ignored_app": "false",
291+
"timestamp": "2017-01-10 17:31:02.662133274 -0300 CLST",
292+
"source_type": "APP",
293+
"origin": "rep",
294+
"cf_app_id": "7833dc75-4484-409c-9b74-90b6454906c6",
295+
},
296+
Msg: "Triggering 'app usage events fetcher'",
297+
Type: "LogMessage",
298+
}
299+
message, err := json.Marshal(eventToExclude)
300+
var msg []byte
301+
if err == nil {
302+
msg = message
303+
}
304+
buf := new(bytes.Buffer)
305+
buf.Write(msg)
306+
includeOnlyFilter := "job:dedicated-node,source_type:other"
307+
excludeAlwaysFilter := "source_type:other,origin:reps"
308+
assert.True(t, WantedEvent(buf.String(), includeOnlyFilter, excludeAlwaysFilter), "This Event should be included")
309+
}
310+
220311
func TestSendNoFilter(t *testing.T) {
221312
eventToExclude := Event{
222313
Fields: map[string]interface{}{

tile.yml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,11 @@ forms:
9393
type: string
9494
label: Cloud Foundry API Endpoint
9595
description: URL to CF API Endpoint
96+
- name: doppler-endpoint
97+
type: string
98+
label: Doppler Endpoint
99+
description: Overwrite default doppler endpoint return by /v2/info
100+
optional: true
96101
- name: cloudfoundry-user
97102
type: string
98103
label: Cloud Foundry User
@@ -126,9 +131,3 @@ forms:
126131
label: Nozzle Polling Period
127132
default: 15s
128133
description: How frequently this Nozzle polls the CF Firehose for data
129-
- name: f2s-disable-logging
130-
type: boolean
131-
label: Disable Logging (Nozzle's Logs)
132-
default: true
133-
description: Handle if the Nozzle logs will be ignored and not send to Sumo Logic
134-
configurable: false

0 commit comments

Comments
 (0)