-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
pushgw transfer time series data to kafka
- Loading branch information
Showing
7 changed files
with
285 additions
and
31 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
package kafka | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/IBM/sarama" | ||
"github.com/prometheus/client_golang/prometheus" | ||
) | ||
|
||
const ( | ||
AsyncProducer = "async" | ||
SyncProducer = "sync" | ||
) | ||
|
||
var ( | ||
KafkaProducerSuccess = prometheus.NewCounterVec( | ||
prometheus.CounterOpts{ | ||
Name: "kafka_producer_message_success_total", | ||
Help: "Total number of successful messages sent to Kafka.", | ||
}, | ||
[]string{"producer_type"}, | ||
) | ||
|
||
KafkaProducerError = prometheus.NewCounterVec( | ||
prometheus.CounterOpts{ | ||
Name: "kafka_producer_message_error_total", | ||
Help: "Total number of errors encountered while sending messages to Kafka.", | ||
}, | ||
[]string{"producer_type"}, | ||
) | ||
) | ||
|
||
func init() { | ||
prometheus.MustRegister( | ||
KafkaProducerSuccess, | ||
KafkaProducerError, | ||
) | ||
} | ||
|
||
type ( | ||
Producer interface { | ||
Send(*sarama.ProducerMessage) error | ||
Close() error | ||
} | ||
|
||
AsyncProducerWrapper struct { | ||
asyncProducer sarama.AsyncProducer | ||
stop chan struct{} | ||
} | ||
|
||
SyncProducerWrapper struct { | ||
syncProducer sarama.SyncProducer | ||
stop chan struct{} | ||
} | ||
) | ||
|
||
func New(typ string, brokers []string, config *sarama.Config) (Producer, error) { | ||
stop := make(chan struct{}) | ||
switch typ { | ||
case AsyncProducer: | ||
p, err := sarama.NewAsyncProducer(brokers, config) | ||
if err != nil { | ||
return nil, err | ||
} | ||
apw := &AsyncProducerWrapper{ | ||
asyncProducer: p, | ||
stop: stop, | ||
} | ||
go apw.errorWorker() | ||
go apw.successWorker() | ||
return apw, nil | ||
case SyncProducer: | ||
if !config.Producer.Return.Successes { | ||
config.Producer.Return.Successes = true | ||
} | ||
p, err := sarama.NewSyncProducer(brokers, config) | ||
return &SyncProducerWrapper{syncProducer: p}, err | ||
default: | ||
return nil, fmt.Errorf("unknown producer type: %s", typ) | ||
} | ||
} | ||
|
||
func (p *AsyncProducerWrapper) Send(msg *sarama.ProducerMessage) error { | ||
p.asyncProducer.Input() <- msg | ||
return nil | ||
} | ||
|
||
func (p *AsyncProducerWrapper) Close() error { | ||
close(p.stop) | ||
return p.asyncProducer.Close() | ||
} | ||
|
||
func (p *AsyncProducerWrapper) errorWorker() { | ||
for { | ||
select { | ||
case <-p.asyncProducer.Errors(): | ||
KafkaProducerError.WithLabelValues(AsyncProducer).Inc() | ||
case <-p.stop: | ||
return | ||
} | ||
} | ||
} | ||
|
||
func (p *AsyncProducerWrapper) successWorker() { | ||
for { | ||
select { | ||
case <-p.asyncProducer.Successes(): | ||
KafkaProducerSuccess.WithLabelValues(AsyncProducer).Inc() | ||
case <-p.stop: | ||
return | ||
} | ||
} | ||
} | ||
|
||
func (p *SyncProducerWrapper) Send(msg *sarama.ProducerMessage) error { | ||
_, _, err := p.syncProducer.SendMessage(msg) | ||
if err == nil { | ||
KafkaProducerSuccess.WithLabelValues(SyncProducer).Inc() | ||
} | ||
return err | ||
} | ||
|
||
func (p *SyncProducerWrapper) Close() error { | ||
close(p.stop) | ||
return p.syncProducer.Close() | ||
} |
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,54 @@ | ||
package writer | ||
|
||
import ( | ||
"time" | ||
|
||
"github.com/IBM/sarama" | ||
"github.com/ccfos/nightingale/v6/pushgw/kafka" | ||
"github.com/ccfos/nightingale/v6/pushgw/pconf" | ||
"github.com/prometheus/prometheus/prompb" | ||
"github.com/toolkits/pkg/logger" | ||
) | ||
|
||
type KafkaWriterType struct { | ||
Opts pconf.KafkaWriterOptions | ||
ForceUseServerTS bool | ||
Client kafka.Producer | ||
RetryCount int | ||
RetryInterval int64 // 单位秒 | ||
} | ||
|
||
func (w KafkaWriterType) Write(key string, items []prompb.TimeSeries, headers ...map[string]string) { | ||
if len(items) == 0 { | ||
return | ||
} | ||
|
||
items = Relabel(items, w.Opts.WriteRelabels) | ||
if len(items) == 0 { | ||
return | ||
} | ||
|
||
data, err := beforeWrite(key, items, w.ForceUseServerTS, ForwardKafkaDuration) | ||
if err != nil { | ||
logger.Warningf("marshal prom data to proto got error: %v, data: %+v", err, items) | ||
return | ||
} | ||
|
||
for i := 0; i < w.RetryCount; i++ { | ||
err := w.Client.Send(&sarama.ProducerMessage{Topic: w.Opts.Topic, | ||
Key: sarama.StringEncoder(key), Value: sarama.ByteEncoder(data)}) | ||
if err == nil { | ||
break | ||
} | ||
|
||
CounterWirteErrorTotal.WithLabelValues(key).Add(float64(len(items))) | ||
logger.Warningf("send to kafka got error: %v in %d times, broker: %v, topic: %s", | ||
err, i, w.Opts.Brokers, w.Opts.Topic) | ||
|
||
if i == 0 { | ||
logger.Warning("example timeseries:", items[0].String()) | ||
} | ||
|
||
time.Sleep(time.Duration(w.RetryInterval) * time.Second) | ||
} | ||
} |
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
Oops, something went wrong.