checkLabels returns whether the provided Collector has a non-const, non-curried label named "code" and/or "method". It panics if the provided Collector does not have a Desc or has more than one Desc or its Desc is invalid. It also panics if the Collector has any non-const, non-curried labels that ar
(c prometheus.Collector)
| 309 | // invalid. It also panics if the Collector has any non-const, non-curried |
| 310 | // labels that are not named "code" or "method". |
| 311 | func checkLabels(c prometheus.Collector) (code, method bool) { |
| 312 | // TODO(beorn7): Remove this hacky way to check for instance labels |
| 313 | // once Descriptors can have their dimensionality queried. |
| 314 | var ( |
| 315 | desc *prometheus.Desc |
| 316 | m prometheus.Metric |
| 317 | pm dto.Metric |
| 318 | lvs []string |
| 319 | ) |
| 320 | |
| 321 | // Get the Desc from the Collector. |
| 322 | descc := make(chan *prometheus.Desc, 1) |
| 323 | c.Describe(descc) |
| 324 | |
| 325 | select { |
| 326 | case desc = <-descc: |
| 327 | default: |
| 328 | panic("no description provided by collector") |
| 329 | } |
| 330 | select { |
| 331 | case <-descc: |
| 332 | panic("more than one description provided by collector") |
| 333 | default: |
| 334 | } |
| 335 | |
| 336 | close(descc) |
| 337 | |
| 338 | // Make sure the Collector has a valid Desc by registering it with a |
| 339 | // temporary registry. |
| 340 | prometheus.NewRegistry().MustRegister(c) |
| 341 | |
| 342 | // Create a ConstMetric with the Desc. Since we don't know how many |
| 343 | // variable labels there are, try for as long as it needs. |
| 344 | for err := errors.New("dummy"); err != nil; lvs = append(lvs, magicString) { |
| 345 | m, err = prometheus.NewConstMetric(desc, prometheus.UntypedValue, 0, lvs...) |
| 346 | } |
| 347 | |
| 348 | // Write out the metric into a proto message and look at the labels. |
| 349 | // If the value is not the magicString, it is a constLabel, which doesn't interest us. |
| 350 | // If the label is curried, it doesn't interest us. |
| 351 | // In all other cases, only "code" or "method" is allowed. |
| 352 | if err := m.Write(&pm); err != nil { |
| 353 | panic("error checking metric for labels") |
| 354 | } |
| 355 | for _, label := range pm.Label { |
| 356 | name, value := label.GetName(), label.GetValue() |
| 357 | if value != magicString || isLabelCurried(c, name) { |
| 358 | continue |
| 359 | } |
| 360 | switch name { |
| 361 | case "code": |
| 362 | code = true |
| 363 | case "method": |
| 364 | method = true |
| 365 | default: |
| 366 | panic("metric partitioned with non-supported labels") |
| 367 | } |
| 368 | } |