mirror of
https://github.com/simon987/feed_archiver.git
synced 2025-04-18 01:46:46 +00:00
Add influxdb monitoring
This commit is contained in:
parent
e8ea4ff1dd
commit
2b25f2afe0
1
go.mod
1
go.mod
@ -7,6 +7,7 @@ require (
|
|||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||||
github.com/go-redis/redis/v8 v8.0.0-beta.2
|
github.com/go-redis/redis/v8 v8.0.0-beta.2
|
||||||
github.com/gofrs/uuid v3.2.0+incompatible // indirect
|
github.com/gofrs/uuid v3.2.0+incompatible // indirect
|
||||||
|
github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab
|
||||||
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 // indirect
|
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 // indirect
|
||||||
github.com/jackc/pgx v3.6.2+incompatible
|
github.com/jackc/pgx v3.6.2+incompatible
|
||||||
github.com/lib/pq v1.2.0 // indirect
|
github.com/lib/pq v1.2.0 // indirect
|
||||||
|
2
go.sum
2
go.sum
@ -39,6 +39,8 @@ github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
|
|||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
|
github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab h1:HqW4xhhynfjrtEiiSGcQUd6vrK23iMam1FO8rI7mwig=
|
||||||
|
github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||||
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc=
|
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGUK1IDqRa5lAAvEkZG1LKaCRc=
|
||||||
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
|
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
|
||||||
github.com/jackc/pgx v3.6.2+incompatible h1:2zP5OD7kiyR3xzRYMhOcXVvkDZsImVXfj+yIyTQf3/o=
|
github.com/jackc/pgx v3.6.2+incompatible h1:2zP5OD7kiyR3xzRYMhOcXVvkDZsImVXfj+yIyTQf3/o=
|
||||||
|
97
influxdb.go
Normal file
97
influxdb.go
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
influx "github.com/influxdata/influxdb1-client/v2"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Monitoring struct {
|
||||||
|
influxdb influx.Client
|
||||||
|
points chan *influx.Point
|
||||||
|
connString string
|
||||||
|
bufferSize int
|
||||||
|
retentionPolicy string
|
||||||
|
database string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMonitoring(connString string, buffer int) *Monitoring {
|
||||||
|
m := new(Monitoring)
|
||||||
|
m.bufferSize = buffer
|
||||||
|
m.points = make(chan *influx.Point, m.bufferSize)
|
||||||
|
m.retentionPolicy = ""
|
||||||
|
m.database = "feed_archiver"
|
||||||
|
m.influxdb, _ = influx.NewHTTPClient(influx.HTTPConfig{
|
||||||
|
Addr: connString,
|
||||||
|
})
|
||||||
|
go m.asyncWriter()
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Monitoring) asyncWriter() {
|
||||||
|
|
||||||
|
logrus.Info("Started async influxdb writer")
|
||||||
|
|
||||||
|
bp, _ := influx.NewBatchPoints(influx.BatchPointsConfig{
|
||||||
|
Database: m.database,
|
||||||
|
RetentionPolicy: m.retentionPolicy,
|
||||||
|
})
|
||||||
|
|
||||||
|
for point := range m.points {
|
||||||
|
bp.AddPoint(point)
|
||||||
|
|
||||||
|
if len(bp.Points()) >= m.bufferSize {
|
||||||
|
m.flushQueue(&bp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.flushQueue(&bp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Monitoring) flushQueue(bp *influx.BatchPoints) {
|
||||||
|
|
||||||
|
err := m.influxdb.Write(*bp)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
logrus.WithError(err).Error("influxdb write")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
logrus.WithFields(logrus.Fields{
|
||||||
|
"size": len((*bp).Points()),
|
||||||
|
}).Debug("Wrote points")
|
||||||
|
|
||||||
|
*bp, _ = influx.NewBatchPoints(influx.BatchPointsConfig{
|
||||||
|
Database: m.database,
|
||||||
|
RetentionPolicy: m.retentionPolicy,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Monitoring) writeMetricInsertRow(size int, table string) {
|
||||||
|
|
||||||
|
point, _ := influx.NewPoint(
|
||||||
|
"insert_row",
|
||||||
|
map[string]string{
|
||||||
|
"table": table,
|
||||||
|
},
|
||||||
|
map[string]interface{}{
|
||||||
|
"size": size,
|
||||||
|
},
|
||||||
|
time.Now(),
|
||||||
|
)
|
||||||
|
m.points <- point
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Monitoring) writeMetricUniqueViolation(size int, table string) {
|
||||||
|
|
||||||
|
point, _ := influx.NewPoint(
|
||||||
|
"unique_violation",
|
||||||
|
map[string]string{
|
||||||
|
"table": table,
|
||||||
|
},
|
||||||
|
map[string]interface{}{
|
||||||
|
"size": size,
|
||||||
|
},
|
||||||
|
time.Now(),
|
||||||
|
)
|
||||||
|
m.points <- point
|
||||||
|
}
|
51
main.go
51
main.go
@ -23,14 +23,16 @@ var pool *pgx.ConnPool
|
|||||||
var replacer = strings.NewReplacer(".", "_")
|
var replacer = strings.NewReplacer(".", "_")
|
||||||
|
|
||||||
type FeedArchiverArgs struct {
|
type FeedArchiverArgs struct {
|
||||||
DbHost string
|
DbHost string
|
||||||
DbUser string
|
DbUser string
|
||||||
DbPassword string
|
DbPassword string
|
||||||
DbDatabase string
|
DbDatabase string
|
||||||
RedisAddr string
|
RedisAddr string
|
||||||
RedisPassword string
|
RedisPassword string
|
||||||
Pattern string
|
Pattern string
|
||||||
Threads int
|
Threads int
|
||||||
|
InfluxDb string
|
||||||
|
InfluxDbBuffer int
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -42,7 +44,7 @@ func main() {
|
|||||||
Email: "me@simon987.net",
|
Email: "me@simon987.net",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
app.Version = "3.0"
|
app.Version = "4.0"
|
||||||
|
|
||||||
args := FeedArchiverArgs{}
|
args := FeedArchiverArgs{}
|
||||||
|
|
||||||
@ -95,13 +97,27 @@ func main() {
|
|||||||
Destination: &args.Threads,
|
Destination: &args.Threads,
|
||||||
EnvVars: []string{"FA_THREADS"},
|
EnvVars: []string{"FA_THREADS"},
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "influxdb",
|
||||||
|
Usage: "Influxdb connection string",
|
||||||
|
Value: "",
|
||||||
|
Destination: &args.InfluxDb,
|
||||||
|
EnvVars: []string{"FA_INFLUXDB"},
|
||||||
|
},
|
||||||
|
&cli.IntFlag{
|
||||||
|
Name: "influxdb-buffer",
|
||||||
|
Usage: "Influxdb buffer size",
|
||||||
|
Value: 500,
|
||||||
|
Destination: &args.InfluxDbBuffer,
|
||||||
|
EnvVars: []string{"FA_INFLUXDB_BUFFER"},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
app.Action = func(c *cli.Context) error {
|
app.Action = func(c *cli.Context) error {
|
||||||
|
|
||||||
archiverCtx.tables = map[string]bool{}
|
archiverCtx.tables = map[string]bool{}
|
||||||
|
|
||||||
logrus.SetLevel(logrus.InfoLevel)
|
logrus.SetLevel(logrus.DebugLevel)
|
||||||
|
|
||||||
connPoolConfig := pgx.ConnPoolConfig{
|
connPoolConfig := pgx.ConnPoolConfig{
|
||||||
ConnConfig: pgx.ConnConfig{
|
ConnConfig: pgx.ConnConfig{
|
||||||
@ -113,6 +129,11 @@ func main() {
|
|||||||
MaxConnections: args.Threads,
|
MaxConnections: args.Threads,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var mon *Monitoring = nil
|
||||||
|
if args.InfluxDb != "" {
|
||||||
|
mon = NewMonitoring(args.InfluxDb, args.InfluxDbBuffer)
|
||||||
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
pool, err = pgx.NewConnPool(connPoolConfig)
|
pool, err = pgx.NewConnPool(connPoolConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -133,7 +154,7 @@ func main() {
|
|||||||
func(message string, key string) error {
|
func(message string, key string) error {
|
||||||
|
|
||||||
table := routingKeyToTable(key[len(args.Pattern)-1:], replacer)
|
table := routingKeyToTable(key[len(args.Pattern)-1:], replacer)
|
||||||
archive(parser, table, message)
|
archive(parser, table, message, mon)
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -160,7 +181,7 @@ func routingKeyToTable(key string, replacer *strings.Replacer) string {
|
|||||||
return table
|
return table
|
||||||
}
|
}
|
||||||
|
|
||||||
func archive(parser fastjson.Parser, table string, json string) {
|
func archive(parser fastjson.Parser, table string, json string, mon *Monitoring) {
|
||||||
item, _ := parser.Parse(json)
|
item, _ := parser.Parse(json)
|
||||||
|
|
||||||
idValue := item.Get("_id")
|
idValue := item.Get("_id")
|
||||||
@ -188,11 +209,17 @@ func archive(parser fastjson.Parser, table string, json string) {
|
|||||||
"id": idValue,
|
"id": idValue,
|
||||||
}).Debug("Insert row")
|
}).Debug("Insert row")
|
||||||
|
|
||||||
|
messageSize := len(json)
|
||||||
|
|
||||||
_, err := pool.Exec(fmt.Sprintf("INSERT INTO %s (id, data) VALUES ($1, $2)", table), id, item.String())
|
_, err := pool.Exec(fmt.Sprintf("INSERT INTO %s (id, data) VALUES ($1, $2)", table), id, item.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err.(pgx.PgError).Code != "23505" {
|
if err.(pgx.PgError).Code != "23505" {
|
||||||
logrus.WithError(err).Error("Error during insert")
|
logrus.WithError(err).Error("Error during insert")
|
||||||
|
} else if mon != nil {
|
||||||
|
mon.writeMetricUniqueViolation(messageSize, table)
|
||||||
}
|
}
|
||||||
|
} else if mon != nil {
|
||||||
|
mon.writeMetricInsertRow(messageSize, table)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user