def log(stats_resource=None, stats_source=None, log_level=DEFAULT_LOG_LEVEL,
        **kwargs):
    """Utility to log given stats to *stats* logger.

    Stats to log are given by `stats_source` and in its absence we log
    `kwargs`. *stats* logger is configured independently from any logger.
    Only stats should be logged to this logger. Will add current timestamp
    to the logged stats if not given.

    Parameters:
        - `stats_resource`: any object that complies with `id` and `name`
        attrs.
        - `stats_source`: any callable that give a `dict` that will be
        logged to *stats* logger.
        - `log_level`: str representing level at which to log this stats
        message.
        - `**kwargs`: if `stats_source` is not given, we log this `dict`.
    """

    # Get stats from source if given.
    if stats_source is not None:
        kwargs = stats_source()

    if stats_resource is None:
        if RESOURCE_ID not in kwargs or RESOURCE_NAME not in kwargs:
            raise ValueError('Missing required stats labels.')
    else:
        if not (hasattr(stats_resource, ConfWithId.ID) and
                hasattr(stats_resource, ConfWithId.NAME)):
            raise ValueError('Given stats source is missing id or name'
                             ' attributes.')
        kwargs[RESOURCE_ID] = stats_resource.id
        kwargs[RESOURCE_NAME] = stats_resource.name

    if TIMESTAMP not in kwargs:
        kwargs[TIMESTAMP] = datetime.datetime.utcfromtimestamp(
            time.time()).strftime("%Y-%m-%dT%H:%M:%S.%fZ")

    _STATS_LOGGER.log(log_level,
                      json.dumps(kwargs))
dataset/ETHPy150Open osrg/ryu/ryu/services/protocols/bgp/utils/stats.py/log/original