Using Ghostferry in Custom Applications
For an example application, see ghostferry-copydb.
Consuming Ghostferry Metrics
Ghostferry provides optional metrics to your application. The following is a complete program that consumes them and emits one metric of its own:
package main
import (
"fmt"
"github.com/Shopify/ghostferry"
)
func main() {
sink := make(chan interface{}, 512)
metrics := ghostferry.SetGlobalMetrics("myApp", sink)
metrics.AddConsumer()
go func() {
defer metrics.DoneConsumer()
for m := range sink {
switch metric := m.(type) {
case ghostferry.CountMetric:
fmt.Printf("count %s=%d\n", metric.Key, metric.Value)
case ghostferry.GaugeMetric:
fmt.Printf("gauge %s=%g\n", metric.Key, metric.Value)
case ghostferry.TimerMetric:
fmt.Printf("timer %s=%s\n", metric.Key, metric.Value)
}
}
}()
metrics.Count("myOwnCustomMetrics", 42, nil, 1.0)
metrics.StopAndFlush()
}
Metric keys are prefixed with the name passed to SetGlobalMetrics, so this prints count myApp.myOwnCustomMetrics=42. StopAndFlush closes the sink and waits for every consumer registered with AddConsumer to call DoneConsumer. In a real application, stop everything that emits metrics (including the Ferry) before calling StopAndFlush, because sending to the closed sink panics. Metrics are sent without blocking: when the sink is full, a metric is dropped and a warning is logged, so size the channel for your consumer’s throughput.