Repository: kentik/ktranslate
Pull request #565 (2023-05-02 23:08:21)

Tweak filters
Reworking filters to make them more logical. Now you can just say `-filters fooII,==,12` and things will work to filter out all events where fooII doesn't equal 12. 

i3149: Now you can do things like `-filter="foo,==,no or fooII,==,12"`. Other wise, `-filter` flags are ANDed together. You can also set a flag `-enricher=/path/to/script.py` to filter this way, setting anything you do not like to None. For example:

```
def main(n):
    keep = 0
    for i in range(len(n)):
      if n[i].TrapOID == ".1.3.6.1.4.1.8072.2.3.0.1":
          print(n[i])
          keep = keep+1
      else:
         n[i] = None

    return keep
```





Patch:
diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml
index 784378f..06c47fd 100644
--- a/.github/workflows/create-release.yml
+++ b/.github/workflows/create-release.yml
@@ -47,12 +47,13 @@ jobs:
 
       - name: Set Version
         run: |
-           echo "KENTIK_KTRANSLATE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
+           echo "KENTIK_KTRANSLATE_VERSION=${{ github.ref_name }}" >> $GITHUB_ENV
+           echo ${{ github.ref_name }}
 
       - name: Setup Go
         uses: actions/setup-go@v2
         with:
-          go-version: '1.18.3'
+          go-version: '1.20.4'
 
       - name: Get Deps
         shell: bash
diff --git a/.github/workflows/publish-develop.yml b/.github/workflows/publish-develop.yml
index 4153036..3961fde 100644
--- a/.github/workflows/publish-develop.yml
+++ b/.github/workflows/publish-develop.yml
@@ -21,7 +21,7 @@ jobs:
       - name: Setup Go
         uses: actions/setup-go@v2
         with:
-          go-version: '1.17.2'
+          go-version: '1.20.4'
 
       - name: Set up QEMU
         uses: docker/setup-qemu-action@v1
@@ -36,17 +36,16 @@ jobs:
           password: ${{ secrets.DOCKERHUB_TOKEN }}
 
       - name: Install dependencies
-        run: sudo apt-get install make libpcap-dev golint
+        run: sudo apt-get install make libpcap-dev
 
       - name: Run build
         run: |
           echo ${{ env.KENTIK_KTRANSLATE_VERSION }}
           KENTIK_KTRANSLATE_VERSION=${{ env.KENTIK_KTRANSLATE_VERSION }} make
 
-      - name: Run vet & lint
+      - name: Run vet
         run: |
           go vet .
-          golint .
 
       - name: Run testing
         run: make test
diff --git a/.github/workflows/publish-eapi.yml b/.github/workflows/publish-eapi.yml
index 256b1f9..e98a631 100644
--- a/.github/workflows/publish-eapi.yml
+++ b/.github/workflows/publish-eapi.yml
@@ -21,7 +21,7 @@ jobs:
       - name: Setup Go
         uses: actions/setup-go@v2
         with:
-          go-version: '1.17.2'
+          go-version: '1.20.4'
 
       - name: Set up QEMU
         uses: docker/setup-qemu-action@v1
@@ -36,17 +36,16 @@ jobs:
           password: ${{ secrets.DOCKERHUB_TOKEN }}
 
       - name: Install dependencies
-        run: sudo apt-get install make libpcap-dev golint
+        run: sudo apt-get install make libpcap-dev
 
       - name: Run build
         run: |
           echo ${{ env.KENTIK_KTRANSLATE_VERSION }}
           KENTIK_KTRANSLATE_VERSION=${{ env.KENTIK_KTRANSLATE_VERSION }} make
 
-      - name: Run vet & lint
+      - name: Run vet
         run: |
           go vet .
-          golint .
 
       - name: Run testing
         run: make test
diff --git a/.github/workflows/publish-kentik.yml b/.github/workflows/publish-kentik.yml
index 6b42e1d..6529fa6 100644
--- a/.github/workflows/publish-kentik.yml
+++ b/.github/workflows/publish-kentik.yml
@@ -27,7 +27,7 @@ jobs:
       - name: Setup Go
         uses: actions/setup-go@v2
         with:
-          go-version: '1.19.2'
+          go-version: '1.20.4'
 
       - name: Set up QEMU
         uses: docker/setup-qemu-action@v1
@@ -49,17 +49,16 @@ jobs:
           password: ${{ secrets.QUAY_LOGIN_TOKEN }}
 
       - name: Install dependencies
-        run: sudo apt-get install make libpcap-dev golint
+        run: sudo apt-get install make libpcap-dev
 
       - name: Run build
         run: |
           echo ${{ env.KENTIK_KTRANSLATE_VERSION }}
           KENTIK_KTRANSLATE_VERSION=${{ env.KENTIK_KTRANSLATE_VERSION }} make
 
-      - name: Run vet & lint
+      - name: Run vet
         run: |
           go vet .
-          golint .
 
       - name: Run testing
         run: make test
diff --git a/.github/workflows/publish-next.yml b/.github/workflows/publish-next.yml
index feb6205..7a824b9 100644
--- a/.github/workflows/publish-next.yml
+++ b/.github/workflows/publish-next.yml
@@ -24,7 +24,7 @@ jobs:
       - name: Setup Go
         uses: actions/setup-go@v2
         with:
-          go-version: '1.18.3'
+          go-version: '1.20.4'
 
       - name: Set up QEMU
         uses: docker/setup-qemu-action@v1
@@ -46,17 +46,16 @@ jobs:
           password: ${{ secrets.QUAY_LOGIN_TOKEN }}
 
       - name: Install dependencies
-        run: sudo apt-get install make libpcap-dev golint
+        run: sudo apt-get install make libpcap-dev
 
       - name: Run build
         run: |
           echo ${{ env.KENTIK_KTRANSLATE_VERSION }}
           KENTIK_KTRANSLATE_VERSION=${{ env.KENTIK_KTRANSLATE_VERSION }} make
 
-      - name: Run vet & lint
+      - name: Run vet
         run: |
           go vet .
-          golint .
 
       - name: Run testing
         run: make test
diff --git a/.github/workflows/publish-packages.yml b/.github/workflows/publish-packages.yml
index cd6ec13..1a9afc0 100644
--- a/.github/workflows/publish-packages.yml
+++ b/.github/workflows/publish-packages.yml
@@ -47,13 +47,13 @@ jobs:
 
       - name: Set Version
         run: |
-           echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
+           echo "RELEASE_VERSION=${{ github.ref_name }}" >> $GITHUB_ENV
            echo KENTIK_KTRANSLATE_VERSION=`date +"kt-%Y-%m-%d-${GITHUB_RUN_ID}"` >> $GITHUB_ENV
 
       - name: Setup Go
         uses: actions/setup-go@v2
         with:
-          go-version: '1.18.3'
+          go-version: '1.20.4'
 
       - name: Get Deps
         run: |
diff --git a/.github/workflows/publish-prod.yml b/.github/workflows/publish-prod.yml
index b4d4231..5cb2285 100644
--- a/.github/workflows/publish-prod.yml
+++ b/.github/workflows/publish-prod.yml
@@ -27,7 +27,7 @@ jobs:
 
       - name: Set Release Version
         run: |
-           echo "KENTIK_KTRANSLATE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
+           echo "KENTIK_KTRANSLATE_VERSION=${{ github.ref_name }}" >> $GITHUB_ENV
         if: steps.version.outputs.is_valid == 'true'
 
       - name: Set NonRelease Version
@@ -38,7 +38,7 @@ jobs:
       - name: Setup Go
         uses: actions/setup-go@v2
         with:
-          go-version: '1.18.3'
+          go-version: '1.20.4'
 
       - name: Set up QEMU
         uses: docker/setup-qemu-action@v1
@@ -60,17 +60,16 @@ jobs:
           password: ${{ secrets.QUAY_LOGIN_TOKEN }}
 
       - name: Install dependencies
-        run: sudo apt-get install make libpcap-dev golint
+        run: sudo apt-get install make libpcap-dev
 
       - name: Run build
         run: |
           echo ${{ env.KENTIK_KTRANSLATE_VERSION }}
           KENTIK_KTRANSLATE_VERSION=${{ env.KENTIK_KTRANSLATE_VERSION }} make
 
-      - name: Run vet & lint
+      - name: Run vet
         run: |
           go vet .
-          golint .
 
       - name: Run testing
         run: make test
diff --git a/.github/workflows/publish-staging.yml b/.github/workflows/publish-staging.yml
index 9b32174..5fb1e1a 100644
--- a/.github/workflows/publish-staging.yml
+++ b/.github/workflows/publish-staging.yml
@@ -21,7 +21,7 @@ jobs:
       - name: Setup Go
         uses: actions/setup-go@v2
         with:
-          go-version: '1.19.2'
+          go-version: '1.20.4'
 
       - name: Set up QEMU
         uses: docker/setup-qemu-action@v1
@@ -43,17 +43,16 @@ jobs:
           password: ${{ secrets.QUAY_LOGIN_TOKEN }}
 
       - name: Install dependencies
-        run: sudo apt-get install make libpcap-dev golint
+        run: sudo apt-get install make libpcap-dev
 
       - name: Run build
         run: |
           echo ${{ env.KENTIK_KTRANSLATE_VERSION }}
           KENTIK_KTRANSLATE_VERSION=${{ env.KENTIK_KTRANSLATE_VERSION }} make
 
-      - name: Run vet & lint
+      - name: Run vet
         run: |
           go vet .
-          golint .
 
       - name: Run testing
         run: make test
diff --git a/.github/workflows/publish-windows.yml b/.github/workflows/publish-windows.yml
index a6a2906..a2bfaf6 100644
--- a/.github/workflows/publish-windows.yml
+++ b/.github/workflows/publish-windows.yml
@@ -26,10 +26,10 @@ jobs:
       - name: Setup Go
         uses: actions/setup-go@v2
         with:
-          go-version: '1.18.3'
+          go-version: '1.20.4'
 
       - name: Install dependencies
-        run: sudo apt-get install make libpcap-dev golint
+        run: sudo apt-get install make libpcap-dev
 
       - name: Install MM DBs
         run: |
@@ -46,10 +46,9 @@ jobs:
           echo ${{ env.KENTIK_KTRANSLATE_VERSION }}
           KENTIK_KTRANSLATE_VERSION=${{ env.KENTIK_KTRANSLATE_VERSION }} make windows
 
-      - name: Run vet & lint
+      - name: Run vet
         run: |
           go vet .
-          golint .
 
       - name: Run testing
         run: make test
diff --git a/cmd/ktranslate/main.go b/cmd/ktranslate/main.go
index 5de1f55..74de2b6 100644
--- a/cmd/ktranslate/main.go
+++ b/cmd/ktranslate/main.go
@@ -401,7 +401,11 @@ func applyFlags(cfg *ktranslate.Config) error {
 				}
 				cfg.EnableHTTPInput = v
 			case "enricher":
-				cfg.EnricherURL = val
+				if _, err := os.Stat(val); err == nil { // If this is a file on disk, run as a script.
+					cfg.EnricherScript = val
+				} else {
+					cfg.EnricherURL = val
+				}
 			case "ddog_url":
 				cfg.DDogSink.URL = val
 			// pkg/maps/file
diff --git a/go.mod b/go.mod
index e183737..4f484c7 100644
--- a/go.mod
+++ b/go.mod
@@ -61,7 +61,6 @@ require (
 	github.com/PuerkitoBio/purell v1.1.1 // indirect
 	github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
 	github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
-	github.com/aws/aws-sdk-go-v2 v1.17.6 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/cespare/xxhash/v2 v2.1.2 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect
@@ -120,11 +119,11 @@ require (
 	go.mongodb.org/mongo-driver v1.8.4 // indirect
 	go.opencensus.io v0.23.0 // indirect
 	golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88 // indirect
-	golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 // indirect
+	golang.org/x/net v0.7.0 // indirect
 	golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a // indirect
 	golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
-	golang.org/x/sys v0.2.0 // indirect
-	golang.org/x/text v0.3.8 // indirect
+	golang.org/x/sys v0.5.0 // indirect
+	golang.org/x/text v0.7.0 // indirect
 	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
 	google.golang.org/api v0.74.0 // indirect
 	google.golang.org/appengine v1.6.7 // indirect
diff --git a/go.sum b/go.sum
index 179fbc4..50dea0a 100644
--- a/go.sum
+++ b/go.sum
@@ -100,9 +100,6 @@ github.com/aws/aws-lambda-go v1.27.0 h1:aLzrJwdyHoF1A18YeVdJjX8Ixkd+bpogdxVInvHc
 github.com/aws/aws-lambda-go v1.27.0/go.mod h1:jJmlefzPfGnckuHdXX7/80O3BvUUi12XOkbv4w9SGLU=
 github.com/aws/aws-sdk-go v1.41.19 h1:9QR2WTNj5bFdrNjRY9SeoG+3hwQmKXGX16851vdh+N8=
 github.com/aws/aws-sdk-go v1.41.19/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
-github.com/aws/aws-sdk-go-v2 v1.17.6 h1:Y773UK7OBqhzi5VDXMi1zVGsoj+CVHs2eaC2bDsLwi0=
-github.com/aws/aws-sdk-go-v2 v1.17.6/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw=
-github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
 github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@@ -299,7 +296,6 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
 github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
 github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
 github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
@@ -690,8 +686,8 @@ golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qx
 golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
 golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
 golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA=
-golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
+golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
+golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -803,8 +799,8 @@ golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
-golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -818,8 +814,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
-golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
+golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
diff --git a/pkg/cat/jchf.go b/pkg/cat/jchf.go
index 46fcf46..feb4705 100644
--- a/pkg/cat/jchf.go
+++ b/pkg/cat/jchf.go
@@ -420,14 +420,17 @@ func int2ip(nn uint32) net.IP {
 
 var (
 	synResultTypes = map[int32]string{
-		0: "error",
-		1: "timeout",
-		2: "ping",
-		3: "fetch",
-		4: "trace",
-		5: "knock",
-		6: "query",
-		7: "shake",
+		0:  "error",
+		1:  "timeout",
+		2:  "ping",
+		3:  "fetch",
+		4:  "trace",
+		5:  "knock",
+		6:  "query",
+		7:  "shake",
+		8:  "pageload",
+		9:  "transaction",
+		10: "dnssec",
 	}
 
 	remapCustomStrings = map[string]string{
@@ -458,7 +461,7 @@ var (
 )
 
 // Updates asn and geo if set for any of these inputs.
-func (kc *KTranslate) doEnrichments(ctx context.Context, msgs []*kt.JCHF) {
+func (kc *KTranslate) doEnrichments(ctx context.Context, msgs []*kt.JCHF) []*kt.JCHF {
 	for _, msg := range msgs {
 		sip := net.ParseIP(msg.SrcAddr)
 		dip := net.ParseIP(msg.DstAddr)
@@ -536,4 +539,6 @@ func (kc *KTranslate) doEnrichments(ctx context.Context, msgs []*kt.JCHF) {
 			msgs = new
 		}
 	}
+
+	return msgs
 }
diff --git a/pkg/cat/kentik.go b/pkg/cat/kentik.go
index 7681c6e..c6ccbb6 100644
--- a/pkg/cat/kentik.go
+++ b/pkg/cat/kentik.go
@@ -278,8 +278,8 @@ func (kc *KTranslate) monitorAlphaChan(ctx context.Context, i int, seri func([]*
 		}
 
 		// Add in any extra things here.
-		if kc.geo != nil || kc.asn != nil {
-			kc.doEnrichments(ctx, msgs)
+		if kc.geo != nil || kc.asn != nil || kc.enricher != nil {
+			msgs = kc.doEnrichments(ctx, msgs)
 		}
 
 		// If we have any rollups defined, send here instead of directly to the output format.
diff --git a/pkg/cat/kkc.go b/pkg/cat/kkc.go
index 7b96a3a..ff5e06a 100644
--- a/pkg/cat/kkc.go
+++ b/pkg/cat/kkc.go
@@ -393,8 +393,8 @@ func (kc *KTranslate) sendToSinks(ctx context.Context) error {
 
 // This processes data from the non-kentik input sets.
 func (kc *KTranslate) handleInput(ctx context.Context, msgs []*kt.JCHF, serBuf []byte, cb func(error), seri func([]*kt.JCHF, []byte) (*kt.Output, error)) {
-	if kc.geo != nil || kc.asn != nil {
-		kc.doEnrichments(ctx, msgs)
+	if kc.geo != nil || kc.asn != nil || kc.enricher != nil {
+		msgs = kc.doEnrichments(ctx, msgs)
 	}
 
 	// If we are filtering, cut any out here.
diff --git a/pkg/filter/addr.go b/pkg/filter/addr.go
index ba0319d..bb99098 100644
--- a/pkg/filter/addr.go
+++ b/pkg/filter/addr.go
@@ -61,6 +61,14 @@ func (f *AddrFilter) addrEquals(chf map[string]interface{}) bool {
 			vv := net.ParseIP(dim[f.dimension[1]])
 			return f.value.Contains(vv)
 		}
+	} else if dd, ok := chf["custom_str"]; ok { // Fall back and try all strings here.
+		switch dim := dd.(type) {
+		case map[string]string:
+			if _, ok := dim[f.dimension[0]]; ok {
+				vv := net.ParseIP(dim[f.dimension[0]])
+				return f.value.Contains(vv)
+			}
+		}
 	}
 	return false
 }
diff --git a/pkg/filter/filter.go b/pkg/filter/filter.go
index 5690503..bc7b2d0 100644
--- a/pkg/filter/filter.go
+++ b/pkg/filter/filter.go
@@ -3,6 +3,8 @@ package filter
 import (
 	"flag"
 	"fmt"
+	"net"
+	"strconv"
 	"strings"
 
 	"github.com/kentik/ktranslate/pkg/kt"
@@ -88,8 +90,18 @@ func (i *FilterDefs) Set(value string) error {
 	inner := FilterDefWrapper{}
 	for _, orSet := range strings.Split(value, OrToken) {
 		pts := strings.Split(orSet, ",")
-		if len(pts) < 4 {
-			return fmt.Errorf("Filter flag is defined by type dimension operator value")
+		if len(pts) < 3 {
+			return fmt.Errorf("Filter flag is defined by <type> dimension operator value")
+		}
+		if len(pts) == 3 {
+			ftype := String
+			// Try to guess the type.
+			if _, err := strconv.Atoi(pts[2]); err == nil {
+				ftype = Int
+			} else if _, _, err := net.ParseCIDR(pts[2]); err == nil {
+				ftype = Addr
+			}
+			pts = append([]string{string(ftype)}, pts...)
 		}
 		ptn := make([]string, len(pts))
 		for i, p := range pts {
diff --git a/pkg/filter/int.go b/pkg/filter/int.go
index fb6512a..b070f33 100644
--- a/pkg/filter/int.go
+++ b/pkg/filter/int.go
@@ -63,6 +63,13 @@ func (f *IntFilter) intEquals(chf map[string]interface{}) bool {
 		case map[string]int64:
 			return dim[f.dimension[1]] == f.value
 		}
+	} else if dd, ok := chf["custom_bigint"]; ok { // Fall back and try all ints here.
+		switch dim := dd.(type) {
+		case map[string]int64:
+			if _, ok := dim[f.dimension[0]]; ok {
+				return dim[f.dimension[0]] == f.value
+			}
+		}
 	}
 	return false
 }
@@ -81,6 +88,13 @@ func (f *IntFilter) intLessThan(chf map[string]interface{}) bool {
 		case map[string]int64:
 			return dim[f.dimension[1]] < f.value
 		}
+	} else if dd, ok := chf["custom_bigint"]; ok { // Fall back and try all ints here.
+		switch dim := dd.(type) {
+		case map[string]int64:
+			if _, ok := dim[f.dimension[0]]; ok {
+				return dim[f.dimension[0]] < f.value
+			}
+		}
 	}
 	return false
 }
@@ -95,6 +109,13 @@ func (f *IntFilter) intGreaterThan(chf map[string]interface{}) bool {
 		case map[string]int64:
 			return dim[f.dimension[1]] > f.value
 		}
+	} else if dd, ok := chf["custom_bigint"]; ok { // Fall back and try all ints here.
+		switch dim := dd.(type) {
+		case map[string]int64:
+			if _, ok := dim[f.dimension[0]]; ok {
+				return dim[f.dimension[0]] > f.value
+			}
+		}
 	}
 	return false
 }
diff --git a/pkg/filter/string.go b/pkg/filter/string.go
index 8ef45d4..0859745 100644
--- a/pkg/filter/string.go
+++ b/pkg/filter/string.go
@@ -53,6 +53,13 @@ func (f *StringFilter) stringEquals(chf map[string]interface{}) bool {
 		case map[string]string:
 			return dim[f.dimension[1]] == f.value
 		}
+	} else if dd, ok := chf["custom_str"]; ok { // Fall back and try all strings here.
+		switch dim := dd.(type) {
+		case map[string]string:
+			if _, ok := dim[f.dimension[0]]; ok {
+				return dim[f.dimension[0]] == f.value
+			}
+		}
 	}
 	return false
 }
@@ -69,6 +76,13 @@ func (f *StringFilter) stringContains(chf map[string]interface{}) bool {
 		case map[string]string:
 			return strings.Contains(dim[f.dimension[1]], f.value)
 		}
+	} else if dd, ok := chf["custom_str"]; ok { // Fall back and try all strings here.
+		switch dim := dd.(type) {
+		case map[string]string:
+			if _, ok := dim[f.dimension[0]]; ok {
+				return strings.Contains(dim[f.dimension[0]], f.value)
+			}
+		}
 	}
 	return false
 }
diff --git a/pkg/formats/nrm/nrm.go b/pkg/formats/nrm/nrm.go
index a69597d..d2e9fc1 100644
--- a/pkg/formats/nrm/nrm.go
+++ b/pkg/formats/nrm/nrm.go
@@ -330,27 +330,38 @@ func (f *NRMFormat) fromSnmpMetadata(in *kt.JCHF) []NRMetric {
 
 var (
 	synthWLAttr = map[string]bool{
-		"agent_id":           true,
-		"agent_name":         true,
-		"dst_addr":           true,
-		"dst_cdn_int":        true,
-		"dst_geo":            true,
-		"provider":           true,
-		"src_addr":           true,
-		"src_cdn_int":        true,
-		"src_geo":            true,
-		"test_id":            true,
-		"test_name":          true,
-		"test_type":          true,
-		"test_url":           true,
-		"src_host":           true,
-		"dst_host":           true,
-		"src_cloud_region":   true,
-		"src_cloud_provider": true,
-		"src_site":           true,
-		"dst_cloud_region":   true,
-		"dst_cloud_provider": true,
-		"dst_site":           true,
+		"agent_id":               true,
+		"agent_name":             true,
+		"dst_addr":               true,
+		"dst_cdn_int":            true,
+		"dst_geo":                true,
+		"provider":               true,
+		"src_addr":               true,
+		"src_cdn_int":            true,
+		"src_geo":                true,
+		"test_id":                true,
+		"test_name":              true,
+		"test_type":              true,
+		"test_url":               true,
+		"src_host":               true,
+		"dst_host":               true,
+		"src_cloud_region":       true,
+		"src_cloud_provider":     true,
+		"src_site":               true,
+		"dst_cloud_region":       true,
+		"dst_cloud_provider":     true,
+		"dst_site":               true,
+		"statusMessage":          true,
+		"statusEncoding":         true,
+		"https_validity":         true,
+		"https_expiry_timestamp": true,
+	}
+
+	synthAttrKeys = []string{
+		"statusMessage",
+		"statusEncoding",
+		"https_validity",
+		"https_expiry_timestamp",
 	}
 )
 
@@ -359,6 +370,7 @@ func (f *NRMFormat) fromKSynth(in *kt.JCHF) []NRMetric {
 		return nil // Don't worry about timeouts and errrors for now.
 	}
 
+	rawStr := in.CustomStr["error_cause/trace_route"] // Pull this out early.
 	metrics := util.GetSynMetricNameSet(in.CustomInt["result_type"])
 	attr := map[string]interface{}{}
 	f.mux.RLock()
@@ -374,6 +386,23 @@ func (f *NRMFormat) fromKSynth(in *kt.JCHF) []NRMetric {
 		attr["instrumentation.name"] = tt
 	}
 
+	// If there's str00 data, try to unserialize and pass in useful bits.
+	if rawStr != "" {
+		strData := []interface{}{}
+		if err := json.Unmarshal([]byte(rawStr), &strData); err == nil {
+			if len(strData) > 0 {
+				switch sd := strData[0].(type) {
+				case map[string]interface{}:
+					for _, key := range synthAttrKeys {
+						if val, ok := sd[key]; ok {
+							attr[key] = val
+						}
+					}
+				}
+			}
+		}
+	}
+
 	for k, v := range attr { // White list only a few attributes here.
 		if !synthWLAttr[k] {
 			delete(attr, k)
@@ -387,7 +416,7 @@ func (f *NRMFormat) fromKSynth(in *kt.JCHF) []NRMetric {
 
 	for m, name := range metrics {
 		switch name.Name {
-		case "avg_rtt", "jit_rtt", "time", "code", "port", "status", "ttlb":
+		case "avg_rtt", "jit_rtt", "time", "code", "port", "status", "ttlb", "size", "trx_time", "validation":
 			ms = append(ms, NRMetric{
 				Name:       "kentik.synth." + name.Name,
 				Type:       NR_GAUGE_TYPE,
diff --git a/pkg/formats/util/util.go b/pkg/formats/util/util.go
index 2780942..315f107 100644
--- a/pkg/formats/util/util.go
+++ b/pkg/formats/util/util.go
@@ -332,6 +332,12 @@ var (
 		6: map[string]kt.MetricInfo{"fetch_status_|_ping_sent_|_trace_time": kt.MetricInfo{Name: "time"}, "fetch_ttlb_|_ping_lost": kt.MetricInfo{Name: "code"}},
 
 		7: map[string]kt.MetricInfo{"fetch_status_|_ping_sent_|_trace_time": kt.MetricInfo{Name: "time"}, "lat/long_dest": kt.MetricInfo{Name: "port"}},
+
+		8: map[string]kt.MetricInfo{"fetch_status_|_ping_sent_|_trace_time": kt.MetricInfo{Name: "status"}, "fetch_size_|_ping_min_rtt": kt.MetricInfo{Name: "size"}, "fetch_ttlb_|_ping_lost": kt.MetricInfo{Name: "ttlb"}},
+
+		9: map[string]kt.MetricInfo{"fetch_status_|_ping_sent_|_trace_time": kt.MetricInfo{Name: "status"}, "fetch_ttlb_|_ping_lost": kt.MetricInfo{Name: "trx_time"}},
+
+		10: map[string]kt.MetricInfo{"fetch_status_|_ping_sent_|_trace_time": kt.MetricInfo{Name: "time"}, "fetch_ttlb_|_ping_lost": kt.MetricInfo{Name: "validation"}},
 	}
 )
 
diff --git a/pkg/inputs/snmp/mibs/load.go b/pkg/inputs/snmp/mibs/load.go
index 93cab0c..08da010 100644
--- a/pkg/inputs/snmp/mibs/load.go
+++ b/pkg/inputs/snmp/mibs/load.go
@@ -95,7 +95,7 @@ func (db *MibDB) GetTrap(oid string) *Trap {
 
 func (db *MibDB) GetForKey(oid string) (*kt.Mib, map[string]string, error) {
 	if res, ok := db.trapMibs[oid]; ok {
-		return res, nil, nil
+		return res, res.XAttr, nil
 	}
 
 	// Now walk resursivly up the tree, seeing what profiles are found via a wildcard or variables.
@@ -115,6 +115,12 @@ func (db *MibDB) GetForKey(oid string) (*kt.Mib, map[string]string, error) {
 					attrs[name] = strings.Join(pts[posits[0]:posits[0]+posits[1]], ".")
 				}
 			}
+			// Also fill in any const attrs here if they are not already set.
+			for k, v := range t.XAttr {
+				if _, ok := attrs[k]; !ok {
+					attrs[k] = v
+				}
+			}
 			return t, attrs, nil
 		}
 	}
diff --git a/pkg/inputs/snmp/mibs/trap.go b/pkg/inputs/snmp/mibs/trap.go
index 9639af8..b9ca786 100644
--- a/pkg/inputs/snmp/mibs/trap.go
+++ b/pkg/inputs/snmp/mibs/trap.go
@@ -12,10 +12,11 @@ import (
 )
 
 type Trap struct {
-	Oid           string `yaml:"trap_oid"`
-	Name          string `yaml:"trap_name"`
-	DropUndefined bool   `yaml:"drop_undefined"`
-	Events        []OID  `yaml:"events"`
+	Oid           string            `yaml:"trap_oid"`
+	Name          string            `yaml:"trap_name"`
+	DropUndefined bool              `yaml:"drop_undefined"`
+	Events        []OID             `yaml:"events"`
+	Attributes    map[string]string `yaml:"attributes"`
 }
 
 type TrapBase struct {
@@ -93,6 +94,7 @@ func (mdb *MibDB) parseTrapsFromYml(fname string, file os.DirEntry, extends map[
 				Extra:      trap.Name,
 				Mib:        trap.Oid,
 				VarSet:     kvs,
+				XAttr:      trap.Attributes,
 			}
 			if len(mib.Enum) > 0 {
 				mib.EnumRev = make(map[int64]string)
diff --git a/pkg/kt/snmp.go b/pkg/kt/snmp.go
index 99c1f8d..245a582 100644
--- a/pkg/kt/snmp.go
+++ b/pkg/kt/snmp.go
@@ -386,6 +386,7 @@ type Mib struct {
 	Condition    *MibCondition
 	Script       Enricher
 	VarSet       map[string][]int
+	XAttr        map[string]string
 }
 
 type Enricher interface {
diff --git a/pkg/util/enrich/enrich.go b/pkg/util/enrich/enrich.go
index a26ae8c..fdc7724 100644
--- a/pkg/util/enrich/enrich.go
+++ b/pkg/util/enrich/enrich.go
@@ -202,10 +202,19 @@ func (e *Enricher) runScript(ctx context.Context, msgs []*kt.JCHF) ([]*kt.JCHF,
 	case starlark.NoneType:
 		return nil, nil
 	case starlark.Int:
-		e.Infof("RC %d", rv)
+		e.Debugf("RC %d", rv)
 	}
 
-	return msgs, nil
+	out := make([]*kt.JCHF, 0, len(msgs))
+	for _, msg := range inputs {
+		switch rv := msg.(type) {
+		case starlark.NoneType: // Its been set to none, so don't pass this value back up.
+		case *JCHF:
+			out = append(out, rv.Unwrap())
+		}
+	}
+
+	return out, nil
 }
 
 func (e *Enricher) sourceProgram(builtins starlark.StringDict) (*starlark.Program, error) {


Test patch:
diff --git a/.github/workflows/test-on-pr.yml b/.github/workflows/test-on-pr.yml
index 843f538..a4e8276 100644
--- a/.github/workflows/test-on-pr.yml
+++ b/.github/workflows/test-on-pr.yml
@@ -18,19 +18,18 @@ jobs:
       - name: Setup Go
         uses: actions/setup-go@v2
         with:
-          go-version: '1.18.3'
+          go-version: '1.20.4'
 
       - name: Install dependencies
-        run: sudo apt-get install make libpcap-dev golint
+        run: sudo apt-get install make libpcap-dev
 
       - name: Run build
         run: |
           make
 
-      - name: Run vet & lint
+      - name: Run vet
         run: |
           go vet .
-          golint .
 
       - name: Run testing
         run: make test
\ No newline at end of file
diff --git a/pkg/filter/filter_test.go b/pkg/filter/filter_test.go
index 1772f01..69c5314 100644
--- a/pkg/filter/filter_test.go
+++ b/pkg/filter/filter_test.go
@@ -21,12 +21,19 @@ func TestFilter(t *testing.T) {
 		"addr,src_addr,%,10.2.3.0/24",
 		"int,custom_bigint.foo,!=,13",
 		"string,src_addr,%,10.2",
+		"int,fooII,==,12",
+		"string,foo,==,bar",
+		"string,fooAAAA,==,",
+		"foo,==,bar",
+		"fooII,==,12",
+		"src_addr,==,10.2.2.0/24",
+		"foo,==,no or fooII,==,12",
 	}
 	fs, err := GetFilters(l, filters)
 	assert.NoError(err)
 	assert.Equal(len(filters), len(fs))
 
-	results := []bool{true, true, true, false, true, true}
+	results := []bool{true, true, true, false, true, true, true, true, false, true, true, true, true}
 	for i, fs := range fs {
 		assert.Equal(results[i], fs.Filter(kt.InputTesting[0]), "%d -> %v", i, filters[i])
 	}
diff --git a/pkg/inputs/snmp/mibs/trap_test.go b/pkg/inputs/snmp/mibs/trap_test.go
index 0b92ee3..d97ee0d 100644
--- a/pkg/inputs/snmp/mibs/trap_test.go
+++ b/pkg/inputs/snmp/mibs/trap_test.go
@@ -44,6 +44,9 @@ traps:
         OID: 1.3.6.1.4.1.9.9.666.1.3.4.5.{cHsrpGrpTable:2}.{ifIndex:1}
       - name: chsrpTrapVarYandex
         OID: 1.3.6.1.4.1.9.9.1811.1.3.4.5.{ifIndex:1}.{cHsrpGrpTable:2}
+    attributes:
+      responsible_team: vmware
+      cHsrpGrpTable: 777
 `)
 	// Save test data to local.
 	file, err := ioutil.TempFile("", "")
@@ -62,34 +65,39 @@ traps:
 	tr, attr, err := mdb.GetForKey(".1.3.6.1.4.1.34510.2.1.1.3.2.1.1")
 	assert.NoError(t, err)
 	assert.Equal(t, "vdcAlarmId", tr.Name)
-	assert.Equal(t, 0, len(attr))
+	assert.Equal(t, 2, len(attr))
 
 	tr, attr, err = mdb.GetForKey(".1.3.6.1.4.1.34510.22.1.2.3.4.5.6")
 	assert.NoError(t, err)
 	assert.Equal(t, "vdcMonAttribWild", tr.Name)
-	assert.Equal(t, 0, len(attr))
+	assert.Equal(t, 2, len(attr))
 
 	tr, attr, err = mdb.GetForKey(".1.3.6.1.4.1.9.9.187.1.2.1.1.7.2.2.2.3")
 	assert.NoError(t, err)
 	assert.Equal(t, "cbgpPeerLastErrorTxt", tr.Name)
 	assert.Equal(t, "2.2.2.3", attr["bgpPeerRemoteAddr"])
 	assert.Equal(t, "", attr["ifIndex"]) // Since this is after a wildcard, assume nothing because there are no valid tokens to consume.
+	assert.Equal(t, "vmware", attr["responsible_team"])
+	assert.Equal(t, "777", attr["cHsrpGrpTable"])
 
 	tr, attr, err = mdb.GetForKey(".1.3.6.1.4.1.9.9.187.1.3.4.5.999.666")
 	assert.NoError(t, err)
 	assert.Equal(t, "chsrpTrapVarBing", tr.Name)
 	assert.Equal(t, "999", attr["ifIndex"])
 	assert.Equal(t, "666", attr["cHsrpGrpTable"])
+	assert.Equal(t, "vmware", attr["responsible_team"])
 
 	tr, attr, err = mdb.GetForKey(".1.3.6.1.4.1.9.9.666.1.3.4.5.66.99.333")
 	assert.NoError(t, err)
 	assert.Equal(t, "chsrpTwoOne", tr.Name)
 	assert.Equal(t, "333", attr["ifIndex"])
 	assert.Equal(t, "66.99", attr["cHsrpGrpTable"])
+	assert.Equal(t, "vmware", attr["responsible_team"])
 
 	tr, attr, err = mdb.GetForKey(".1.3.6.1.4.1.9.9.1811.1.3.4.5.66.99.333")
 	assert.NoError(t, err)
 	assert.Equal(t, "chsrpTrapVarYandex", tr.Name)
 	assert.Equal(t, "66", attr["ifIndex"])
 	assert.Equal(t, "99.333", attr["cHsrpGrpTable"])
+	assert.Equal(t, "vmware", attr["responsible_team"])
 }
diff --git a/pkg/util/enrich/enrich_test.go b/pkg/util/enrich/enrich_test.go
index e818e0b..aff6023 100644
--- a/pkg/util/enrich/enrich_test.go
+++ b/pkg/util/enrich/enrich_test.go
@@ -149,3 +149,29 @@ def main(n):
 	assert.Equal("fool", out[0].CustomStr["zero"])
 	assert.Equal("barf", out[0].CustomStr["bar"])
 }
+
+func TestRemoveMsg(t *testing.T) {
+	testDataPy := string(`
+def main(n):
+    for i in range(len(n)):
+      if i == 0:
+        n[i] = None
+      else:
+        n[i].company_id = i-1 # Bump everyone up.
+    return len(n)-1
+`)
+
+	assert := assert.New(t)
+	l := lt.NewTestContextL(logger.NilContext, t)
+	e, err := NewEnricher("", testDataPy, "", l.GetLogger().GetUnderlyingLogger())
+	assert.Nil(err)
+	assert.NotNil(e)
+
+	out, err := e.Enrich(context.Background(), kt.InputTestingSnmp)
+	assert.Nil(err)
+	assert.NotNil(out)
+	assert.Equal(len(kt.InputTestingSnmp)-1, len(out))
+	for i, evt := range out {
+		assert.Equal(i, int(evt.CompanyId), "%v", evt)
+	}
+}