package metrics import ( "context" "runtime" "time" ) var metricsReporters []Reporter // AddMetricsReporter to be used func AddMetricsReporter(mr Reporter) { metricsReporters = append(metricsReporters, mr) } // GetMetricsReporters gets registered metrics reporters func GetMetricsReporters() []Reporter { return metricsReporters } // func GetMetricsReporter() metrics.Reporter { // if len(app.metricsReporters) > 0 { // return app.metricsReporters[0] // } // return nil // } // 上报系统运行信息 func PeriodicSysMetrics() { period := time.Second * 15 //.config.GetDuration("pitaya.metrics.periodicMetrics.period") go ReportSysMetrics(metricsReporters, period) // if app.worker.Started() { // go worker.Report(app.metricsReporters, period) // } } // ReportTimingFromCtx reports the latency from the context func ReportTimingFromCtx(ctx context.Context, reporters []Reporter, typ string, err error) { if ctx == nil { return } code := CodeFromError(err) status := "ok" if err != nil { status = "failed" } if len(reporters) > 0 { startTime := GetFromPropagateCtx(ctx, StartTimeKey) route := GetFromPropagateCtx(ctx, RouteKey) elapsed := time.Since(time.Unix(0, startTime.(int64))) tags := getTags(ctx, map[string]string{ "route": route.(string), "status": status, "type": typ, "code": code, }) for _, r := range reporters { r.ReportSummary(ResponseTime, tags, float64(elapsed.Nanoseconds())) } } } // ReportMessageProcessDelayFromCtx reports the delay to process the messages // �ϱ����յ���Ϣ����ʼ����֮��ļ�� func ReportMessageProcessDelayFromCtx(ctx context.Context, reporters []Reporter, typ string) { if len(reporters) > 0 { startTime := GetFromPropagateCtx(ctx, StartTimeKey) elapsed := time.Since(time.Unix(0, startTime.(int64))) route := GetFromPropagateCtx(ctx, RouteKey) tags := getTags(ctx, map[string]string{ "route": route.(string), "type": typ, }) for _, r := range reporters { r.ReportSummary(ProcessDelay, tags, float64(elapsed.Nanoseconds())) } } } // ReportNumberOfConnectedClients reports the number of connected clients func ReportNumberOfConnectedClients(reporters []Reporter, number int64) { for _, r := range reporters { r.ReportGauge(ConnectedClients, map[string]string{}, float64(number)) } } // ReportSysMetrics reports sys metrics func ReportSysMetrics(reporters []Reporter, period time.Duration) { tick := time.NewTicker(period) for { select { case <-tick.C: for _, r := range reporters { num := runtime.NumGoroutine() m := &runtime.MemStats{} runtime.ReadMemStats(m) r.ReportGauge(Goroutines, map[string]string{}, float64(num)) r.ReportGauge(HeapSize, map[string]string{}, float64(m.Alloc)) r.ReportGauge(HeapObjects, map[string]string{}, float64(m.HeapObjects)) } } } } // ReportExceededRateLimiting reports the number of requests made // after exceeded rate limiting in a connection func ReportExceededRateLimiting(reporters []Reporter) { for _, r := range reporters { r.ReportCount(ExceededRateLimiting, map[string]string{}, 1) } } func tagsFromContext(ctx context.Context) map[string]string { val := GetFromPropagateCtx(ctx, MetricTagsKey) if val == nil { return map[string]string{} } tags, ok := val.(map[string]string) if !ok { return map[string]string{} } return tags } func getTags(ctx context.Context, tags map[string]string) map[string]string { for k, v := range tagsFromContext(ctx) { tags[k] = v } return tags } // 上报消息计数 func ReportMessageHandleCount(msg string) { for _, r := range metricsReporters { r.ReportCount(MessageHandler, map[string]string{"handler": msg}, float64(1)) } } // 上报通道容量 已使用容量 func ReportChannelCapacity(channel string, cap int) { for _, r := range metricsReporters { r.ReportGauge(ChannelCapacity, map[string]string{"channel": channel}, float64(cap)) } } // 上报已连接客户端数量 func ReportConnectedClient(num int) { for _, r := range metricsReporters { r.ReportGauge(ConnectedClients, map[string]string{}, float64(num)) } } // 上报连接服务器数量 func ReportConnectedServer(typ string, num int) { for _, r := range metricsReporters { r.ReportGauge(CountServers, map[string]string{"type": typ}, float64(num)) } } // ReportMessageResponseTime 上报消息处理耗时 func ReportMessageResponseTime(label string, value int64) { for _, r := range metricsReporters { r.ReportHistogram(MessageResponseTime, label, float64(value)) } }