forked from influxdata/telegraf
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add s2_geo processor plugin (influxdata#7087)
- Loading branch information
Showing
6 changed files
with
164 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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, | ||
} | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
} |