extractNewDescMetric extracts a metric from a prometheus.NewDesc() call. Pattern: prometheus.NewDesc(name, help, variableLabels, constLabels) Currently, coder only uses MustNewConstMetric with NewDesc. TODO(ssncferreira): Add support for other MustNewConst* functions if needed.
(call *ast.CallExpr, decls declarations)
| 392 | // Currently, coder only uses MustNewConstMetric with NewDesc. |
| 393 | // TODO(ssncferreira): Add support for other MustNewConst* functions if needed. |
| 394 | func extractNewDescMetric(call *ast.CallExpr, decls declarations) (Metric, bool) { |
| 395 | // Check if this is a prometheus.NewDesc call. |
| 396 | sel, ok := call.Fun.(*ast.SelectorExpr) |
| 397 | if !ok { |
| 398 | return Metric{}, false |
| 399 | } |
| 400 | |
| 401 | // Match calls that are exactly "prometheus.NewDesc()". This checks the local |
| 402 | // package identifier, not the resolved import path. If the prometheus package |
| 403 | // is imported with an alias, this will not match. |
| 404 | ident, ok := sel.X.(*ast.Ident) |
| 405 | if !ok || ident.Name != "prometheus" || sel.Sel.Name != "NewDesc" { |
| 406 | return Metric{}, false |
| 407 | } |
| 408 | |
| 409 | // NewDesc requires at least 4 arguments: name, help, variableLabels, constLabels |
| 410 | if len(call.Args) < 4 { |
| 411 | return Metric{}, false |
| 412 | } |
| 413 | |
| 414 | // Extract name (first argument). |
| 415 | name := resolveStringExpr(call.Args[0], decls) |
| 416 | if name == "" { |
| 417 | warnf("extractNewDescMetric: skipping prometheus.NewDesc() call: could not resolve metric name") |
| 418 | return Metric{}, false |
| 419 | } |
| 420 | |
| 421 | // Extract help (second argument). |
| 422 | help := resolveStringExpr(call.Args[1], decls) |
| 423 | |
| 424 | // Extract labels (third argument). |
| 425 | labels := extractLabels(call.Args[2], decls) |
| 426 | |
| 427 | // Infer metric type from name suffix. |
| 428 | // TODO(ssncferreira): The actual type is determined by the MustNewConst* function |
| 429 | // that uses this descriptor (e.g., MustNewConstMetric with prometheus.CounterValue or |
| 430 | // prometheus.GaugeValue). Currently, coder only uses MustNewConstMetric, so we |
| 431 | // infer the type from naming conventions. |
| 432 | metricType := MetricTypeGauge |
| 433 | if strings.HasSuffix(name, "_total") || strings.HasSuffix(name, "_count") { |
| 434 | metricType = MetricTypeCounter |
| 435 | } |
| 436 | |
| 437 | return Metric{ |
| 438 | Name: name, |
| 439 | Type: metricType, |
| 440 | Help: help, |
| 441 | Labels: labels, |
| 442 | }, true |
| 443 | } |
| 444 | |
| 445 | // parseMetricFuncName parses a prometheus function name and returns the metric type |
| 446 | // and whether it's a Vec type. Returns empty string if not a recognized metric function. |
no test coverage detected