This patch adds an overload to `Base.getindex` for the `Family`
collector to have the same meaning as `Prometheus.labels`.
`family[labels]` is equivalent to `Prometheus.labels(family, 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.