diff --git a/ginmetrics/middleware.go b/ginmetrics/middleware.go index 20eb8fb..efae0b9 100644 --- a/ginmetrics/middleware.go +++ b/ginmetrics/middleware.go @@ -59,47 +59,98 @@ func (m *Monitor) initGinMetrics() { Type: Counter, Name: metricRequestTotal, Description: "all the server received request num.", - Labels: nil, + Labels: m.getMetricLabelsIncludingMetadata(metricRequestTotal), }) _ = monitor.AddMetric(&Metric{ Type: Counter, Name: metricRequestUVTotal, Description: "all the server received ip num.", - Labels: nil, + Labels: m.getMetricLabelsIncludingMetadata(metricRequestUVTotal), }) _ = monitor.AddMetric(&Metric{ Type: Counter, Name: metricURIRequestTotal, Description: "all the server received request num with every uri.", - Labels: []string{"uri", "method", "code"}, + Labels: m.getMetricLabelsIncludingMetadata(metricURIRequestTotal), }) _ = monitor.AddMetric(&Metric{ Type: Counter, Name: metricRequestBody, Description: "the server received request body size, unit byte", - Labels: nil, + Labels: m.getMetricLabelsIncludingMetadata(metricRequestBody), }) _ = monitor.AddMetric(&Metric{ Type: Counter, Name: metricResponseBody, Description: "the server send response body size, unit byte", - Labels: nil, + Labels: m.getMetricLabelsIncludingMetadata(metricResponseBody), }) _ = monitor.AddMetric(&Metric{ Type: Histogram, Name: metricRequestDuration, Description: "the time server took to handle the request.", - Labels: []string{"uri"}, + Labels: m.getMetricLabelsIncludingMetadata(metricRequestDuration), Buckets: m.reqDuration, }) _ = monitor.AddMetric(&Metric{ Type: Counter, Name: metricSlowRequest, Description: fmt.Sprintf("the server handled slow requests counter, t=%d.", m.slowTime), - Labels: []string{"uri", "method", "code"}, + Labels: m.getMetricLabelsIncludingMetadata(metricSlowRequest), }) } +func (m *Monitor) includesMetadata() bool { + return len(m.metadata) > 0 +} + +func (m *Monitor) getMetadata() ([]string, []string) { + metadata_labels := []string{} + metadata_values := []string{} + + for v := range m.metadata { + metadata_labels = append(metadata_labels, v) + metadata_values = append(metadata_values, m.metadata[v]) + } + + return metadata_labels, metadata_values +} + +func (m *Monitor) getMetricLabelsIncludingMetadata(metricName string) []string { + includes_metadata := m.includesMetadata() + metadata_labels, _ := m.getMetadata() + + switch metricName { + case metricRequestDuration: + metric_labels := []string{"uri"} + if includes_metadata { + metric_labels = append(metric_labels, metadata_labels...) + } + return metric_labels + + case metricURIRequestTotal: + metric_labels := []string{"uri", "method", "code"} + if includes_metadata { + metric_labels = append(metric_labels, metadata_labels...) + } + return metric_labels + + case metricSlowRequest: + metric_labels := []string{"uri", "method", "code"} + if includes_metadata { + metric_labels = append(metric_labels, metadata_labels...) + } + return metric_labels + + default: + var metric_labels []string = nil + if includes_metadata { + metric_labels = metadata_labels + } + return metric_labels + } +} + // monitorInterceptor as gin monitor middleware. func (m *Monitor) monitorInterceptor(ctx *gin.Context) { // some paths should not be reported @@ -122,34 +173,50 @@ func (m *Monitor) ginMetricHandle(ctx *gin.Context, start time.Time) { w := ctx.Writer // set request total - _ = m.GetMetric(metricRequestTotal).Inc(nil) + var metric_values []string = nil + _ = m.GetMetric(metricRequestTotal).Inc(m.getMetricValues(metric_values)) // set uv if clientIP := ctx.ClientIP(); !bloomFilter.Contains(clientIP) { bloomFilter.Add(clientIP) - _ = m.GetMetric(metricRequestUVTotal).Inc(nil) + metric_values = nil + _ = m.GetMetric(metricRequestUVTotal).Inc(m.getMetricValues(metric_values)) } // set uri request total - _ = m.GetMetric(metricURIRequestTotal).Inc([]string{ctx.FullPath(), r.Method, strconv.Itoa(w.Status())}) + metric_values = []string{ctx.FullPath(), r.Method, strconv.Itoa(w.Status())} + _ = m.GetMetric(metricURIRequestTotal).Inc(m.getMetricValues(metric_values)) // set request body size // since r.ContentLength can be negative (in some occasions) guard the operation if r.ContentLength >= 0 { - _ = m.GetMetric(metricRequestBody).Add(nil, float64(r.ContentLength)) + metric_values = nil + _ = m.GetMetric(metricRequestBody).Add(m.getMetricValues(metric_values), float64(r.ContentLength)) } // set slow request latency := time.Since(start) if int32(latency.Seconds()) > m.slowTime { - _ = m.GetMetric(metricSlowRequest).Inc([]string{ctx.FullPath(), r.Method, strconv.Itoa(w.Status())}) + metric_values = []string{ctx.FullPath(), r.Method, strconv.Itoa(w.Status())} + _ = m.GetMetric(metricSlowRequest).Inc(m.getMetricValues(metric_values)) } // set request duration - _ = m.GetMetric(metricRequestDuration).Observe([]string{ctx.FullPath()}, latency.Seconds()) + metric_values = []string{ctx.FullPath()} + _ = m.GetMetric(metricRequestDuration).Observe(m.getMetricValues(metric_values), latency.Seconds()) // set response size if w.Size() > 0 { - _ = m.GetMetric(metricResponseBody).Add(nil, float64(w.Size())) + metric_values = nil + _ = m.GetMetric(metricResponseBody).Add(m.getMetricValues(metric_values), float64(w.Size())) + } +} + +func (m *Monitor) getMetricValues(metric_values []string) []string { + includes_metadata := m.includesMetadata() + _, metadata_values := m.getMetadata() + if includes_metadata { + metric_values = append(metric_values, metadata_values...) } + return metric_values } diff --git a/ginmetrics/types.go b/ginmetrics/types.go index 1444dd0..d284e55 100644 --- a/ginmetrics/types.go +++ b/ginmetrics/types.go @@ -38,6 +38,7 @@ type Monitor struct { excludePaths []string reqDuration []float64 metrics map[string]*Metric + metadata map[string]string } // GetMonitor used to get global Monitor object, @@ -50,6 +51,7 @@ func GetMonitor() *Monitor { excludePaths: defaultExcludePaths, reqDuration: defaultDuration, metrics: make(map[string]*Metric), + metadata: make(map[string]string), } } return monitor