scanFile parses a single Go file and extracts all Prometheus metric definitions.
(path string)
| 189 | |
| 190 | // scanFile parses a single Go file and extracts all Prometheus metric definitions. |
| 191 | func scanFile(path string) ([]Metric, error) { |
| 192 | fset := token.NewFileSet() |
| 193 | file, err := parser.ParseFile(fset, path, nil, parser.SkipObjectResolution) |
| 194 | if err != nil { |
| 195 | return nil, xerrors.Errorf("parsing file: %w", err) |
| 196 | } |
| 197 | |
| 198 | // Collect exported constants into the global package declarations map. |
| 199 | collectPackageConsts(file) |
| 200 | |
| 201 | // Collect file-local const and var declarations for resolving references. |
| 202 | decls := collectDecls(file) |
| 203 | |
| 204 | var metrics []Metric |
| 205 | |
| 206 | // Walk the AST looking for metric registration calls. |
| 207 | ast.Inspect(file, func(n ast.Node) bool { |
| 208 | call, ok := n.(*ast.CallExpr) |
| 209 | if !ok { |
| 210 | return true |
| 211 | } |
| 212 | |
| 213 | metric, ok := extractMetricFromCall(call, decls) |
| 214 | if ok { |
| 215 | if metric.Help == "" { |
| 216 | warnf("metric %q has no HELP description, skipping", metric.Name) |
| 217 | // Skip metrics without descriptions, they should be fixed in the source code |
| 218 | // or added to the static metrics file with a manual description. |
| 219 | return true |
| 220 | } |
| 221 | metrics = append(metrics, metric) |
| 222 | } |
| 223 | |
| 224 | return true |
| 225 | }) |
| 226 | |
| 227 | return metrics, nil |
| 228 | } |
| 229 | |
| 230 | // collectPackageConsts collects exported string constants from a file into |
| 231 | // the global packageDeclarations map, keyed by package name. |
no test coverage detected