This patch changes how new child collectors are constructed. Previously
only `metric_name`, `help`, and `registry=nothing` were passed to the
constructor `C`. With this patch any `args...` and `; kwargs...` not
consumed by the `Family{C}` constructor are passed along as well. In
order to make this efficient a constructor closure is created in the
`Family{C}` constructor and stored in the `Family` struct.
This change is in preparation for the Histogram collector where more
arguments is needed to construct the children. It also make it easier to
later add the option to explicitly pass a constructor, or to specialize
the closure on the specific collector type `C`.
This patch moves the label names from the Metric struct to the Sample
struct in preparation for the Histogram collector where only some of the
samples have labels.
This patch changes how label names and label values can be passed to the
constructor `Prometheus.Family{C}` and `Prometheus.labels`. In
particular, the label names are now stored as symbols internally. This
enables using `getfield` when creating the corresponding label values.
Concretely this enables using e.g. named tuples, and custom structs, as
label names/values.
For example, the following now works
```julia
struct RequestLabels
target::String
status_code::Int
end
request_counter = Prometheus.Family{Prometheus.Counter}(
"http_requests", "Total number of HTTP requests", RequestLabels
)
counter = Prometheus.labels(request_counter, RequestLabels("/api", 200))
```
In this example, the field names of the type, `RequestLabels`, are used
as label names in the `Family{C}` constructor. When extracting the
counter for a specific set of labels an instance of the struct is used.
All non-string values are stringified using string (`status_code::Int`
in the example above, for example).
- New macro `Prometheus.@time collector <expr>` for timing `<expr>` and
pass the elapsed time to the collector.
- New macro `Prometheus.@inprogress collector <expr>` to track number of
in-progress concurrent evalutations of `<expr>`.
In both cases, `<expr>` can be a single expression, a block, or a
function *definition*. In the latter case, all calls to the function
will be instrumented (no matter the call site). See documentation for
more details.