class_docstr: Normalizer class to handle log key normalization in payloads
docstr: Recursively extract lists of path parts from a dictionary
  
  Args:
      record (dict): Parsed payload of log
      paths_to_normalize (set): Normalized keys for which to extract paths
      path (list=None): Parts of current path for which keys are being extracted
  
  Yields:
      dict: A dict contians the values of normalized types. For example,
          {
              'values': ['1.1.1.2']
              'function': 'Source ip address'
          }
docstr_tok: ["Recursively","extract","lists","of","path","parts","from","a","dictionary","Args",":","record","(","dict",")",":","Parsed","payload","of","log","paths_to_normalize","(","set",")",":","Normalized","keys","for","which","to","extract","paths","path","(","list=None",")",":","Parts","of","current","path","for","which","keys","are","being","extracted","Yields",":","dict",":","A","dict","contians","the","values","of","normalized","types",".","For","example",",","{","'values","'",":","[","'","1.1.1.2","'","]","'function","'",":","'Source","ip","address'","}"]
code: def _extract_values(cls, record, paths_to_normalize):
      """Recursively extract lists of path parts from a dictionary
  
      Args:
          record (dict): Parsed payload of log
          paths_to_normalize (set): Normalized keys for which to extract paths
          path (list=None): Parts of current path for which keys are being extracted
  
      Yields:
          dict: A dict contians the values of normalized types. For example,
              {
                  'values': ['1.1.1.2']
                  'function': 'Source ip address'
              }
      """
      for param in paths_to_normalize.parsed_params:
          if param.get(CONST_CONDITION) and not cls._match_condition(
              record, param[CONST_CONDITION]
          ):
              # If optional 'condition' block is configured, it will only extract values if
              # condition is matched.
              continue
  
          found_value, value = cls._find_value(
              record, param.get(CONST_PATH)
          )
  
          if found_value:
              result = {
                  CONST_FUNCTION: param.get(CONST_FUNCTION) or None,
                  # if value not a list, it will be cast to a str even it is a dict or other
                  # types
                  CONST_VALUES: value
                  if isinstance(value, list)
                  else [str(value)],
              }
  
              # Add "send_to_artifacts" flag to the normalized field when it explicitly sets the
              # flag to "false" in the normalizer in conf/schemas/*.json
              if not param.get(CONST_ARTIFACTS_FLAG, True):
                  result[CONST_ARTIFACTS_FLAG] = False
  
              yield result
  
imports: from collections import defaultdict
  import logging
  import itertools
  import uuid
  from streamalert.shared.config import TopLevelConfigKeys
  from streamalert.shared.exceptions import ConfigError
  from streamalert.shared.logger import get_logger
label_desc: Use image node_id 3 for calling the Normalizer obj's underlying member method code with example usage: obj._extract_values(cls, record, paths_to_normalize) without return types