(PUP-2750) Add hierarchical metric ids to profiler

This commit modifies the signature of the
`Puppet::Util::Profiler.profile` method to accept a new argument,
which is basically a "metric id".  The argument takes the form
of an array of strings/symbols, allowing us to group specific sets of
profiling data into hierarchies and report aggregate profiling
statistics at any level of the hierarchy.

It also adds a new profiler, `Aggregate`, which extends the
existing `WallClock` profiler.  The new profiler tracks the
aggregate timing data based on the metric id hierarchy,
and logs a message containing the aggregate data
at the end of the run.
This is the part of this PR that I waffled the most on.  I could introduce a `LoggingProfilerContext` class with a `description` or `message` getter on it, and then extend that class to add a `WallClockProfilerContext` class that adds in the `time` accessor, if that seems cleaner than using a hash.  Also open to other suggestions.