class_docstr: ProducerConsumer wrapper with log_progress reporting.
  
  It is to be used around a `consumer` which returns or yields result records.
  If that is not the case -- use regular `ProducerConsumer`.
  
  It will update `.total` of the `log_progress` each time it changes (i.e. whenever
  producer produced new values to be consumed).
code: def __iter__(self):
      pid = str(
          uuid.uuid4()
      )  # could be based on PID and time may be to be informative?
      lgr_ = self.lgr
      label = self.label
      if lgr_ is None:
          lgr_ = lgr
  
      log_progress(
          lgr_.info,
          pid,
          "%s: starting",
          self.label,
          # will become known only later total=len(items),
          label=self.label,
          unit=" " + self.unit,
          noninteractive_level=5,
      )
      counts = defaultdict(int)
      total_announced = None  # self.total
      for res in super().__iter__():
          if self.total and total_announced != self.total:
              # update total with new information
              log_progress(
                  lgr_.info,
                  pid,
                  "",  # None flips python 3.6.7 in conda if nose ran without -s
                  # I do not think there is something
                  # valuable to announce
                  total=self.total,
                  # unfortunately of no effect, so we cannot inform that more items to come
                  # unit=("+" if not it.finished else "") + " " + unit,
                  update=0,  # not None, so it does not stop
                  noninteractive_level=5,
              )
              total_announced = self.total
  
          if not (self.log_filter and not self.log_filter(res)):
              counts[res["status"]] += 1
              count_strs = [
                  _count_str(*args)
                  for args in [
                      (counts["notneeded"], "skipped", False),
                      (counts["error"], "failed", True),
                  ]
              ]
              if (
                  counts["notneeded"]
                  or counts["error"]
                  or self.interrupted
              ):
                  strs = count_strs
                  if self.interrupted:
                      strs.append("exiting!")
                  label = "{} ({})".format(
                      self.label, ", ".join(filter(None, count_strs))
                  )
  
              log_progress(
                  lgr_.error if res["status"] == "error" else lgr_.info,
                  pid,
                  "%s: processed result%s",
                  self.label,
                  " for " + res["path"] if "path" in res else "",
                  label=label,
                  update=1,
                  increment=True,
                  noninteractive_level=5,
              )
          yield res
      log_progress(
          lgr_.info, pid, "%s: done", self.label, noninteractive_level=5
      )
  
imports: import concurrent.futures
  import inspect
  import sys
  import time
  import uuid
  from collections import defaultdict
  from queue import Queue, Empty
  from threading import Thread
  from .None import ansi_colors
  from ..log import log_progress
  from ..utils import path_is_subpath
  from datalad.support.exceptions import CapturedException
  import logging
label_desc: Use image node_id 2 for calling the ProducerConsumerProgressLog obj's underlying member method code with example usage: obj.__iter__() without return types