Add s2_geo processor plugin (#7087)

This commit is contained in:
alespour 2020-03-10 23:39:06 +01:00 committed by GitHub
parent 0be6275495
commit c5234b365a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 164 additions and 0 deletions

1
go.mod
View File

@ -49,6 +49,7 @@ require (
github.com/gobwas/glob v0.2.3
github.com/gofrs/uuid v2.1.0+incompatible
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec
github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129 // indirect
github.com/golang/protobuf v1.3.2
github.com/google/go-cmp v0.4.0

2
go.sum
View File

@ -166,6 +166,8 @@ github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I=
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec h1:lJwO/92dFXWeXOZdoGXgptLmNLwynMSHUmU6besqtiw=
github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=

View File

@ -5,6 +5,7 @@ import (
_ "github.com/influxdata/telegraf/plugins/processors/converter"
_ "github.com/influxdata/telegraf/plugins/processors/date"
_ "github.com/influxdata/telegraf/plugins/processors/enum"
_ "github.com/influxdata/telegraf/plugins/processors/geo"
_ "github.com/influxdata/telegraf/plugins/processors/override"
_ "github.com/influxdata/telegraf/plugins/processors/parser"
_ "github.com/influxdata/telegraf/plugins/processors/pivot"

View File

@ -0,0 +1,29 @@
# S2 Geo Processor Plugin
Use the `s2geo` processor to add tag with S2 cell ID token of specified [cell level][cell levels].
The tag is used in `experimental/geo` Flux package functions.
The `lat` and `lon` fields values should contain WGS-84 coordinates in decimal degrees.
### Configuration
```toml
[[processors.geo]]
## The name of the lat and lon fields containing WGS-84 latitude and longitude in decimal degrees
lat_field = "lat"
lon_field = "lon"
## New tag to create
tag_key = "s2_cell_id"
## Cell level (see https://s2geometry.io/resources/s2cell_statistics.html)
cell_level = 11
```
### Example
```diff
- mta,area=llir,id=GO505_20_2704,status=1 lat=40.878738,lon=-72.517572 1560540094
+ mta,area=llir,id=GO505_20_2704,status=1,s2_cell_id=89e8ed4 lat=40.878738,lon=-72.517572 1560540094
```
[cell levels]: https://s2geometry.io/resources/s2cell_statistics.html

View File

@ -0,0 +1,76 @@
package geo
import (
"fmt"
"github.com/golang/geo/s2"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/plugins/processors"
)
type Geo struct {
LatField string `toml:"lat_field"`
LonField string `toml:"lon_field"`
TagKey string `toml:"tag_key"`
CellLevel int `toml:"cell_level"`
}
var SampleConfig = `
## The name of the lat and lon fields containing WGS-84 latitude and longitude in decimal degrees
lat_field = "lat"
lon_field = "lon"
## New tag to create
tag_key = "s2_cell_id"
## Cell level (see https://s2geometry.io/resources/s2cell_statistics.html)
cell_level = 9
`
func (g *Geo) SampleConfig() string {
return SampleConfig
}
func (g *Geo) Description() string {
return "Reads latitude and longitude fields and adds tag with with S2 cell ID token of specified level."
}
func (g *Geo) Init() error {
if g.CellLevel < 0 || g.CellLevel > 30 {
return fmt.Errorf("invalid cell level %d", g.CellLevel)
}
return nil
}
func (g *Geo) Apply(in ...telegraf.Metric) []telegraf.Metric {
for _, point := range in {
var latOk, lonOk bool
var lat, lon float64
for _, field := range point.FieldList() {
switch field.Key {
case g.LatField:
lat, latOk = field.Value.(float64)
case g.LonField:
lon, lonOk = field.Value.(float64)
}
}
if latOk && lonOk {
cellID := s2.CellIDFromLatLng(s2.LatLngFromDegrees(lat, lon))
if cellID.IsValid() {
value := cellID.Parent(g.CellLevel).ToToken()
point.AddTag(g.TagKey, value)
}
}
}
return in
}
func init() {
processors.Add("s2geo", func() telegraf.Processor {
return &Geo{
LatField: "lat",
LonField: "lon",
TagKey: "s2_cell_id",
CellLevel: 9,
}
})
}

View File

@ -0,0 +1,55 @@
package geo
import (
"testing"
"time"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/testutil"
"github.com/stretchr/testify/require"
)
func TestGeo(t *testing.T) {
plugin := &Geo{
LatField: "lat",
LonField: "lon",
TagKey: "s2_cell_id",
CellLevel: 11,
}
pluginMostlyDefault := &Geo{
CellLevel: 11,
}
err := plugin.Init()
require.NoError(t, err)
metric := testutil.MustMetric(
"mta",
map[string]string{},
map[string]interface{}{
"lat": 40.878738,
"lon": -72.517572,
},
time.Unix(1578603600, 0),
)
expected := []telegraf.Metric{
testutil.MustMetric(
"mta",
map[string]string{
"s2_cell_id": "89e8ed4",
},
map[string]interface{}{
"lat": 40.878738,
"lon": -72.517572,
},
time.Unix(1578603600, 0),
),
}
actual := plugin.Apply(metric)
testutil.RequireMetricsEqual(t, expected, actual)
actual = pluginMostlyDefault.Apply(metric)
testutil.RequireMetricsEqual(t, expected, actual)
}